diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000..78629f50 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,4 @@ +*.gif filter=lfs diff=lfs merge=lfs -text +*.otf filter=lfs diff=lfs merge=lfs -text +*.svg filter=lfs diff=lfs merge=lfs -text +*.png filter=lfs diff=lfs merge=lfs -text diff --git a/.github/stale.yml b/.github/stale.yml new file mode 100644 index 00000000..e6e32871 --- /dev/null +++ b/.github/stale.yml @@ -0,0 +1,17 @@ +# Number of days of inactivity before an issue becomes stale +daysUntilStale: 120 +# Number of days of inactivity before a stale issue is closed +daysUntilClose: 7 +# Issues with these labels will never be considered stale +exemptLabels: + - pinned + - security +# Label to use when marking an issue as stale +staleLabel: wontfix +# Comment to post when marking an issue as stale. Set to `false` to disable +markComment: > + This issue has been automatically marked as stale because it has not had + recent activity. It will be closed if no further activity occurs. Thank you + for your contributions. +# Comment to post when closing a stale issue. Set to `false` to disable +closeComment: false diff --git a/.github/workflows/cpp_full_node_workflow.yml b/.github/workflows/cpp_full_node_workflow.yml new file mode 100644 index 00000000..a2c6386c --- /dev/null +++ b/.github/workflows/cpp_full_node_workflow.yml @@ -0,0 +1,269 @@ +name: WeDPR-Component ci for full node +on: + push: + paths-ignore: + - "docs/**" + - "python/**" + - "cpp/wedpr-transport/sdk-wrapper/python/bindings/**" + - "Changelog.md" + - "README.md" + pull_request: + paths-ignore: + - "docs/**" + - "python/**" + - "Changelog.md" + - "README.md" + release: + types: [published, push] +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +env: + RUST_BACKTRACE: 1 + ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true + ACTIONS_RUNNER_FORCED_INTERNAL_NODE_VERSION: node16 + ACTIONS_RUNNER_FORCE_ACTIONS_NODE_VERSION: node16 + +jobs: + build: + name: build all + runs-on: ${{ matrix.os }} + continue-on-error: true + strategy: + fail-fast: false + matrix: + os: [macos-13, ubuntu-20.04] + steps: + - uses: actions/checkout@v2 + with: + fetch-depth: 5 + - uses: actions-rs/toolchain@v1 + with: + toolchain: nightly-2022-07-28 + override: true + - name: Prepare vcpkg + if: runner.os != 'Windows' + uses: friendlyanon/setup-vcpkg@v1 + with: { committish: 51b14cd4e1230dd51c11ffeff6f7d53c61cc5297 } + - uses: actions/cache@v2 + id: deps_cache + with: + path: | + deps/ + c:/vcpkg + !c:/vcpkg/.git + !c:/vcpkg/buildtrees + !c:/vcpkg/packages + !c:/vcpkg/downloads + key: build-all-${{ matrix.os }}-${{ github.base_ref }}-${{ hashFiles('.github/workflows/cpp_full_node_workflow.yml') }} + restore-keys: | + build-all-${{ matrix.os }}-${{ github.base_ref }}-${{ hashFiles('.github/workflows/cpp_full_node_workflow.yml') }} + build-all-${{ matrix.os }}-${{ github.base_ref }}- + build-all-${{ matrix.os }}- + - name: Build for linux + if: runner.os == 'Linux' + run: | + sudo apt install -y lcov ccache wget libgmp-dev python3-dev + export GCC='gcc-10' + export CXX='g++-10' + sudo bash -x cpp/tools/install_depends.sh -o ubuntu + mkdir -p cpp/build && cd cpp/build && cmake -DBUILD_STATIC=ON -DTESTS=ON -DCOVERAGE=ON -DCMAKE_TOOLCHAIN_FILE=${{ env.VCPKG_ROOT }}/scripts/buildsystems/vcpkg.cmake ../ + echo "Disk usage before delete files: "`df -lh` + du -sch ${{ env.VCPKG_ROOT }}/buildtrees/* + du -sch ${{ env.VCPKG_ROOT }}/buildtrees/grpc/src/* + rm -rf ${{ env.VCPKG_ROOT }}/buildtrees/*/src + rm -rf ${{ env.VCPKG_ROOT }}/buildtrees/*/*-dbg + rm -rf ${{ env.VCPKG_ROOT }}/buildtrees/*/*-rel + echo "Disk usage after delete files: "`df -lh` + make -j3 + - name: Build for macOS + if: runner.os == 'macOS' + run: | + bash -x cpp/tools/install_depends.sh -o macos + brew install libiconv + brew reinstall m4 autoconf libtool automake + echo "## m4:"`which m4` + export DYLD_LIBRARY_PATH=/usr/local/opt/libiconv/lib:${DYLD_LIBRARY_PATH} + export LDFLAGS="-L/usr/local/opt/libiconv/lib" + export CPPFLAGS="-I/usr/local/opt/libiconv/include" + export PATH="/usr/bin:${PATH}" + mkdir -p cpp/build && cd cpp/build + cmake -DBUILD_STATIC=ON -DTESTS=ON -DCOVERAGE=ON -DCMAKE_TOOLCHAIN_FILE=${{ env.VCPKG_ROOT }}/scripts/buildsystems/vcpkg.cmake ../ + make -j3 + - name: Publish Error + if: always() + uses: actions/upload-artifact@v4 + with: + name: gperftools-build-err.log + path: /home/runner/work/WeDPR-Component/WeDPR-Component/cpp/deps/src/gperftools-stamp/gperftools-build-err.log + - uses: actions/upload-artifact@v4 + if: runner.os == 'macOS' + with: + name: ppc-air-node-macOS + path: ./cpp/build/bin/ppc-air-node + - uses: actions/upload-artifact@v4 + if: runner.os == 'macOS' + with: + name: ppc-pro-node-macOS + path: ./cpp/build/bin/ppc-pro-node + - uses: actions/upload-artifact@v4 + if: runner.os == 'macOS' + with: + name: ppc-gateway-service-macOS + path: ./cpp/build/bin/ppc-gateway-service + - name: Test + if: runner.os != 'Windows' + run: | + cd cpp/build && CTEST_OUTPUT_ON_FAILURE=TRUE make test ARGS="--output-on-failure" + - name: Publish Error + if: always() + uses: actions/upload-artifact@v4 + with: + name: build-x64-linux-dbg-err.log + path: /home/runner/work/WeDPR-Component/WeDPR-Component/vcpkg/buildtrees/gsasl/build-x64-linux-dbg-err.log + - name: Publish Error macos + if: always() + uses: actions/upload-artifact@v4 + with: + name: build-x64-osx-dbg-err.log + path: /Users/runner/work/WeDPR-Component/WeDPR-Component/vcpkg/buildtrees/gsasl/build-x64-osx-dbg-err.log + - name: Publish Error macos + if: always() + uses: actions/upload-artifact@v4 + with: + name: autoconf-x64-osx-err.log + path: /Users/runner/work/WeDPR-Component/WeDPR-Component/vcpkg/buildtrees/gsasl/autoconf-x64-osx-err.log + + build_centos: + name: build_centos full node + runs-on: ubuntu-latest + continue-on-error: true + strategy: + fail-fast: false + matrix: + container: + - centos-7.9 + container: + image: docker.io/centos:7 + volumes: + - /usr/local/share/vcpkg:/usr/local/share/vcpkg + - /node20217:/node20217:rw,rshared + - ${{ matrix.container == 'centos-7.9' && '/node20217:/__e/node20:ro,rshared' || ' ' }} + steps: + - name: install nodejs20glibc2.17 + if: ${{ matrix.container == 'centos-7.9' }} + run: | + curl -LO https://unofficial-builds.nodejs.org/download/release/v20.9.0/node-v20.9.0-linux-x64-glibc-217.tar.xz + tar -xf node-v20.9.0-linux-x64-glibc-217.tar.xz --strip-components 1 -C /node20217 + - name: Check out the repo + uses: actions/checkout@v4 + - uses: actions/cache@v3 + id: deps_cache + with: + path: | + deps/ + /usr/local/share/vcpkg/buildtrees + /usr/local/share/vcpkg/packages + /home/runner/.ccache + /Users/runner/.ccache/ + key: centos-notest-all-${{ matrix.os }}-${{ github.base_ref }}-${{ hashFiles('.github/workflows/cpp_full_node_workflow.yml') }} + restore-keys: | + centos-notest-all-${{ matrix.os }}-${{ github.base_ref }}-${{ hashFiles('.github/workflows/cpp_full_node_workflow.yml') }} + centos-notest-all-${{ matrix.os }}-${{ github.base_ref }}- + centos-notest-all-${{ matrix.os }}- + - name: Prepare centos tools + run: | + rpm -ivh https://cbs.centos.org/kojifiles/packages/centos-release-scl-rh/2/3.el7.centos/noarch/centos-release-scl-rh-2-3.el7.centos.noarch.rpm + rpm -ivh https://cbs.centos.org/kojifiles/packages/centos-release-scl/2/3.el7.centos/noarch/centos-release-scl-2-3.el7.centos.noarch.rpm + sed -i s/mirror.centos.org/mirrors.aliyun.com/g /etc/yum.repos.d/*.repo + sed -i s/^#.*baseurl=http/baseurl=http/g /etc/yum.repos.d/*.repo + sed -i s/^mirrorlist=http/#mirrorlist=http/g /etc/yum.repos.d/*.repo + cat /etc/yum.repos.d/*.repo + yum clean all + yum makecache + yum update -y + yum install -y epel-release centos-release-scl centos-release-scl-rh + yum install -y https://packages.endpointdev.com/rhel/7/os/x86_64/endpoint-repo.x86_64.rpm + yum install -y libtool wget java-11-openjdk-devel git autoconf automake make gcc gcc-c++ glibc-static glibc-devel cmake3 ccache devtoolset-11 libzstd-devel zlib-devel flex bison python-devel python3-devel + - uses: actions-rs/toolchain@v1 + with: + toolchain: nightly-2022-07-28 + override: true + - name: Prepare vcpkg + if: runner.os != 'Windows' + uses: friendlyanon/setup-vcpkg@v1 + with: { committish: 51b14cd4e1230dd51c11ffeff6f7d53c61cc5297 } + - name: Check disk space + run: df . -h + - name: Free disk space + run: | + du -sch /usr/share/* + du -sch /opt/* + - name: Check disk space + run: | + df . -h + du /usr/ -hx -d 4 --threshold=1G | sort -hr | head + df /tmp + du /tmp | sort -n + ls -lh /tmp + - name: upgradeDepends + run: | + wget http://ftp.gnu.org/gnu/automake/automake-1.14.1.tar.gz + tar -xf automake-1.14.1.tar.gz + cd automake-1.14.1 + ./configure && make -j4 && make install + cd .. + - name: DependenciesBuild + run: | + bash -x cpp/tools/install_depends.sh -o centos + alias cmake='cmake3' + . /opt/rh/devtoolset-11/enable + rm -rf python + mkdir -p cpp/build + cd cpp/build + cmake3 -DCMAKE_TOOLCHAIN_FILE=${{ env.VCPKG_ROOT }}/scripts/buildsystems/vcpkg.cmake -DBUILD_STATIC=ON -DCMAKE_BUILD_TYPE=Release -DTESTS=ON ../ + - name: FreeDiskSpace + run: | + df -lh + du -sch /__w/WeDPR-Component/WeDPR-Component/vcpkg/buildtrees/* + du -sch /__w/WeDPR-Component/WeDPR-Component/vcpkg/buildtrees/grpc/src/* + rm -rf /__w/WeDPR-Component/WeDPR-Component/vcpkg/buildtrees/grpc/src + rm -rf /__w/WeDPR-Component/WeDPR-Component/vcpkg/buildtrees/grpc/*-dbg + rm -rf /__w/WeDPR-Component/WeDPR-Component/vcpkg/buildtrees/openssl/src + rm -rf /__w/WeDPR-Component/WeDPR-Component/vcpkg/buildtrees/openssl/*-dbg + rm -rf /__w/WeDPR-Component/WeDPR-Component/vcpkg/buildtrees/*/*-dbg + df -lh + - name: Compile + run: | + alias cmake='cmake3' + . /opt/rh/devtoolset-11/enable + cd cpp/build && cmake3 --build . --parallel 3 + #- name: Test + # run: | + # export OMP_NUM_THREADS=1 + # cd build && CTEST_OUTPUT_ON_FAILURE=TRUE make test + - uses: actions/upload-artifact@v3 + with: + name: ppc-air-node-x64 + path: ./cpp/build/bin/ppc-air-node + - uses: actions/upload-artifact@v3 + with: + name: ppc-pro-node-x64 + path: ./cpp/build/bin/ppc-pro-node + - uses: actions/upload-artifact@v3 + with: + name: ppc-gateway-service-x64 + path: ./cpp/build/bin/ppc-gateway-service + - name: Publish Error macos + if: always() + uses: actions/upload-artifact@v4 + with: + name: vcpkg-manifest-install.log + path: /__w/WeDPR-Component/WeDPR-Component/cpp/build/vcpkg-manifest-install.log + - name: Publish Error macos + if: always() + uses: actions/upload-artifact@v4 + with: + name: autoconf-x64-linux-err.log + path: /__w/WeDPR-Component/WeDPR-Component/vcpkg/buildtrees/gsasl/autoconf-x64-linux-err.log \ No newline at end of file diff --git a/.github/workflows/cpp_sdk_workflow.yml b/.github/workflows/cpp_sdk_workflow.yml new file mode 100644 index 00000000..3ba1ec06 --- /dev/null +++ b/.github/workflows/cpp_sdk_workflow.yml @@ -0,0 +1,172 @@ +name: WeDPR-Component ci for cpp-sdk +on: + push: + paths-ignore: + - "docs/**" + - "python/**" + - "cpp/wedpr-transport/sdk-wrapper/python/bindings/**" + - "Changelog.md" + - "README.md" + pull_request: + paths-ignore: + - "docs/**" + - "python/**" + - "Changelog.md" + - "README.md" + release: + types: [published, push] +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +env: + RUST_BACKTRACE: 1 + ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true + ACTIONS_RUNNER_FORCED_INTERNAL_NODE_VERSION: node16 + ACTIONS_RUNNER_FORCE_ACTIONS_NODE_VERSION: node16 + +jobs: + build_sdk: + name: build sdk + runs-on: ${{ matrix.os }} + continue-on-error: true + strategy: + fail-fast: false + matrix: + os: [ubuntu-22.04, windows-2019, macos-13] + steps: + - uses: actions/checkout@v2 + with: + fetch-depth: 5 + - uses: actions-rs/toolchain@v1 + with: + toolchain: nightly-2022-07-28 + override: true + - name: Prepare vcpkg + if: runner.os != 'Windows' + uses: friendlyanon/setup-vcpkg@v1 + with: { committish: 51b14cd4e1230dd51c11ffeff6f7d53c61cc5297 } + - uses: actions/cache@v2 + id: deps_cache + with: + path: | + deps/ + ${{ env.VCPKG_ROOT }} + ${{ env.VCPKG_ROOT }}/.git + ${{ env.VCPKG_ROOT }}/buildtrees + ${{ env.VCPKG_ROOT }}/packages + ${{ env.VCPKG_ROOT }}/downloads + key: build-sdk-${{ matrix.os }}-${{ github.base_ref }}-${{ hashFiles('.github/workflows/cpp_sdk_workflow.yml') }} + restore-keys: | + build-sdk-${{ matrix.os }}-${{ github.base_ref }}-${{ hashFiles('.github/workflows/cpp_sdk_workflow.yml') }} + build-sdk-${{ matrix.os }}-${{ github.base_ref }}- + build-sdk-${{ matrix.os }}- + - name: Add MSbuild to PATH + if: runner.os == 'Windows' + uses: microsoft/setup-msbuild@v1.1 + - name: Build for windows + if: runner.os == 'Windows' + run: | + mkdir -p cpp/build && cd cpp/build && cmake -G "Visual Studio 16 2019" -A x64 -DCMAKE_BUILD_TYPE=Release -DTESTS=OFF -DBUILD_SDK=ON -DVCPKG_TARGET_TRIPLET=x64-windows-static -DCMAKE_TOOLCHAIN_FILE=c:/vcpkg/scripts/buildsystems/vcpkg.cmake .. + MSBuild /version + MSBuild WeDPR-Component.sln /p:Configuration=Release /p:Platform=x64 + - name: Build for linux + if: runner.os == 'Linux' + run: | + sudo apt install -y lcov ccache wget libgmp-dev python3-dev + export GCC='gcc-10' + export CXX='g++-10' + bash cpp/tools/install_depends.sh -o ubuntu + mkdir -p cpp/build && cd cpp/build && cmake -DTESTS=ON -DCOVERAGE=ON -DBUILD_SDK=ON -DCMAKE_TOOLCHAIN_FILE=${{ env.VCPKG_ROOT }}/scripts/buildsystems/vcpkg.cmake ../ + make -j3 + - name: Build for macos + if: runner.os == 'macOS' + run: | + brew install lcov + bash cpp/tools/install_depends.sh -o macos + mkdir -p cpp/build && cd cpp/build && cmake -DTESTS=ON -DCOVERAGE=OFF -DBUILD_SDK=ON -DCMAKE_TOOLCHAIN_FILE=${{ env.VCPKG_ROOT }}/scripts/buildsystems/vcpkg.cmake ../ + make -j3 + - name: Test + if: runner.os == 'macOS' + run: | + cd cpp/build && CTEST_OUTPUT_ON_FAILURE=TRUE make test + - name: Test and upload coverage + if: runner.os == 'Linux' + run: | + cd cpp/build && CTEST_OUTPUT_ON_FAILURE=TRUE make test + - uses: actions/upload-artifact@v4 + if: runner.os == 'macos' + with: + name: 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@v4 + if: runner.os == 'Windows' + with: + name: libppc-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_for_sdk: + name: build_centos_for_sdk + runs-on: ubuntu-latest + continue-on-error: true + strategy: + fail-fast: false + matrix: + container: + - centos-7.9 + container: + image: docker.io/centos:7 + volumes: + - /usr/local/share/vcpkg:/usr/local/share/vcpkg + - /node20217:/node20217:rw,rshared + - ${{ matrix.container == 'centos-7.9' && '/node20217:/__e/node20:ro,rshared' || ' ' }} + steps: + - name: install nodejs20glibc2.17 + if: ${{ matrix.container == 'centos-7.9' }} + run: | + curl -LO https://unofficial-builds.nodejs.org/download/release/v20.9.0/node-v20.9.0-linux-x64-glibc-217.tar.xz + tar -xf node-v20.9.0-linux-x64-glibc-217.tar.xz --strip-components 1 -C /node20217 + - name: Check out the repo + uses: actions/checkout@v4 + - uses: actions/cache@v3 + id: deps_cache + with: + path: | + deps/ + /usr/local/share/vcpkg/buildtrees + /usr/local/share/vcpkg/packages + /home/runner/.ccache + /Users/runner/.ccache/ + key: centos-sdk-notest-all-${{ matrix.os }}-${{ github.base_ref }}-${{ hashFiles('.github/workflows/cpp_sdk_workflow.yml') }} + restore-keys: | + centos-sdk-notest-all-${{ matrix.os }}-${{ github.base_ref }}-${{ hashFiles('.github/workflows/cpp_sdk_workflow.yml') }} + centos-sdk-notest-all-${{ matrix.os }}-${{ github.base_ref }}- + centos-sdk-notest-all-${{ matrix.os }}- + - name: Prepare centos tools + run: | + rpm -ivh https://cbs.centos.org/kojifiles/packages/centos-release-scl-rh/2/3.el7.centos/noarch/centos-release-scl-rh-2-3.el7.centos.noarch.rpm + rpm -ivh https://cbs.centos.org/kojifiles/packages/centos-release-scl/2/3.el7.centos/noarch/centos-release-scl-2-3.el7.centos.noarch.rpm + sed -i s/mirror.centos.org/mirrors.aliyun.com/g /etc/yum.repos.d/*.repo + sed -i s/^#.*baseurl=http/baseurl=http/g /etc/yum.repos.d/*.repo + sed -i s/^mirrorlist=http/#mirrorlist=http/g /etc/yum.repos.d/*.repo + cat /etc/yum.repos.d/*.repo + yum clean all + yum makecache + yum update -y + yum install -y epel-release centos-release-scl centos-release-scl-rh + yum install -y https://packages.endpointdev.com/rhel/7/os/x86_64/endpoint-repo.x86_64.rpm + yum install -y java-11-openjdk-devel git make gcc gcc-c++ glibc-static glibc-devel openssl cmake3 ccache devtoolset-11 llvm-toolset-7.0 rh-perl530-perl libzstd-devel zlib-devel flex bison python-devel python3-devel + yum install -y rh-perl530-perl cmake3 zlib-devel ccache lcov python-devel python3-devel + yum install -y git + - name: Prepare vcpkg + if: runner.os != 'Windows' + uses: friendlyanon/setup-vcpkg@v1 + with: { committish: 51b14cd4e1230dd51c11ffeff6f7d53c61cc5297 } + - name: Build + run: | + alias cmake='cmake3' + . /opt/rh/devtoolset-11/enable + mkdir -p cpp/build + cd cpp/build + cmake3 -DCMAKE_TOOLCHAIN_FILE=${{ env.VCPKG_ROOT }}/scripts/buildsystems/vcpkg.cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_SDK=ON -DCMAKE_TOOLCHAIN_FILE=/usr/local/share/vcpkg/scripts/buildsystems/vcpkg.cmake ../ + cmake3 --build . --parallel 3 diff --git a/.github/workflows/cpp_toolkit_workflow.yml b/.github/workflows/cpp_toolkit_workflow.yml new file mode 100644 index 00000000..025f276c --- /dev/null +++ b/.github/workflows/cpp_toolkit_workflow.yml @@ -0,0 +1,186 @@ +name: WeDPR-Component ci for cpp-toolkit +on: + push: + paths-ignore: + - "docs/**" + - "python/**" + - "cpp/wedpr-transport/sdk-wrapper/python/bindings/**" + - "Changelog.md" + - "README.md" + pull_request: + paths-ignore: + - "docs/**" + - "python/**" + - "Changelog.md" + - "README.md" + release: + types: [published, push] +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +env: + RUST_BACKTRACE: 1 + ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true + ACTIONS_RUNNER_FORCED_INTERNAL_NODE_VERSION: node16 + ACTIONS_RUNNER_FORCE_ACTIONS_NODE_VERSION: node16 + +jobs: + build_wedpr_toolkit: + name: build wedpr toolkit + runs-on: ${{ matrix.os }} + continue-on-error: true + strategy: + fail-fast: false + matrix: + os: [ubuntu-22.04, windows-2019, macos-13] + steps: + - uses: actions/checkout@v2 + with: + fetch-depth: 5 + - uses: actions-rs/toolchain@v1 + with: + toolchain: nightly-2022-07-28 + override: true + - name: Prepare python + if: runner.os == 'Windows' + uses: actions/setup-python@v5 + with: + python-version: '3.8' + - name: Prepare vcpkg + if: runner.os != 'Windows' + uses: friendlyanon/setup-vcpkg@v1 + with: { committish: 51b14cd4e1230dd51c11ffeff6f7d53c61cc5297 } + - uses: actions/cache@v2 + id: deps_cache + with: + path: | + deps/ + ${{ env.VCPKG_ROOT }} + ${{ env.VCPKG_ROOT }}/.git + ${{ env.VCPKG_ROOT }}/buildtrees + ${{ env.VCPKG_ROOT }}/packages + ${{ env.VCPKG_ROOT }}/downloads + key: build-toolkit-${{ matrix.os }}-${{ github.base_ref }}-${{ hashFiles('.github/workflows/cpp_toolkit_workflow.yml') }} + restore-keys: | + build-toolkit-${{ matrix.os }}-${{ github.base_ref }}-${{ hashFiles('.github/workflows/cpp_toolkit_workflow.yml') }} + build-toolkit-${{ matrix.os }}-${{ github.base_ref }}- + build-toolkit-${{ matrix.os }}- + - name: Add MSbuild to PATH + if: runner.os == 'Windows' + uses: microsoft/setup-msbuild@v1.1 + - name: Build for windows + if: runner.os == 'Windows' + run: | + mkdir -p cpp/build && cd cpp/build && cmake -G "Visual Studio 16 2019" -A x64 -DBUILD_PYTHON=OFF -DCMAKE_BUILD_TYPE=Release -DTESTS=OFF -DBUILD_WEDPR_TOOLKIT=ON -DVCPKG_TARGET_TRIPLET=x64-windows-static -DVCPKG_HOST_TRIPLET=x64-windows-static -DCMAKE_TOOLCHAIN_FILE=c:/vcpkg/scripts/buildsystems/vcpkg.cmake .. && MSBuild /version && MSBuild WeDPR-Component.sln /p:Configuration=Release /p:Platform=x64 + - name: Build for linux + if: runner.os == 'Linux' + run: | + sudo apt install -y lcov ccache wget libgmp-dev python3-dev + export GCC='gcc-10' + export CXX='g++-10' + bash cpp/tools/install_depends.sh -o ubuntu + mkdir -p cpp/build && cd cpp/build && cmake -DBUILD_WEDPR_TOOLKIT=ON -DBUILD_PYTHON=ON -DCMAKE_TOOLCHAIN_FILE=${{ env.VCPKG_ROOT }}/scripts/buildsystems/vcpkg.cmake ../ + make -j3 + - name: Build for macos + if: runner.os == 'macOS' + run: | + brew install lcov + bash cpp/tools/install_depends.sh -o macos + mkdir -p cpp/build && cd cpp/build && cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_WEDPR_TOOLKIT=ON -DBUILD_PYTHON=ON -DCMAKE_TOOLCHAIN_FILE=${{ env.VCPKG_ROOT }}/scripts/buildsystems/vcpkg.cmake ../ + make -j3 + - uses: actions/upload-artifact@v4 + if: runner.os == 'macos' + with: + name: libwedpr_java_transport_jni.dylib + path: ./cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/resources/META-INF/native/libwedpr_java_transport_jni.dylib + - uses: actions/upload-artifact@v4 + if: runner.os == 'Windows' + with: + name: libwedpr_java_transport_jni.dll + path: D:\a\WeDPR-Component\WeDPR-Component\cpp\wedpr-transport\sdk-wrapper\java\bindings\src\main\resources\META-INF\native\Release\wedpr_java_transport_jni.dll + - uses: actions/upload-artifact@v4 + if: runner.os == 'macos' + with: + name: libwedpr_python_transport.dylib + path: ./cpp/wedpr-transport/sdk-wrapper/python/bindings/wedpr_python_gateway_sdk/libs/libwedpr_python_transport.dylib + - uses: actions/upload-artifact@v4 + if: runner.os == 'Windows' + with: + name: libwedpr_python_transport.dll + path: D:\a\WeDPR-Component\WeDPR-Component\cpp\wedpr-transport\sdk-wrapper\python\bindings\wedpr_python_gateway_sdk\libs\Release\wedpr_python_transport.dll + + + build_centos_for_toolkit: + name: build_centos_for_toolkit + runs-on: ubuntu-latest + continue-on-error: true + strategy: + fail-fast: false + matrix: + container: + - centos-7.9 + container: + image: docker.io/centos:7 + volumes: + - /usr/local/share/vcpkg:/usr/local/share/vcpkg + - /node20217:/node20217:rw,rshared + - ${{ matrix.container == 'centos-7.9' && '/node20217:/__e/node20:ro,rshared' || ' ' }} + steps: + - name: install nodejs20glibc2.17 + if: ${{ matrix.container == 'centos-7.9' }} + run: | + curl -LO https://unofficial-builds.nodejs.org/download/release/v20.9.0/node-v20.9.0-linux-x64-glibc-217.tar.xz + tar -xf node-v20.9.0-linux-x64-glibc-217.tar.xz --strip-components 1 -C /node20217 + - name: Check out the repo + uses: actions/checkout@v4 + - uses: actions/cache@v3 + id: deps_cache + with: + path: | + deps/ + /usr/local/share/vcpkg/buildtrees + /usr/local/share/vcpkg/packages + /home/runner/.ccache + /Users/runner/.ccache/ + key: centos-toolkit-notest-all-${{ matrix.os }}-${{ github.base_ref }}-${{ hashFiles('.github/workflows/cpp_toolkit_workflow.yml') }} + restore-keys: | + centos-toolkit-notest-all-${{ matrix.os }}-${{ github.base_ref }}-${{ hashFiles('.github/workflows/cpp_toolkit_workflow.yml') }} + centos-toolkit-notest-all-${{ matrix.os }}-${{ github.base_ref }}- + centos-toolkit-notest-all-${{ matrix.os }}- + - name: Prepare centos tools + run: | + rpm -ivh https://cbs.centos.org/kojifiles/packages/centos-release-scl-rh/2/3.el7.centos/noarch/centos-release-scl-rh-2-3.el7.centos.noarch.rpm + rpm -ivh https://cbs.centos.org/kojifiles/packages/centos-release-scl/2/3.el7.centos/noarch/centos-release-scl-2-3.el7.centos.noarch.rpm + sed -i s/mirror.centos.org/mirrors.aliyun.com/g /etc/yum.repos.d/*.repo + sed -i s/^#.*baseurl=http/baseurl=http/g /etc/yum.repos.d/*.repo + sed -i s/^mirrorlist=http/#mirrorlist=http/g /etc/yum.repos.d/*.repo + cat /etc/yum.repos.d/*.repo + yum clean all + yum makecache + yum update -y + yum install -y epel-release centos-release-scl centos-release-scl-rh + yum install -y https://packages.endpointdev.com/rhel/7/os/x86_64/endpoint-repo.x86_64.rpm + yum install -y java-11-openjdk-devel git make gcc gcc-c++ glibc-static glibc-devel openssl cmake3 ccache devtoolset-11 llvm-toolset-7.0 rh-perl530-perl libzstd-devel zlib-devel flex bison python-devel python3-devel + yum install -y rh-perl530-perl cmake3 zlib-devel ccache lcov python-devel python3-devel + yum install -y git + - name: Prepare vcpkg + if: runner.os != 'Windows' + uses: friendlyanon/setup-vcpkg@v1 + with: { committish: 51b14cd4e1230dd51c11ffeff6f7d53c61cc5297 } + - name: Build + run: | + alias cmake='cmake3' + . /opt/rh/devtoolset-11/enable + mkdir -p cpp/build + cd cpp/build + cmake3 -DCMAKE_TOOLCHAIN_FILE=${{ env.VCPKG_ROOT }}/scripts/buildsystems/vcpkg.cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_WEDPR_TOOLKIT=ON -DBUILD_PYTHON=ON -DCMAKE_TOOLCHAIN_FILE=/usr/local/share/vcpkg/scripts/buildsystems/vcpkg.cmake ../ + cmake3 --build . --parallel 3 + - uses: actions/upload-artifact@v3 + with: + name: libwedpr_java_transport_jni.so + path: ./cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/resources/META-INF/native/libwedpr_java_transport_jni.so + - uses: actions/upload-artifact@v3 + with: + name: libwedpr_python_transport.so + path: ./cpp/wedpr-transport/sdk-wrapper/python/bindings/wedpr_python_gateway_sdk/libs/libwedpr_python_transport.so diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml new file mode 100644 index 00000000..b15a5aa3 --- /dev/null +++ b/.github/workflows/docker.yml @@ -0,0 +1,97 @@ +name: WeDPR-Component docker ci +on: + push: + paths-ignore: + - "docs/**" + - "Changelog.md" + - "README.md" + tags: + - 'v3.*.*' + branches: + - feature-milestone2-gateway + pull_request: + paths-ignore: + - "docs/**" + - "python/**" + - "Changelog.md" + - "README.md" + release: + types: [prereleased] + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +env: + RUST_BACKTRACE: 1 + ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true + ACTIONS_RUNNER_FORCED_INTERNAL_NODE_VERSION: node16 + ACTIONS_RUNNER_FORCE_ACTIONS_NODE_VERSION: node16 + +jobs: + build-docker: + if: github.event.pull_request.merged == true || github.event_name == 'push' + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Get branch name + uses: nelonoel/branch-name@v1.0.1 + - name: Fetch tag + run: | + git fetch --tags --force + - name: Login to Docker Hub + uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3 + with: + username: ${{ secrets.DOCKER_FISCOPR_USER }} + password: ${{ secrets.DOCKER_FISCOPR_TOKEN }} + - name: Get git tag + uses: little-core-labs/get-git-tag@v3.0.1 + id: tag_data + with: + tagRegex: (.*) # Optional. Returns specified group text as tag name. Full tag string is returned if regex is not defined. + tagRegexGroup: 1 # Optional. Default is 1. + # the model image + - name: Build and Push model images + run: | + [[ ${{github.ref}} == */tags/* ]] && MODEL_DOCKER_TAG="${GIT_TAG_NAME}" || MODEL_DOCKER_TAG="${BRANCH_NAME}" + MODEL_DOCKER_TAG="fiscoorg/wedpr-model-service:${MODEL_DOCKER_TAG}" + echo "* Begin to build model docker: ${MODEL_DOCKER_TAG}" + cd docker-files/model/model + docker build --build-arg SOURCE_BRANCH=${BRANCH_NAME} -t ${MODEL_DOCKER_TAG} . + echo "* Build model docker: ${MODEL_DOCKER_TAG} success" + docker push ${MODEL_DOCKER_TAG} + echo "* Push model docker: ${MODEL_DOCKER_TAG} success" + # the wedpr-gateway-service image + - name: Build and Push wedpr-gateway-service images + run: | + [[ ${{github.ref}} == */tags/* ]] && GW_DOCKER_TAG="${GIT_TAG_NAME}" || GW_DOCKER_TAG="${BRANCH_NAME}" + GW_DOCKER_TAG="fiscoorg/wedpr-gateway-service:${GW_DOCKER_TAG}" + echo "* Begin to build wedpr-gateway-service docker: ${GW_DOCKER_TAG}" + cd docker-files/cpp/ + docker build --no-cache --build-arg SOURCE_BRANCH=${BRANCH_NAME} --target wedpr-gateway-service -t ${GW_DOCKER_TAG} . + echo "* Build wedpr-gateway-service docker: ${GW_DOCKER_TAG} success" + docker push ${GW_DOCKER_TAG} + echo "* Push wedpr-gateway-service docker: ${GW_DOCKER_TAG} success" + # the wedpr-pro-node-service image + - name: Build and Push wedpr-pro-node-service images + run: | + [[ ${{github.ref}} == */tags/* ]] && NODE_DOCKER_TAG="${GIT_TAG_NAME}" || NODE_DOCKER_TAG="${BRANCH_NAME}" + NODE_DOCKER_TAG="fiscoorg/wedpr-pro-node-service:${NODE_DOCKER_TAG}" + echo "* Begin to build wedpr-pro-node-service docker: ${NODE_DOCKER_TAG}" + cd docker-files/cpp/ + docker build --build-arg SOURCE_BRANCH=${BRANCH_NAME} --target wedpr-pro-node-service -t ${NODE_DOCKER_TAG} . + echo "* Build wedpr-pro-node-service docker: ${NODE_DOCKER_TAG} success" + docker push ${NODE_DOCKER_TAG} + echo "* Push wedpr-pro-node-service docker: ${NODE_DOCKER_TAG} success" + # the wedpr-mpc-service image + - name: Build and Push wedpr-mpc-service images + run: | + [[ ${{github.ref}} == */tags/* ]] && MPC_DOCKER_TAG="${GIT_TAG_NAME}" || MPC_DOCKER_TAG="${BRANCH_NAME}" + MPC_DOCKER_TAG="fiscoorg/wedpr-mpc-service:${MPC_DOCKER_TAG}" + echo "* Begin to build wedpr-mpc-service docker: ${MPC_DOCKER_TAG}" + cd docker-files/cpp/ + docker build --build-arg SOURCE_BRANCH=${BRANCH_NAME} --target wedpr-mpc-service -t ${MPC_DOCKER_TAG} . + echo "* Build wedpr-mpc-service docker: ${MPC_DOCKER_TAG} success" + docker push ${MPC_DOCKER_TAG} + echo "* Push wedpr-mpc-service docker: ${MPC_DOCKER_TAG} success" \ No newline at end of file diff --git a/.github/workflows/model_docker_image_base.yml b/.github/workflows/model_docker_image_base.yml new file mode 100644 index 00000000..0af4ab5a --- /dev/null +++ b/.github/workflows/model_docker_image_base.yml @@ -0,0 +1,40 @@ +name: Manual trigger wedpr-model-service-base-image docker image build + +on: + workflow_dispatch: + inputs: + logLevel: + description: 'Log level' + required: true + default: 'warning' + tags: + description: 'the input tag' + +jobs: + manual-build-model-base-docker: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Get branch name + uses: nelonoel/branch-name@v1.0.1 + - name: Fetch tag + run: | + git fetch --tags --force + - name: Login to Docker Hub + uses: docker/login-action@v1 + with: + username: ${{ secrets.DOCKER_FISCOPR_USER }} + password: ${{ secrets.DOCKER_FISCOPR_TOKEN }} + + # the model image + - name: Build and Push wedpr-model-service-base-image images + run: | + echo "* Manual build wedpr-model-service-base-image image, docker version: ${{ github.event.inputs.tags }}" + DOCKER_TAG="fiscoorg/wedpr-model-service-base-image:${{ github.event.inputs.tags }}" + echo "* Begin to build ${DOCKER_TAG}" + cd docker-files/model/base + docker build -t ${DOCKER_TAG} . + echo "* Build ${DOCKER_TAG} success" + docker push ${DOCKER_TAG} + echo "* Push ${DOCKER_TAG} success" \ No newline at end of file diff --git a/.github/workflows/vcpkg_docker_image.yml b/.github/workflows/vcpkg_docker_image.yml new file mode 100644 index 00000000..33c03299 --- /dev/null +++ b/.github/workflows/vcpkg_docker_image.yml @@ -0,0 +1,46 @@ +name: Manual trigger vcpkg-cache docker image build + +on: + workflow_dispatch: + inputs: + logLevel: + description: 'Log level' + required: true + default: 'warning' + tags: + description: 'the input tag' + +jobs: + manual-build-vcpkg-cache-docker: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Get branch name + uses: nelonoel/branch-name@v1.0.1 + - name: Fetch tag + run: | + git fetch --tags --force + - name: Login to Docker Hub + uses: docker/login-action@v1 + with: + username: ${{ secrets.DOCKER_FISCOPR_USER }} + password: ${{ secrets.DOCKER_FISCOPR_TOKEN }} + + # the model image + - name: Build and Push wedpr-component-vcpkg-cache images + run: | + echo "* Manual build wedpr-component-vcpkg-cache image, docker version: ${{ github.event.inputs.tags }}" + DOCKER_TAG="fiscoorg/wedpr-component-vcpkg-cache:${{ github.event.inputs.tags }}" + echo "* Begin to build ${DOCKER_TAG}" + cd docker-files/cpp/vcpkg + docker build --build-arg SOURCE_BRANCH=${BRANCH_NAME} -t ${DOCKER_TAG} . + echo "* Build ${DOCKER_TAG} success" + docker push ${DOCKER_TAG} + echo "* Push ${DOCKER_TAG} success" + - name: Publish Error + if: always() + uses: actions/upload-artifact@v4 + with: + name: autoconf-x64-linux-err.log + path: /WeDPR-Component/cpp/vcpkg/buildtrees/gsasl/autoconf-x64-linux-err.log \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..c4556f6c --- /dev/null +++ b/.gitignore @@ -0,0 +1,153 @@ +.venv + +# Prerequisites +*.d + +.DS_Store +.vscode +.idea +.cache + +cmake-build-debug +# Compiled Object files +*.slo +*.lo +*.o +*.obj + +# Precompiled Headers +*.gch +*.pch + +# Compiled Dynamic libraries +*.so +*.dylib +*.dll + +# Fortran module files +*.mod +*.smod + +# Compiled Static libraries +*.lai +*.la +*.a +*.lib + +# Executables +*.exe +*.out +*.app +**/*.class + +build/** +GPATH +GRTAGS +GTAGS +deps +deps/** +**/bin + +d1-encrypted +d2-encrypted +d3-encrypted +__pycache__ + +ppc-psi/tests/cm2020-psi/data +ppc-psi/tests/bs-ecdh-psi/data +ppc-psi/tests/labeled-psi/data + +tools/*-node +ppc-crypto-c-sdk/bindings/java/.gradle/** +ppc-udf/hive/bin/** +ppc-udf/hive/build/** +ppc-udf/hive/dist/** +ppc-udf/hive/.gradle/** +ppc-udf/hive/libs/ppc-crypto-sdk-jni-1* + +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +logs/ +*/service/PSI-DATA/ +static/ +env/ +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +*.egg-info/ +.installed.cfg +*.egg + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*,cover +.hypothesis/ + +# Translations +*.mo +*.pot + +# Flask stuff: +instance/ +.webassets-cache + +# pyenv +.python-version + +# dotenv +.env + +# javaenv +.gradle + +# virtualenv +venv/ +ENV/ + +# Editors +.idea/ +*.crt +*/bin +*/logs +*/bin +*.csv +*/*/logs +*/start.out +*/application.yml +*/client_config.py + +# Mac cache file +.DS_Store + diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..b647ee05 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "cpp/vcpkg"] + path = cpp/vcpkg + url = https://github.com/microsoft/vcpkg diff --git a/ChangeLog.md b/ChangeLog.md new file mode 100644 index 00000000..67c02c6f --- /dev/null +++ b/ChangeLog.md @@ -0,0 +1,37 @@ +# 3.0.0 +(2024-12-9) + +### 新增 + +**隐私计算组件** + +- PSI: 实现多种类型隐私求交集算法,包括CM2020, RA2018, ECDH-PSI, ECDH-Multi-PSI等 +- MPC: 安全多方计算 +- PIR: 匿踪查询核心组件 + +**联合建模组件** + +- 2+方的多方联合XGB/LR建模组件(训练 + 离线预测) +- 2+方多方特征工程组件(特征分箱,WOE/IV计算等) +- 多方数据预处理组件 + +**统一网关** + +- 支持基于最短路径的消息路由转发 +- 支持按节点ID、服务名、机构名进行路由寻址 +- 支持服务注册和服务发现 + +**统一网关SDK** + +- 提供Java/Python网关SDK,支持接入网关与其他节点、服务或者机构进行通信 +- 可向网关注册服务 +- 可从网关拉取服务信息 + +**专家模式SDK** + +- `wedpr-ml-toolkit`: 可通过python sdk向WeDPR隐私计算平台发起各类任务,并获取对应的结果,扩展了WeDPR隐私计算系统功能的可扩展性,可在不侵入式修改系统的前提下,实现数据开发人员的各类数据分析需求 + +**密码学组件** + +- 实现了各种同态算法,包括`Paillier`, `IHC`等 + diff --git a/README.md b/README.md index b984af1d..fd18f059 100644 --- a/README.md +++ b/README.md @@ -1 +1,43 @@ -# WeDPR-Component \ No newline at end of file +# WeDPR-Component + +![](./static/images/wedpr_logo.png) + + +[![CodeFactor](https://www.codefactor.io/repository/github/webankblockchain/wedpr-component/badge?s=a4c3fb6ffd39e7618378fe13b6bd06c5846cc103)](https://www.codefactor.io/repository/github/webankblockchain/wedpr-component) +[![contributors](https://img.shields.io/github/contributors/WeBankBlockchain/WeDPR)](https://github.com/WeBankBlockchain/WeDPR-Component/graphs/contributors) +[![GitHub activity](https://img.shields.io/github/commit-activity/m/WeBankBlockchain/WeDPR-Component)](https://github.com/WeBankBlockchain/WeDPR-Component/pulse) +[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](http://makeapullrequest.com) + +微众银行多方大数据隐私计算平台[WeDPR-Component](https://github.com/WeBankBlockchain/WeDPR-Component)核心组件库,包括: + + +**丰富的隐私计算任务支持** + +- **隐私求交集**: 包括两方隐私求交集任务和多方隐私求交集任务,并从性能、网络带宽、使用场景等多方面考虑,实现了多种隐私求交集算法,包括CM2020(性能高), RA2018(非平衡PSI算法,适用于CS模式), ECDH-PSI; +- **匿踪查询**: 基于OT算法构建匿踪查询,可将数据集发布为匿踪查询服务开放给相关用户使用; +- **联合建模**: 基于SecureLGB和SecureLR算法支持多方数据联合建模,并可将建模结果发布为模型用于预测,满足了80%多方数据联合建模需求; +- **联合分析**: 基于安全多方计算算法,提供了类SQL/Python的隐私数据联合分析语法,可在不引入额外学习成本的前提下,满足数据开发人员基于多方数据进行联合分析的需求; + + +**统一网关** + +- 支持基于最短路径的消息路由转发 +- 支持按节点ID、服务名、机构名进行路由寻址 +- 支持服务注册和服务发现 + +**统一网关SDK** + +- 提供Java/Python网关SDK,支持接入网关与其他节点、服务或者机构进行通信 +- 可向网关注册服务 +- 可从网关拉取服务信息 + + +## 技术文档 + +- [文档](https://wedpr-document.readthedocs.io/zh-cn/latest/) +- [代码](https://github.com/WeBankBlockchain/WeDPR-Component) + + +## License + +WeDPR-Component的开源协议为Apache License 2.0, 详情参见[LICENSE](LICENSE)。 \ No newline at end of file diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt new file mode 100644 index 00000000..a56790ce --- /dev/null +++ b/cpp/CMakeLists.txt @@ -0,0 +1,120 @@ +#------------------------------------------------------------------------------ +# Top-level CMake file for WeDPR-Component +# ------------------------------------------------------------------------------ +# Copyright (C) 2022 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. +#------------------------------------------------------------------------------ + +cmake_minimum_required(VERSION 3.14) + +set(PROJECT_CMAKE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/cmake" CACHE PATH "The cmake path for the library") +list(APPEND CMAKE_MODULE_PATH ${PROJECT_CMAKE_DIR}) + +add_definitions(-w) + +include(FetchContent) +if (NOT DEFINED URL_BASE) + set(URL_BASE "github.com") + #set(URL_BASE "github.com.cnpmjs.org") +endif () + +if (WIN32) + set(VCPKG_C_FLAGS -D_WIN32_WINNT=0x0600 -DWINVER=0x0600) + set(VCPKG_CXX_FLAGS -D_WIN32_WINNT=0x0600 -DWINVER=0x0600) + add_definitions(-D_WIN32_WINNT=0x0600) + add_definitions(-DBOOST_USE_WINAPI_VERSION=BOOST_WINAPI_VERSION_WIN7) + set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS "ON") +else () + add_definitions(-DBOOST_UUID_RANDOM_PROVIDER_FORCE_POSIX) +endif () + +# basic settings +include(Options) +configure_project() + + +# vcpkg init +if(NOT DEFINED CMAKE_TOOLCHAIN_FILE) + find_package(Git REQUIRED) + execute_process(COMMAND ${GIT_EXECUTABLE} submodule update --init --recursive -- vcpkg WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}) + set(CMAKE_TOOLCHAIN_FILE "${CMAKE_CURRENT_SOURCE_DIR}/vcpkg/scripts/buildsystems/vcpkg.cmake" + CACHE STRING "Vcpkg toolchain file") +endif() + +include(Version) +project(WeDPR-Component VERSION ${VERSION}) + +include(CompilerSettings) +include(BuildInfoGenerator) +set(PROTO_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR}/generated/pb) + +include(IncludeDirectories) +# the target settings +include(TargetSettings) +# dependencies +include(Dependencies) + +########### set the sources ########### +set(JNI_SOURCE_PATH wedpr-crypto/sdk/bindings/java/src/main/c) +set(SDK_SOURCE_LIST wedpr-crypto/ppc-homo wedpr-crypto/ppc-crypto-core wedpr-crypto/sdk ${JNI_SOURCE_PATH}) +# Note: the udf depends on mysql, not enabled in the full node mode +set(UDF_SOURCE_LIST ${SDK_SOURCE_LIST} wedpr-crypto/ppc-udf) +set(CEM_SOURCE "") +if(BUILD_CEM) + set(CEM_SOURCE "wedpr-computing/ppc-cem") +endif() + +set(TRANSPORT_SDK_SOURCE_LIST + wedpr-protocol + wedpr-transport/ppc-front + wedpr-transport/sdk) + +set(TRANSPORT_SDK_TOOLKIT_SOURCE_LIST + ${TRANSPORT_SDK_SOURCE_LIST} + wedpr-transport/sdk-wrapper) + +set(ALL_SOURCE_LIST + ${SDK_SOURCE_LIST} + ${TRANSPORT_SDK_SOURCE_LIST} + wedpr-crypto/ppc-crypto + wedpr-helper/libhelper wedpr-helper/ppc-tools + wedpr-storage/ppc-io wedpr-storage/ppc-storage + wedpr-transport/ppc-gateway + wedpr-transport/ppc-rpc + wedpr-transport/ppc-http + wedpr-computing/ppc-psi wedpr-computing/ppc-mpc wedpr-computing/ppc-pir ${CEM_SOURCE} + wedpr-initializer wedpr-main) + +if(BUILD_ALL) + add_sources("${ALL_SOURCE_LIST}") +elseif(BUILD_UDF) + add_sources("${UDF_SOURCE_LIST}") +elseif(BUILD_SDK) + add_sources("${SDK_SOURCE_LIST}") +elseif(BUILD_WEDPR_TOOLKIT) + include(swig) + add_sources("${TRANSPORT_SDK_TOOLKIT_SOURCE_LIST}") +endif() +########### set the sources end ########### + +if (TESTS) + enable_testing() + set(CTEST_OUTPUT_ON_FAILURE TRUE) +endif () + +# for code coverage +if (COVERAGE) + include(Coverage) + config_coverage("coverage" "") +endif () diff --git a/cpp/cmake/BuildInfo.cmake b/cpp/cmake/BuildInfo.cmake new file mode 100644 index 00000000..b100a7f5 --- /dev/null +++ b/cpp/cmake/BuildInfo.cmake @@ -0,0 +1,44 @@ +function(create_build_info) + # Set build platform; to be written to BuildInfo.h + set(PPC_BUILD_OS "${CMAKE_HOST_SYSTEM_NAME}") + + if (CMAKE_COMPILER_IS_MINGW) + set(PPC_BUILD_COMPILER "mingw") + elseif (CMAKE_COMPILER_IS_MSYS) + set(PPC_BUILD_COMPILER "msys") + elseif (CMAKE_COMPILER_IS_GNUCXX) + set(PPC_BUILD_COMPILER "g++") + elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") + set(PPC_BUILD_COMPILER "clang") + elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "AppleClang") + set(PPC_BUILD_COMPILER "appleclang") + else () + set(PPC_BUILD_COMPILER "unknown") + endif () + + set(PPC_BUILD_PLATFORM "${PPC_BUILD_OS}/${PPC_BUILD_COMPILER}") + + + if (CMAKE_BUILD_TYPE) + set(_cmake_build_type ${CMAKE_BUILD_TYPE}) + else() + set(_cmake_build_type "${CMAKE_CFG_INTDIR}") + endif() + # Generate header file containing useful build information + add_custom_target(BuildInfo.h ALL + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} + COMMAND ${CMAKE_COMMAND} -DPPC_SOURCE_DIR="${PROJECT_SOURCE_DIR}/.." + -DPPC_BUILDINFO_IN="${CMAKE_CURRENT_SOURCE_DIR}/cmake/templates/BuildInfo.h.in" + -DPPC_DST_DIR="${PROJECT_BINARY_DIR}/include" + -DPPC_CMAKE_DIR="${CMAKE_CURRENT_SOURCE_DIR}/cmake" + -DPPC_BUILD_TYPE="${_cmake_build_type}" + -DPPC_BUILD_OS="${PPC_BUILD_OS}" + -DPPC_BUILD_COMPILER="${PPC_BUILD_COMPILER}" + -DPPC_BUILD_PLATFORM="${PPC_BUILD_PLATFORM}" + -DPPC_BUILD_NUMBER="${PPC_BUILD_NUMBER}" + -DPPC_VERSION_SUFFIX="${VERSION_SUFFIX}" + -DPROJECT_VERSION="${PROJECT_VERSION}" + -P "${PPC_SCRIPTS_DIR}/buildinfo.cmake" + ) + include_directories(BEFORE ${PROJECT_BINARY_DIR}) +endfunction() diff --git a/cpp/cmake/BuildInfoGenerator.cmake b/cpp/cmake/BuildInfoGenerator.cmake new file mode 100644 index 00000000..00871500 --- /dev/null +++ b/cpp/cmake/BuildInfoGenerator.cmake @@ -0,0 +1,3 @@ +set(PPC_SCRIPTS_DIR ${CMAKE_CURRENT_SOURCE_DIR}/cmake/scripts) +include(BuildInfo) +create_build_info() diff --git a/cpp/cmake/CompilerSettings.cmake b/cpp/cmake/CompilerSettings.cmake new file mode 100644 index 00000000..e6a91d9b --- /dev/null +++ b/cpp/cmake/CompilerSettings.cmake @@ -0,0 +1,204 @@ +set(CMAKE_CXX_STANDARD 20) +set(Boost_NO_WARN_NEW_VERSIONS ON) +# export windows dll symbol +if(WIN32) + message(STATUS "Compile on Windows") + set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS "ON") +endif() + +message(STATUS "COMPILER_ID: ${CMAKE_CXX_COMPILER_ID}") +if (("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") OR ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")) + find_program(CCACHE_PROGRAM ccache) + if(CCACHE_PROGRAM) + set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "${CCACHE_PROGRAM}") + set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK "${CCACHE_PROGRAM}") + endif() + set(CMAKE_CXX_STANDARD 20) + # set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "/usr/bin/time") + # set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK "/usr/bin/time") + # Use ISO C++17 standard language. + # set(CMAKE_CXX_VISIBILITY_PRESET hidden) + # Enables all the warnings about constructions that some users consider questionable, + # and that are easy to avoid. Also enable some extra warning flags that are not + # enabled by -Wall. Finally, treat at warnings-as-errors, which forces developers + # to fix warnings as they arise, so they don't accumulate "to be fixed later". + add_compile_options(-Werror) + add_compile_options(-Wall) + add_compile_options(-pedantic) + add_compile_options(-Wextra) + add_compile_options(-Wno-deprecated-declarations) + add_compile_options(-Wno-unused-variable) + add_compile_options(-Wno-unused-parameter) + add_compile_options(-Wno-unused-function) + add_compile_options(-Wno-unused-private-field) + add_compile_options(-Wno-variadic-macros) + add_compile_options(-Wno-deprecated-declarations) + add_compile_options(-Wno-deprecated-copy) + # add_compile_options(-Wno-missing-field-initializers) + # Disable warnings about unknown pragmas (which is enabled by -Wall). + add_compile_options(-Wno-unknown-pragmas) + add_compile_options(-fno-omit-frame-pointer) + # for boost json spirit + add_compile_options(-DBOOST_SPIRIT_THREADSAFE) + # for tbb, TODO: https://software.intel.com/sites/default/files/managed/b2/d2/TBBRevamp.pdf + add_compile_options(-DTBB_SUPPRESS_DEPRECATED_MESSAGES=1) + # build deps lib Release + set(_only_release_configuration "-DCMAKE_BUILD_TYPE=Release") + + if(BUILD_STATIC) + SET(CMAKE_FIND_LIBRARY_SUFFIXES ".a") + SET(BUILD_SHARED_LIBRARIES OFF) + SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS}") + # Note: If bring the -static option, apple will fail to link + if (NOT APPLE) + SET(CMAKE_EXE_LINKER_FLAGS "-static") + endif() + # SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Bdynamic -ldl -lpthread -Wl,-Bstatic -static-libstdc++ ") + endif () + + if(TESTS) + add_compile_options(-DBOOST_TEST_THREAD_SAFE) + endif () + + if(PROF) + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pg") + SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pg") + SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -pg") + endif () + + # Configuration-specific compiler settings. + set(CMAKE_CXX_FLAGS_DEBUG "-Og -g") + set(CMAKE_CXX_FLAGS_MINSIZEREL "-Os -DNDEBUG") + set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG") + set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g") + + option(USE_LD_GOLD "Use GNU gold linker" ON) + if (USE_LD_GOLD) + if("${LINKER}" MATCHES "gold") + execute_process(COMMAND ${CMAKE_C_COMPILER} -fuse-ld=gold -Wl,--version ERROR_QUIET OUTPUT_VARIABLE LD_VERSION) + if("${LD_VERSION}" MATCHES "GNU gold") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fuse-ld=gold") + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -fuse-ld=gold") + endif() + elseif("${LINKER}" MATCHES "mold") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fuse-ld=mold") + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -fuse-ld=mold") + endif() + endif () + + # Additional GCC-specific compiler settings. + if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") + # Check that we've got GCC 7.0 or newer. + set(GCC_MIN_VERSION "7.0") + execute_process( + COMMAND ${CMAKE_CXX_COMPILER} -dumpversion OUTPUT_VARIABLE GCC_VERSION) + if (NOT (GCC_VERSION VERSION_GREATER ${GCC_MIN_VERSION} OR GCC_VERSION VERSION_EQUAL ${GCC_MIN_VERSION})) + message(FATAL_ERROR "${PROJECT_NAME} requires g++ ${GCC_MIN_VERSION} or greater. Current is ${GCC_VERSION}") + endif () + if(BUILD_STATIC) + # solve multiple definition of `__lll_lock_wait_private' + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${MARCH_TYPE} -ftree-parallelize-loops=2 -flto") + else() + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${MARCH_TYPE}") + endif() + set(CMAKE_C_FLAGS "-std=c99 -fexceptions ${CMAKE_C_FLAGS} ${MARCH_TYPE}") + + # Strong stack protection was only added in GCC 4.9. + # Use it if we have the option to do so. + # See https://lwn.net/Articles/584225/ + add_compile_options(-fstack-protector-strong) + add_compile_options(-fstack-protector) + + add_compile_options(-fPIC) + add_compile_options(-Wno-error=nonnull) + add_compile_options(-foptimize-sibling-calls) + add_compile_options(-Wno-stringop-overflow) + add_compile_options(-Wno-restrict) + add_compile_options(-Wno-error=format-truncation) + + if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 11.0) + add_compile_options(-Wno-stringop-overread) + add_compile_options(-Wno-maybe-uninitialized) + add_compile_options(-Wno-array-bounds) + add_compile_options(-Wno-aggressive-loop-optimizations) + endif() + # Additional Clang-specific compiler settings. + elseif ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") + if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.0) + set(CMAKE_CXX_FLAGS_DEBUG "-O -g") + endif() + # set(CMAKE_CXX_FLAGS "-stdlib=libc++ ${CMAKE_CXX_FLAGS}") + add_compile_options(-fstack-protector) + add_compile_options(-Winconsistent-missing-override) + # Some Linux-specific Clang settings. We don't want these for OS X. + if ("${CMAKE_HOST_SYSTEM_NAME}" MATCHES "Linux") + # Tell Boost that we're using Clang's libc++. Not sure exactly why we need to do. + add_definitions(-DBOOST_ASIO_HAS_CLANG_LIBCXX) + # Use fancy colors in the compiler diagnostics + add_compile_options(-fcolor-diagnostics) + endif() + endif() + + if (COVERAGE) + set(TESTS ON) + if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") + set(CMAKE_CXX_FLAGS "-g --coverage ${CMAKE_CXX_FLAGS}") + set(CMAKE_C_FLAGS "-g --coverage ${CMAKE_C_FLAGS}") + set(CMAKE_SHARED_LINKER_FLAGS "--coverage ${CMAKE_SHARED_LINKER_FLAGS}") + set(CMAKE_EXE_LINKER_FLAGS "--coverage ${CMAKE_EXE_LINKER_FLAGS}") + elseif ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") + add_compile_options(-Wno-unused-command-line-argument) + set(CMAKE_CXX_FLAGS "-g -fprofile-arcs -ftest-coverage ${CMAKE_CXX_FLAGS}") + set(CMAKE_C_FLAGS "-g -fprofile-arcs -ftest-coverage ${CMAKE_C_FLAGS}") + endif() + endif () +elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES "MSVC") + # Only support visual studio 2017 and visual studio 2019 + set(MSVC_MIN_VERSION "1914") # VS2017 15.7, for full-ish C++17 support + + message(STATUS "Compile On Windows, MSVC_TOOLSET_VERSION: ${MSVC_TOOLSET_VERSION}") + + if (MSVC_TOOLSET_VERSION EQUAL 141) + message(STATUS "Compile On Visual Studio 2017") + elseif(MSVC_TOOLSET_VERSION EQUAL 142) + message(STATUS "Compile On Visual Studio 2019") + else() + message(FATAL_ERROR "Unsupported Visual Studio, supported list: [2017, 2019]. Current MSVC_TOOLSET_VERSION: ${MSVC_TOOLSET_VERSION}") + endif() + + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /std:c++17") + add_compile_definitions(NOMINMAX) + add_compile_options(-bigobj) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHsc") + if(BUILD_SHARED_LIBS) + if(CMAKE_BUILD_TYPE MATCHES "Debug") + add_compile_options(/MDd) + else() + add_compile_options(/MD) + endif() + else () + if(CMAKE_BUILD_TYPE MATCHES "Debug") + add_compile_options(/MTd) + else() + add_compile_options(/MT) + endif () + endif () + link_libraries(ws2_32 Crypt32 userenv) +else () + message(WARNING "Your compiler is not tested, if you run into any issues, we'd welcome any patches.") +endif () + +if (SANITIZE) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-omit-frame-pointer -fsanitize=${SANITIZE}") + if (${CMAKE_CXX_COMPILER_ID} MATCHES "Clang") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize-blacklist=${CMAKE_SOURCE_DIR}/sanitizer-blacklist.txt") + endif() +endif() + +# rust static library linking requirements for macos +if(APPLE) + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -framework Security -framework Kerberos") +else() + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -ldl") +endif() +set(CMAKE_SKIP_INSTALL_ALL_DEPENDENCY ON) diff --git a/cpp/cmake/Coverage.cmake b/cpp/cmake/Coverage.cmake new file mode 100644 index 00000000..51c2f313 --- /dev/null +++ b/cpp/cmake/Coverage.cmake @@ -0,0 +1,41 @@ +# ------------------------------------------------------------------------------ +# Copyright (C) 2021 FISCO BCOS. +# 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: Coverage.cmake +# Function: Define coverage related functions +# ------------------------------------------------------------------------------ +# REMOVE_FILE_PATTERN eg.: '/usr*' '${CMAKE_SOURCE_DIR}/deps**' '${CMAKE_SOURCE_DIR}/evmc*' ‘${CMAKE_SOURCE_DIR}/fisco-bcos*’ +function(config_coverage TARGET REMOVE_FILE_PATTERN) + find_program(LCOV_TOOL lcov) + message(STATUS "lcov tool: ${LCOV_TOOL}") + if (LCOV_TOOL) + message(STATUS "coverage dir: " ${CMAKE_BINARY_DIR}) + message(STATUS "coverage TARGET: " ${TARGET}) + message(STATUS "coverage REMOVE_FILE_PATTERN: " ${REMOVE_FILE_PATTERN}) + if (APPLE) + add_custom_target(${TARGET} + COMMAND ${LCOV_TOOL} -keep-going --ignore-errors inconsistent,unmapped,source --rc lcov_branch_coverage=1 -o ${CMAKE_BINARY_DIR}/coverage.info.in -c -d ${CMAKE_BINARY_DIR}/ + COMMAND ${LCOV_TOOL} -keep-going --ignore-errors inconsistent,unmapped,source --rc lcov_branch_coverage=1 -r ${CMAKE_BINARY_DIR}/coverage.info.in '*MacOS*' '/usr*' '.*vcpkg_installed*' '.*boost/*' '*test*' '*build*' '*deps*' ${REMOVE_FILE_PATTERN} -o ${CMAKE_BINARY_DIR}/coverage.info + COMMAND genhtml --keep-going --ignore-errors inconsistent,unmapped,source --rc lcov_branch_coverage=1 -q -o ${CMAKE_BINARY_DIR}/CodeCoverage ${CMAKE_BINARY_DIR}/coverage.info) + else() + add_custom_target(${TARGET} + COMMAND ${LCOV_TOOL} --rc lcov_branch_coverage=1 -o ${CMAKE_BINARY_DIR}/coverage.info.in -c -d ${CMAKE_BINARY_DIR}/ + COMMAND ${LCOV_TOOL} --rc lcov_branch_coverage=1 -r ${CMAKE_BINARY_DIR}/coverage.info.in '*MacOS*' '/usr*' '.*vcpkg_installed*' '.*boost/*' '*test*' '*build*' '*deps*' ${REMOVE_FILE_PATTERN} -o ${CMAKE_BINARY_DIR}/coverage.info + COMMAND genhtml --rc lcov_branch_coverage=1 -q -o ${CMAKE_BINARY_DIR}/CodeCoverage ${CMAKE_BINARY_DIR}/coverage.info) + endif() + else () + message(FATAL_ERROR "Can't find lcov tool. Please install lcov") + endif() +endfunction() \ No newline at end of file diff --git a/cpp/cmake/Dependencies.cmake b/cpp/cmake/Dependencies.cmake new file mode 100644 index 00000000..3e9f1854 --- /dev/null +++ b/cpp/cmake/Dependencies.cmake @@ -0,0 +1,54 @@ + +# ipp-crypto +#if(ENABLE_IPP_CRYPTO) +# hunter_add_package(ipp-crypto) +#endif() + +######## common dependencies ######## +include(InstallBcosUtilities) +if (TESTS) + find_package(Boost COMPONENTS unit_test_framework) +endif() + +# cpp_features +if(ENABLE_CPU_FEATURES) + find_package(CpuFeatures REQUIRED) +endif() +######## common dependencies end ######## + +##### the wedpr_toolkit ##### +if(BUILD_ALL OR BUILD_WEDPR_TOOLKIT) + find_package(TBB REQUIRED) + find_package(gRPC REQUIRED) + find_package(jsoncpp REQUIRED) +endif() +##### the sdk dependencies ##### +if(BUILD_ALL OR BUILD_SDK OR BUILD_UDF) + find_package(OpenSSL REQUIRED) + find_package(unofficial-sodium CONFIG REQUIRED) +endif() + +##### the full-dependencies ##### +if(BUILD_ALL) + find_package(${BCOS_BOOSTSSL_TARGET} REQUIRED) + # tcmalloc + include(ProjectTCMalloc) + + find_package(SEAL REQUIRED) + find_package(Kuku REQUIRED) + + # APSI: Note: APSI depends on seal 4.0 and Kuku 2.1 + include(ProjectAPSI) + # Wedpr Crypto + include(ProjectWedprCrypto) + include(Installlibhdfs3) +endif() +##### the full-dependencies end ##### + +##### the sdk-dependencies ##### +# find JNI +set(JAVA_AWT_LIBRARY NotNeeded) +set(JAVA_JVM_LIBRARY NotNeeded) +find_package(JNI REQUIRED) +include_directories(${JNI_INCLUDE_DIRS}) +##### the sdk-dependencies end##### \ No newline at end of file diff --git a/cpp/cmake/IncludeDirectories.cmake b/cpp/cmake/IncludeDirectories.cmake new file mode 100644 index 00000000..4c0e78d4 --- /dev/null +++ b/cpp/cmake/IncludeDirectories.cmake @@ -0,0 +1,17 @@ +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) +include_directories(${CMAKE_CURRENT_BINARY_DIR}) +include_directories(${CMAKE_BINARY_DIR}/generated/) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/wedpr-protocol) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/wedpr-transport) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/wedpr-computing) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/wedpr-crypto) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/wedpr-storage) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/wedpr-helper) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/wedpr-transport) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/wedpr-crypto/sdk) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/wedpr-transport/ppc-front) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/wedpr-transport/ppc-gateway) +include_directories(${PROTO_OUTPUT_PATH}) + +set(VCPKG_INCLUDE_PATH "${VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/include") +include_directories(${VCPKG_INCLUDE_PATH}) \ No newline at end of file diff --git a/cpp/cmake/InstallBcosUtilities.cmake b/cpp/cmake/InstallBcosUtilities.cmake new file mode 100644 index 00000000..6177ba72 --- /dev/null +++ b/cpp/cmake/InstallBcosUtilities.cmake @@ -0,0 +1,3 @@ +find_package(Boost COMPONENTS log filesystem chrono thread serialization iostreams system ) +find_package(ZLIB REQUIRED) +find_package(bcos-utilities CONFIG REQUIRED) \ No newline at end of file diff --git a/cpp/cmake/Installlibhdfs3.cmake b/cpp/cmake/Installlibhdfs3.cmake new file mode 100644 index 00000000..6b1f6c59 --- /dev/null +++ b/cpp/cmake/Installlibhdfs3.cmake @@ -0,0 +1,6 @@ +find_package(libxml2 REQUIRED) +find_package(protobuf REQUIRED) +if ("${CMAKE_HOST_SYSTEM_NAME}" MATCHES "Linux") + find_package(unofficial-libuuid REQUIRED) +endif() +find_package(libhdfs3 REQUIRED) \ No newline at end of file diff --git a/cpp/cmake/Options.cmake b/cpp/cmake/Options.cmake new file mode 100644 index 00000000..9af80391 --- /dev/null +++ b/cpp/cmake/Options.cmake @@ -0,0 +1,195 @@ +macro(default_option O DEF) + if (DEFINED ${O}) + if (${${O}}) + set(${O} ON) + else () + set(${O} OFF) + endif () + else () + set(${O} ${DEF}) + endif () +endmacro() +macro(add_sources source_list) + foreach(source ${source_list}) + add_subdirectory(${source}) + endforeach() +endmacro() + +# common settings +if ("${CMAKE_SIZEOF_VOID_P}" STREQUAL "4") + message(FATAL "The ${PROJECT_NAME} does not support compiling on 32-bit systems") +endif () + +EXECUTE_PROCESS(COMMAND uname -m COMMAND tr -d '\n' OUTPUT_VARIABLE ARCHITECTURE) + +macro(configure_project) + set(NAME ${PROJECT_NAME}) + + # Default to RelWithDebInfo configuration if no configuration is explicitly specified. + if (NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE "RelWithDebInfo" CACHE STRING + "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel." FORCE) + endif () + + default_option(BUILD_STATIC OFF) + + # unit tests + default_option(TESTS OFF) + # code coverage + default_option(COVERAGE OFF) + + #debug + default_option(DEBUG OFF) + + #cem + default_option(BUILD_CEM OFF) + + #conn_psi + default_option(ENABLE_CONN OFF) + + default_option(ENABLE_DEMO OFF) + # sdk + 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) + set(VERSION_SUFFIX "") + endif () + + # for boost-ssl enable/disable native + set(ARCH_NATIVE OFF) + if ("${ARCHITECTURE}" MATCHES "aarch64" OR "${ARCHITECTURE}" MATCHES "arm64") + set(ARCH_NATIVE ON) + endif () + + set(VISIBILITY_FLAG " -fvisibility=hidden -fvisibility-inlines-hidden") + set(PROGRAM_POSTFIX "") + if(CMAKE_HOST_SYSTEM_NAME MATCHES "Windows") + set(PROGRAM_POSTFIX ".exe") + endif() + + set(MARCH_TYPE "-march=x86-64 -mtune=generic ${VISIBILITY_FLAG}") + if (ARCH_NATIVE) + set(MARCH_TYPE "-march=native -mtune=native ${VISIBILITY_FLAG}") + endif () + + # for enable sse4.2(hdfs used) + set(ENABLE_SSE OFF) + # for enable/disable ipp-crypto + if (APPLE) + EXECUTE_PROCESS(COMMAND sysctl -a COMMAND grep "machdep.cpu.*features" COMMAND tr -d '\n' OUTPUT_VARIABLE SUPPORTED_INSTRUCTIONS) + message("* SUPPORTED_INSTRUCTIONS: ${SUPPORTED_INSTRUCTIONS}") + # detect sse4.2 + if (${SUPPORTED_INSTRUCTIONS} MATCHES ".*SSE4.2.*") + set(ENABLE_SSE ON) + endif () + elseif(NOT ${CMAKE_HOST_SYSTEM_NAME} MATCHES "Windows") + # detect sse4_2 + FILE(READ "/proc/cpuinfo" SUPPORTED_INSTRUCTIONS) + message("* Linux SUPPORTED_INSTRUCTIONS: ${SUPPORTED_INSTRUCTIONS}") + if (${SUPPORTED_INSTRUCTIONS} MATCHES ".*sse4_2.*") + set(ENABLE_SSE ON) + endif () + endif () + + set(ENABLE_CPU_FEATURES OFF) + # only ENABLE_CPU_FEATURES for aarch64 and x86 + if ("${ARCHITECTURE}" MATCHES "aarch64") + add_definitions(-DARCH) + set(ENABLE_CPU_FEATURES ON) + endif () + + if ("${ARCHITECTURE}" MATCHES "x86_64") + add_definitions(-DX86) + set(ENABLE_CPU_FEATURES ON) + endif () + + if (ENABLE_CPU_FEATURES) + add_definitions(-DENABLE_CPU_FEATURES) + endif () + + # Enable CONN_PSI Joint Running With Ant Company + if (ENABLE_CONN) + add_definitions(-DENABLE_CONN) + endif () + + set(ENABLE_IPP_CRYPTO OFF) + # Note: only ENABLE_CRYPTO_MB for x86_64 + # if ("${ARCHITECTURE}" MATCHES "x86_64") + # set(ENABLE_IPP_CRYPTO ON) + # add_definitions(-DENABLE_CRYPTO_MB) + # endif () + + # fix the boost beast build failed for [call to 'async_teardown' is ambiguous] + add_definitions(-DBOOST_ASIO_DISABLE_CONCEPTS) + + ####### options settings ###### + if (BUILD_UDF) + set(VISIBILITY_FLAG "") + set(BUILD_ALL OFF) + list(APPEND VCPKG_MANIFEST_FEATURES "sdk") + endif() + if (BUILD_SDK) + set(VISIBILITY_FLAG "") + set(BUILD_ALL OFF) + list(APPEND VCPKG_MANIFEST_FEATURES "sdk") + endif() + if (BUILD_WEDPR_TOOLKIT) + set(VISIBILITY_FLAG "") + set(BUILD_ALL OFF) + endif() + if (BUILD_ALL) + # install all dependencies + list(APPEND VCPKG_MANIFEST_FEATURES "all") + list(APPEND VCPKG_MANIFEST_FEATURES "sdk") + if(ENABLE_SSE) + # enable sse for libhdfs3 + list(APPEND VCPKG_MANIFEST_FEATURES "sse-libhdfs3") + else() + list(APPEND VCPKG_MANIFEST_FEATURES "default-libhdfs3") + endif() + endif() + if (BUILD_WEDPR_TOOLKIT) + # install wedpr dependencies + list(APPEND VCPKG_MANIFEST_FEATURES "toolkit") + endif() + # cpp_features + if(ENABLE_CPU_FEATURES) + list(APPEND VCPKG_MANIFEST_FEATURES "cpufeatures") + endif() + ####### options settings ###### + print_config("WeDPR-Component") +endmacro() + +macro(print_config NAME) + message("") + message("------------------------------------------------------------------------") + message("-- Configuring ${NAME} ${PROJECT_VERSION}${VERSION_SUFFIX}") + message("------------------------------------------------------------------------") + message("-- CMake CMake version and location ${CMAKE_VERSION} (${CMAKE_COMMAND})") + message("-- Compiler C++ compiler version ${CMAKE_CXX_COMPILER_ID} ${CMAKE_CXX_COMPILER_VERSION}") + message("-- CMAKE_BUILD_TYPE Build type ${CMAKE_BUILD_TYPE}") + message("-- VCPKG_MANIFEST_FEATURES VCPKG manifest features ${VCPKG_MANIFEST_FEATURES}") + message("-- CMAKE_TOOLCHAIN_FILE Cmake toolchain file ${CMAKE_TOOLCHAIN_FILE}") + message("-- TARGET_PLATFORM Target platform ${CMAKE_HOST_SYSTEM_NAME} ${ARCHITECTURE}") + message("-- BUILD_STATIC Build static ${BUILD_STATIC}") + message("-- COVERAGE Build code coverage ${COVERAGE}") + message("-- TESTS Build tests ${TESTS}") + message("-- ARCH_NATIVE Enable native code ${ARCH_NATIVE}") + message("-- ENABLE_CONN Enable conn_psi ant company ${ENABLE_CONN}") + message("-- ENABLE_IPP_CRYPTO Enable ipp-crypto ${ENABLE_IPP_CRYPTO}") + message("-- ENABLE_CPU_FEATURES Enable cpu-features ${ENABLE_CPU_FEATURES}") + message("-- ENABLE_SSE Enable SSE ${ENABLE_SSE}") + message("-- BUILD_CEM Enable CEM ${BUILD_CEM}") + message("-- DEMO Enable DEMO ${ENABLE_DEMO}") + message("-- BUILD_SDK BUILD SDK ${BUILD_SDK}") + message("-- BUILD_UDF BUILD UDF ${BUILD_UDF}") + message("-- BUILD_WEDPR_TOOLKIT BUILD_WEDPR_TOOLKIT ${BUILD_WEDPR_TOOLKIT}") + message("-- AUTO_GENERATE AUTO_GENERATE ${AUTO_GENERATE}") + message("-- DEBUG ${DEBUG}") + message("------------------------------------------------------------------------") + message("") +endmacro() \ No newline at end of file diff --git a/cpp/cmake/ProjectAPSI.cmake b/cpp/cmake/ProjectAPSI.cmake new file mode 100644 index 00000000..7dfadd01 --- /dev/null +++ b/cpp/cmake/ProjectAPSI.cmake @@ -0,0 +1,28 @@ +include(ExternalProject) +include(GNUInstallDirs) + +file(MAKE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/deps/) +ExternalProject_Add(APSI + PREFIX ${CMAKE_CURRENT_SOURCE_DIR}/deps + GIT_REPOSITORY https://${URL_BASE}/WeDPR-Team/APSI.git + GIT_TAG 7626026ec925e865a8e722251a71c9f167eb5fd2 + GIT_SHALLOW false + BUILD_IN_SOURCE 1 + CMAKE_ARGS -DCMAKE_PREFIX_PATH=${VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET} -DCMAKE_INSTALL_PREFIX=${CMAKE_SOURCE_DIR}/deps + LOG_DOWNLOAD 0 + LOG_CONFIGURE 0 + LOG_BUILD 0 + LOG_INSTALL 0 + ) + +ExternalProject_Get_Property(APSI SOURCE_DIR) + +set(APSI_INCLUDE_DIR ${CMAKE_SOURCE_DIR}/deps/include/APSI-0.8) +set(APSI_LIBRARY_DIR ${CMAKE_SOURCE_DIR}/deps/${CMAKE_INSTALL_LIBDIR}/libapsi-0.8.a) +file(MAKE_DIRECTORY ${APSI_INCLUDE_DIR}) # Must exist. + +add_library(apsi INTERFACE IMPORTED) +set_property(TARGET apsi PROPERTY INTERFACE_LINK_LIBRARIES ${APSI_LIBRARY_DIR}) +set_property(TARGET apsi PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${APSI_INCLUDE_DIR}) +add_dependencies(apsi APSI) +unset(SOURCE_DIR) diff --git a/cpp/cmake/ProjectTCMalloc.cmake b/cpp/cmake/ProjectTCMalloc.cmake new file mode 100644 index 00000000..8abce463 --- /dev/null +++ b/cpp/cmake/ProjectTCMalloc.cmake @@ -0,0 +1,41 @@ +include(ExternalProject) + +set(GPERFTOOLS_OPTIONS --disable-shared --disable-cpu-profiler --disable-heap-profiler --disable-heap-checker --disable-debugalloc --enable-minimal) +set(TCMALLOC_LIB_NAME "libtcmalloc_minimal.a") +if (DEBUG) + set(GPERFTOOLS_OPTIONS "") + set(TCMALLOC_LIB_NAME "libtcmalloc${CMAKE_STATIC_LIBRARY_SUFFIX}") +endif() + +set(TCMALLOC_CONFIG ./configure CXXFLAGS=-DHAVE_POSIX_MEMALIGN_SYMBOL=1 --enable-frame-pointers ${GPERFTOOLS_OPTIONS} --prefix=${CMAKE_SOURCE_DIR}/deps/src/gperftools) + +set(TCMALLOC_MAKE make install) + +ExternalProject_Add(gperftools + PREFIX ${CMAKE_CURRENT_SOURCE_DIR}/deps/ + DOWNLOAD_NAME gperftools-2.10.tar.gz + DOWNLOAD_NO_PROGRESS 1 + URL https://github.com/gperftools/gperftools/releases/download/gperftools-2.10/gperftools-2.10.tar.gz + URL_HASH SHA256=83e3bfdd28b8bcf53222c3798d4d395d52dadbbae59e8730c4a6d31a9c3732d8 + BUILD_IN_SOURCE 1 + LOG_CONFIGURE 1 + LOG_BUILD 1 + LOG_INSTALL 1 + CONFIGURE_COMMAND ${TCMALLOC_CONFIG} + BUILD_COMMAND ${TCMALLOC_MAKE} + INSTALL_COMMAND "" + BUILD_BYPRODUCTS /.libs/${TCMALLOC_LIB_NAME} +) + +ExternalProject_Get_Property(gperftools SOURCE_DIR) +add_library(TCMalloc STATIC IMPORTED GLOBAL) + +set(TCMALLOC_INCLUDE_DIR ${SOURCE_DIR}/include/) +set(TCMALLOC_LIBRARY ${SOURCE_DIR}/.libs/${TCMALLOC_LIB_NAME}) +file(MAKE_DIRECTORY ${TCMALLOC_INCLUDE_DIR}) # Must exist. + +set_property(TARGET TCMalloc PROPERTY IMPORTED_LOCATION ${TCMALLOC_LIBRARY}) +set_property(TARGET TCMalloc PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${TCMALLOC_INCLUDE_DIR}) + +add_dependencies(TCMalloc gperftools) +unset(SOURCE_DIR) diff --git a/cpp/cmake/ProjectWedprCrypto.cmake b/cpp/cmake/ProjectWedprCrypto.cmake new file mode 100644 index 00000000..641c6fa3 --- /dev/null +++ b/cpp/cmake/ProjectWedprCrypto.cmake @@ -0,0 +1,35 @@ +include(ExternalProject) +include(GNUInstallDirs) + +find_program(CARGO_COMMAND NAMES cargo REQUIRED PATHS "${USER_HOME}\\.cargo\\bin") + +if(NOT CARGO_COMMAND) + message(FATAL_ERROR "cargo is not installed") +endif() + +file(MAKE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/deps/) + +set(ECC_DIR "ffi/ffi_c/ffi_c_ecc_edwards25519") +ExternalProject_Add(WEDPR_CRYPTO_ECC + PREFIX ${CMAKE_CURRENT_SOURCE_DIR}/deps + GIT_REPOSITORY https://${URL_BASE}/WeBankBlockchain/WeDPR-Lab-Crypto.git + GIT_TAG c569186dd4bb73c5348012e15b2db18f7f20c103 + GIT_SHALLOW false + BUILD_IN_SOURCE 1 + CONFIGURE_COMMAND "" + BUILD_COMMAND cd ${ECC_DIR} && ${CARGO_COMMAND} build --release + INSTALL_COMMAND cp /target/release/libffi_c_edwards25519.a ${CMAKE_SOURCE_DIR}/deps/${CMAKE_INSTALL_LIBDIR}/libffi_c_edwards25519.a + LOG_DOWNLOAD 1 + LOG_CONFIGURE 1 + LOG_BUILD 0 + LOG_INSTALL 1 + ) + +ExternalProject_Get_Property(WEDPR_CRYPTO_ECC SOURCE_DIR) + +set(WEDPR_LIBRARY ${CMAKE_SOURCE_DIR}/deps/${CMAKE_INSTALL_LIBDIR}/libffi_c_edwards25519.a) + +add_library(wedpr_ecc INTERFACE IMPORTED) +set_property(TARGET wedpr_ecc PROPERTY INTERFACE_LINK_LIBRARIES ${WEDPR_LIBRARY}) +add_dependencies(wedpr_ecc WEDPR_CRYPTO_ECC) +unset(SOURCE_DIR) diff --git a/cpp/cmake/TargetSettings.cmake b/cpp/cmake/TargetSettings.cmake new file mode 100644 index 00000000..e66f019b --- /dev/null +++ b/cpp/cmake/TargetSettings.cmake @@ -0,0 +1,146 @@ +set(BCOS_UTILITIES_TARGET "bcos-utilities") +set(PROTOBUF_TARGET "protobuf::libprotobuf") +# ppc-crypto-core +set(CRYPTO_CORE_TARGET "ppc-crypto-core") +set(BCOS_BOOSTSSL_TARGET "bcos-boostssl") + +# ppc-crypto +set(CRYPTO_TARGET "ppc-crypto") +set(PAILLIER_TARGET "ppc-paillier") +set(FAHE_TARGET "ppc-fahe") +set(IHC_TARGET "ppc-ihc") +set(CRYPTO_CODEC_TARGET "ppc-crypto-codec") + +# ppc-tools +set(TOOLS_TARGET "ppc-tools") + +# ppc-protocol +set(PROTOCOL_TARGET "ppc-protocol") + +# wedpr-protocol/tars +set(TARS_PROTOCOL_TARGET "wedpr-tars-protocol") + +# wedpr-protocol/protobuf +set(PB_PROTOCOL_TARGET "wedpr-pb-protocol") + +# wedpr-protocol/grpc/client +set(SERVICE_CLIENT_TARGET "wedpr-client") +# wedpr-protocol/grpc/server +set(SERVICE_SERVER_TARGET "wedpr-server") +# wedpr-protocol/proto generated file +set(SERVICE_PB_TARGET "service-pb") + +# ppc-front +SET(FRONT_TARGET "ppc-front") + +# ppc-gateway +set(GATEWAY_TARGET "ppc-gateway") + +# ppc-io +set(IO_TARGET "ppc-io") + +# ppc-storage +set(STORAGE_TARGET "ppc-storage") + +# ppc-psi: labeled_ps +set(PSI_FRAMEWORK_TARGET "psi-framework") +set(LABELED_PSI_TARGET "ppc-labeled-psi") +set(RA2018_PSI_TARGET "ppc-ra2018-psi") +set(CM2020_PSI_TARGET "ppc-cm2020-psi") +set(ECDH_2PC_PSI_TARGET "ecdh-2pc-psi") +set(ECDH_MULTI_PSI_TARGET "ecdh-multi-psi") +# TODO: optimize here +#set(ECDH_CONN_PSI_TARGET "ecdh-conn-psi") +set(ECDH_CONN_PSI_TARGET "") + +# ppc-http +set(HTTP_TARGET "ppc-http") +set(BS_ECDH_PSI_TARGET "bs-ecdh-psi") + +# ppc-rpc +set(RPC_TARGET "ppc-rpc") + +# libhelper +set(HELPER_TARGET "ppc-helper") + +# wedpr-initializer +set(INIT_LIB "wedpr-inititializer") + +# ppc-cem +set(CEM_TARGET "ppc-cem") + +# ppc-mpc +set(MPC_TARGET "ppc-mpc") + +# ppc-pir +set(PIR_TARGET "ppc-pir") + +# the binary-name +set(GATEWAY_BINARY_NAME ppc-gateway-service) +set(GATEWAY_PKG_NAME PPCGatewayService) + +# current only include the psi function +set(PRO_BINARY_NAME ppc-pro-node) +set(PPC_NODE_PKG_NAME PPCProNodeService) + +set(AIR_BINARY_NAME ppc-air-node) +set(CEM_BINARY_NAME wedpr-cem) +set(MPC_BINARY_NAME wedpr-mpc) + +set(HDFS_LIB libhdfs3) + +# set cpu-info +set(CPU_FEATURES_LIB "") +if (ENABLE_CPU_FEATURES) + set(CPU_FEATURES_LIB CpuFeatures::cpu_features) +endif () + +#====== wedpr-crypto-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) + +# 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") +endif() +#====== wedpr-crypto-sdk =========== + + +#====== ppc-crypto-sdk-jni =========== +set(PPC_CRYPTO_SDK_JNI_TARGET ppc-crypto-sdk-jni) +set(PPC_CRYPTO_SDK_JNI_STATIC_TARGET ppc-crypto-sdk-jni-static) +# add suffix for arm +if(ARCH_NATIVE) + set(PPC_CRYPTO_SDK_JNI_TARGET "ppc-crypto-sdk-jni-aarch64") + set(PPC_CRYPTO_SDK_JNI_STATIC_TARGET "ppc-crypto-sdk-jni-static-aarch64") +endif() +#====== ppc-crypto-sdk-jni =========== + +# ========== ppc-udf =========== +set(PPC_UDF_TARGET ppc-udf) +set(PPC_UDF_STATIC_TARGET ppc-udf-static) + +# add suffix for arm +if(ARCH_NATIVE) + set(PPC_UDF_TARGET ppc-udf-aarch64) + set(PPC_UDF_STATIC_TARGET ppc-udf-static-aarch64) +endif() +# ========== ppc-udf =========== + +set(BOOST_UNIT_TEST Boost::unit_test_framework) + +# ==== the transport sdk=== +set(WEDPR_TRANSPORT_SDK_TARGET wedpr-transport-sdk) + +# ==== the swig wrapper ===== +set(WEDPR_PYTHON_TRANSPORT "wedpr_python_transport") +set(WEDPR_PYTHON_TRANSPORT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/python/generated/${WEDPR_PYTHON_TRANSPORT}) +set(WEDPR_PYTHON_TRANSPORT_LIB_DIR ${CMAKE_CURRENT_SOURCE_DIR}/wedpr-transport/sdk-wrapper/python/bindings/wedpr_python_gateway_sdk/libs) + +set(WEDPR_JAVA_TRANSPORT "wedpr_java_transport_jni") +set(WEDPR_JAVA_TRANSPORT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/java/generated/${WEDPR_JAVA_TRANSPORT}) +set(WEDPR_JAVA_TRANSPORT_LIB_DIR ${CMAKE_CURRENT_SOURCE_DIR}/wedpr-transport/sdk-wrapper/java/bindings/src/main/resources/META-INF/native) diff --git a/cpp/cmake/Version.cmake b/cpp/cmake/Version.cmake new file mode 100644 index 00000000..8259d91c --- /dev/null +++ b/cpp/cmake/Version.cmake @@ -0,0 +1,2 @@ +set(VERSION "3.0.0") +set(PYTHON_TOOLKIT_VERSION "3.0.0") diff --git a/cpp/cmake/config.cmake b/cpp/cmake/config.cmake new file mode 100644 index 00000000..47e003f5 --- /dev/null +++ b/cpp/cmake/config.cmake @@ -0,0 +1,74 @@ +hunter_config(tarscpp VERSION 3.0.4-local + URL https://${URL_BASE}/FISCO-BCOS/TarsCpp/archive/e1a1df43e42a636d26c59f7fc12f62ae756d9ffc.tar.gz + SHA1 8632a852c0dbf367d8d4c4d2957fde2ff713abe0 + ) +hunter_config(cryptopp VERSION 8.6.0 + URL "https://${URL_BASE}/FISCO-BCOS/cryptopp/archive/1887f2f05679debf5d5b9553b8d1a686049eb8c0.tar.gz" + SHA1 062e044d15415151ddebe67cce63fbaeba4ba596 + ) + +# Note: mysql-connector-cpp default use the tassl +hunter_config(mysql-connector-cpp VERSION 8.0.31-local + URL "https://github.com/mysql/mysql-connector-cpp/archive/8.0.31.tar.gz" + SHA1 082c58faa4fbf61b796ccdb0b075b4cb3c331b9d + CMAKE_ARGS WITH_HUNTER_OpenSSl=ON WITH_HUNTER_PROTOBUF=ON + BUILDTYPE_DOCSTRING=${CMAKE_BUILD_TYPE} + ) + +hunter_config(OpenSSL VERSION tassl_1.1.1b_v1.4-local + URL https://${URL_BASE}/FISCO-BCOS/TASSL-1.1.1b/archive/5144cc460da7b7de36e27780aba0fd928da222ed.tar.gz + SHA1 e0d6de3a5abb2ea09cdf3fd22e50bd8b866125d6 + ) + +hunter_config(hiredis VERSION ${HUNTER_hiredis_VERSION}) +hunter_config(redis-plus-plus VERSION 1.3.6-local + URL https://${URL_BASE}/sewenew/redis-plus-plus/archive/1.3.6.tar.gz + SHA1 650a9fc65c958119f5360ae7dc2341487a29ac6d + CMAKE_ARGS REDIS_PLUS_PLUS_BUILD_STATIC=ON) + +hunter_config(SEAL VERSION 4.0.0 + URL https://${URL_BASE}/microsoft/SEAL/archive/4.0.0.tar.gz + SHA1 1ed568161c784d41a485590b08f841d213726e76 + CMAKE_ARGS SEAL_THROW_ON_TRANSPARENT_CIPHERTEXT=OFF + ) + +hunter_config(Kuku VERSION 2.1.0 + URL https://${URL_BASE}/microsoft/Kuku/archive/2.1.0.tar.gz + SHA1 9dc206b885bd8da17877d78849c1b17a29bef59f + ) +hunter_config(tbb VERSION 2021.3.0 CMAKE_ARGS BUILD_SHARED_LIBS=OFF) + + +# the dependencies for libhdfs3 +hunter_config(Protobuf VERSION "3.19.4-p0" + URL https://github.com/cpp-pm/protobuf/archive/v3.19.4-p0.tar.gz + SHA1 e5b797dbc4e6ad92d0924ae86c130be4354c35b6 + CMAKE_ARGS CMAKE_POSITION_INDEPENDENT_CODE=TRUE + ) +hunter_config(libxml2 VERSION "2.9.7-p0" CMAKE_ARGS CMAKE_POSITION_INDEPENDENT_CODE=TRUE) +hunter_config(uuid VERSION 1.0.3 CMAKE_ARGS CMAKE_POSITION_INDEPENDENT_CODE=TRUE) + +hunter_config(cpu_features VERSION 0.7.0 + URL https://${URL_BASE}/google/cpu_features/archive/v0.7.0.tar.gz + SHA1 dacec18454c542ef450c883f45be7b2deaba7a91 + CMAKE_ARGS + CMAKE_POSITION_INDEPENDENT_CODE=TRUE + BUILD_TESTING=OFF + ) + +hunter_config(libhdfs3 VERSION 3.0.0-local + URL https://${URL_BASE}/FISCO-BCOS/libhdfs3/archive/f63e08d0c45f76591e448b56eb3f1b4e7de09c13.tar.gz + SHA1 88fdd418500478ea35fb09911d088430f0835893 + CMAKE_ARGS + ENABLE_BOOST=OFF + ENABLE_COVERAGE=OFF + ENABLE_SSE=${ENABLE_SSE} + ) + +hunter_config(ipp-crypto VERSION 202104-local + URL https://${URL_BASE}/intel/ipp-crypto/archive/ippcp_2021.4.tar.gz + SHA1 72edc2d16c30ec1612f45793befbc5689f72970f + CMAKE_ARGS + WITH_HUNTER_OpenSSl=ON + ) + \ No newline at end of file diff --git a/cpp/cmake/grpc.cmake b/cpp/cmake/grpc.cmake new file mode 100644 index 00000000..f02b80b5 --- /dev/null +++ b/cpp/cmake/grpc.cmake @@ -0,0 +1,24 @@ +if(NOT GRPC_CPP_PLUGIN AND TARGET gRPC::grpc_cpp_plugin) + get_target_property(GRPC_CPP_PLUGIN gRPC::grpc_cpp_plugin + IMPORTED_LOCATION_RELEASE) + if(NOT EXISTS "${GRPC_CPP_PLUGIN}") + get_target_property(GRPC_CPP_PLUGIN gRPC::grpc_cpp_plugin + IMPORTED_LOCATION_RELWITHDEBINFO) + endif() + if(NOT EXISTS "${GRPC_CPP_PLUGIN}") + get_target_property(GRPC_CPP_PLUGIN gRPC::grpc_cpp_plugin + IMPORTED_LOCATION_MINSIZEREL) + endif() + if(NOT EXISTS "${GRPC_CPP_PLUGIN}") + get_target_property(GRPC_CPP_PLUGIN gRPC::grpc_cpp_plugin + IMPORTED_LOCATION_DEBUG) + endif() + if(NOT EXISTS "${GRPC_CPP_PLUGIN}") + get_target_property(GRPC_CPP_PLUGIN gRPC::grpc_cpp_plugin + IMPORTED_LOCATION_NOCONFIG) + endif() +endif() + +set(PROTOC_BINARY ${Protobuf_PROTOC_EXECUTABLE}) +message("# PROTOC_BINARY: ${Protobuf_PROTOC_EXECUTABLE}") +message("# GRPC_CPP_PLUGIN: ${GRPC_CPP_PLUGIN}") \ No newline at end of file diff --git a/cpp/cmake/python.cmake b/cpp/cmake/python.cmake new file mode 100644 index 00000000..cbd54a70 --- /dev/null +++ b/cpp/cmake/python.cmake @@ -0,0 +1,94 @@ +if(NOT BUILD_PYTHON) + return() +endif() +# Find Python 3 +find_package(Python REQUIRED COMPONENTS Interpreter Development) +message("Python_FOUND:${Python_FOUND}") +message("Python_VERSION:${Python_VERSION}") +message("Python_Development_FOUND:${Python_Development_FOUND}") +message("Python_LIBRARIES:${Python_LIBRARIES}") +message("Python_INCLUDE_DIRS:${Python_INCLUDE_DIRS}") + +list(APPEND CMAKE_SWIG_FLAGS "-D${Python_LIBRARIES}") +message("## CMAKE_SWIG_FLAGS: ${CMAKE_SWIG_FLAGS}") + +function(search_python_module) + set(options NO_VERSION) + set(oneValueArgs NAME PACKAGE) + set(multiValueArgs "") + cmake_parse_arguments(MODULE + "${options}" + "${oneValueArgs}" + "${multiValueArgs}" + ${ARGN} + ) + message(STATUS "Searching python module: \"${MODULE_NAME}\"") + if(${MODULE_NO_VERSION}) + execute_process( + COMMAND ${Python3_EXECUTABLE} -c "import ${MODULE_NAME}" + RESULT_VARIABLE _RESULT + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + set(MODULE_VERSION "unknown") + else() + execute_process( + COMMAND ${Python3_EXECUTABLE} -c "import ${MODULE_NAME}; print(${MODULE_NAME}.__version__)" + RESULT_VARIABLE _RESULT + OUTPUT_VARIABLE MODULE_VERSION + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + endif() + if(${_RESULT} STREQUAL "0") + message(STATUS "Found python module: \"${MODULE_NAME}\" (found version \"${MODULE_VERSION}\")") + else() + if(FETCH_PYTHON_DEPS) + message(WARNING "Can't find python module: \"${MODULE_NAME}\", install it using pip...") + execute_process( + COMMAND ${Python3_EXECUTABLE} -m pip install --user ${MODULE_PACKAGE} + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + else() + message(FATAL_ERROR "Can't find python module: \"${MODULE_NAME}\", please install it using your system package manager.") + endif() + endif() +endfunction() + +# Find if a python builtin module is available. +# e.g +# search_python_internal_module( +# NAME +# mypy_protobuf +# ) +function(search_python_internal_module) + set(options "") + set(oneValueArgs NAME) + set(multiValueArgs "") + cmake_parse_arguments(MODULE + "${options}" + "${oneValueArgs}" + "${multiValueArgs}" + ${ARGN} + ) + message(STATUS "Searching python module: \"${MODULE_NAME}\"") + execute_process( + COMMAND ${Python3_EXECUTABLE} -c "import ${MODULE_NAME}" + RESULT_VARIABLE _RESULT + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + if(${_RESULT} STREQUAL "0") + message(STATUS "Found python internal module: \"${MODULE_NAME}\"") + else() + message(FATAL_ERROR "Can't find python internal module \"${MODULE_NAME}\", please install it using your system package manager.") + endif() +endfunction() + +# Look for python module wheel +search_python_module( + NAME setuptools + PACKAGE setuptools) +search_python_module( + NAME wheel + PACKAGE wheel) \ No newline at end of file diff --git a/cpp/cmake/scripts/buildinfo.cmake b/cpp/cmake/scripts/buildinfo.cmake new file mode 100644 index 00000000..338156d0 --- /dev/null +++ b/cpp/cmake/scripts/buildinfo.cmake @@ -0,0 +1,70 @@ +macro(replace_if_different SOURCE DST) + set(extra_macro_args ${ARGN}) + set(options CREATE) + set(one_value_args) + set(multi_value_args) + cmake_parse_arguments(REPLACE_IF_DIFFERENT "${options}" "${one_value_args}" "${multi_value_args}" "${extra_macro_args}") + + if (REPLACE_IF_DIFFERENT_CREATE AND (NOT (EXISTS "${DST}"))) + file(WRITE "${DST}" "") + endif() + + execute_process(COMMAND ${CMAKE_COMMAND} -E compare_files "${SOURCE}" "${DST}" RESULT_VARIABLE DIFFERENT OUTPUT_QUIET ERROR_QUIET) + + if (DIFFERENT) + execute_process(COMMAND ${CMAKE_COMMAND} -E rename "${SOURCE}" "${DST}") + else() + execute_process(COMMAND ${CMAKE_COMMAND} -E remove "${SOURCE}") + endif() +endmacro() + +if (NOT PPC_BUILD_TYPE) + set(PPC_BUILD_TYPE "unknown") +endif() + +if (NOT PPC_BUILD_PLATFORM) + set(PPC_BUILD_PLATFORM "unknown") +endif() + +execute_process( + COMMAND git --git-dir=${PPC_SOURCE_DIR}/.git --work-tree=${PPC_SOURCE_DIR} rev-parse HEAD + OUTPUT_VARIABLE PPC_COMMIT_HASH OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET +) + +if (NOT PPC_COMMIT_HASH) + set(PPC_COMMIT_HASH 0) +endif() + +execute_process( + COMMAND git --git-dir=${PPC_SOURCE_DIR}/.git --work-tree=${PPC_SOURCE_DIR} diff HEAD --shortstat + OUTPUT_VARIABLE PPC_LOCAL_CHANGES OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET +) + +execute_process( + COMMAND date "+%Y%m%d %H:%M:%S" + OUTPUT_VARIABLE PPC_BUILD_TIME OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET + ) + +execute_process( + COMMAND date "+%Y%m%d" + OUTPUT_VARIABLE PPC_BUILD_NUMBER OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET + ) + +execute_process( + COMMAND git rev-parse --abbrev-ref HEAD + OUTPUT_VARIABLE PPC_BUILD_BRANCH OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET + ) + +if (PPC_LOCAL_CHANGES) + set(PPC_CLEAN_REPO 0) +else() + set(PPC_CLEAN_REPO 1) +endif() + +set(TMPFILE "${PPC_DST_DIR}/BuildInfo.h.tmp") +set(OUTFILE "${PPC_DST_DIR}/BuildInfo.h") + +configure_file("${PPC_BUILDINFO_IN}" "${TMPFILE}") + +replace_if_different("${TMPFILE}" "${OUTFILE}" CREATE) + diff --git a/cpp/cmake/swig.cmake b/cpp/cmake/swig.cmake new file mode 100644 index 00000000..850d636b --- /dev/null +++ b/cpp/cmake/swig.cmake @@ -0,0 +1,20 @@ +if(NOT AUTO_GENERATE) + return() +endif() + +# Use latest UseSWIG module (3.14) and Python3 module (3.18) +cmake_minimum_required(VERSION 3.18) + +# Will need swig +set(CMAKE_SWIG_FLAGS) + +find_package(SWIG REQUIRED) +include(UseSWIG) + +if(${SWIG_VERSION} VERSION_GREATER_EQUAL 4) + list(APPEND CMAKE_SWIG_FLAGS "-doxygen") +endif() + +if(UNIX AND NOT APPLE) + list(APPEND CMAKE_SWIG_FLAGS "-DSWIGWORDSIZE64") +endif() diff --git a/cpp/cmake/templates/BuildInfo.h.in b/cpp/cmake/templates/BuildInfo.h.in new file mode 100644 index 00000000..4bb5187b --- /dev/null +++ b/cpp/cmake/templates/BuildInfo.h.in @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2022 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 BuildInfo.h + */ +#pragma once +#define PPC_COMMIT_HASH "@PPC_COMMIT_HASH@" +#define PPC_CLEAN_REPO "@PPC_CLEAN_REPO@" +#define PPC_BUILD_TYPE "@PPC_BUILD_TYPE@" +#define PPC_BUILD_OS "@PPC_BUILD_OS@" +#define PPC_BUILD_COMPILER "@PPC_BUILD_COMPILER@" +#define PPC_BUILD_PLATFORM "@PPC_BUILD_PLATFORM@" +#define PPC_BUILD_NUMBER "@PPC_BUILD_NUMBER@" +#define PPC_VERSION_SUFFIX "@PPC_VERSION_SUFFIX@" +#define PPC_BUILD_TIME "@PPC_BUILD_TIME@" +#define PPC_BUILD_BRANCH "@PPC_BUILD_BRANCH@" +#define PPC_PROJECT_VERSION "@PROJECT_VERSION@@PPC_VERSION_SUFFIX@" \ No newline at end of file diff --git a/cpp/ppc-framework/Common.h b/cpp/ppc-framework/Common.h new file mode 100644 index 00000000..cfd3f7f3 --- /dev/null +++ b/cpp/ppc-framework/Common.h @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2022 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 Common.h + * @author: yujiechen + * @date 2022-10-20 + */ +#pragma once +#include +#if ENABLE_CPU_FEATURES +#if X86 +#include +#endif +#if ARCH +#include +#endif +#endif + +#if defined(WIN32) || defined(WIN64) || defined(_WIN32) || defined(_WIN32_) +#define WIN32_LEAN_AND_MEAN +#include +#endif + +#include +#include + +namespace ppc +{ +/// construct a new exception class overriding Exception +#define DERIVE_PPC_EXCEPTION(X) \ + struct X : virtual bcos::Exception \ + { \ + } + +#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); +DERIVE_PPC_EXCEPTION(WeDPRException); + +#if ENABLE_CPU_FEATURES +#if X86 +static const cpu_features::X86Features CPU_FEATURES = cpu_features::GetX86Info().features; +#endif +#if ARCH +static const cpu_features::Aarch64Features CPU_FEATURES = cpu_features::GetAarch64Info().features; +#endif +#endif + +using u128 = boost::multiprecision::number>; + +// for double support +using u1024 = boost::multiprecision::number>; + +using s1024 = boost::multiprecision::number>; + +using float50 = boost::multiprecision::cpp_dec_float_50; +} // namespace ppc \ No newline at end of file diff --git a/cpp/ppc-framework/Helper.h b/cpp/ppc-framework/Helper.h new file mode 100644 index 00000000..6684fa04 --- /dev/null +++ b/cpp/ppc-framework/Helper.h @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2022 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 Common.h + * @author: yujiechen + * @date 2022-10-20 + */ +#pragma once +#include +#include +namespace ppc +{ +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); +} + + +template +inline std::string_view printNodeID(T const& nodeID) +{ + return std::string_view((const char*)nodeID.data(), nodeID.size()); +} + +template +inline std::string printCollection(T const& collection) +{ + std::ostringstream oss; + for (auto const& it : collection) + { + oss << it << ","; + } + return oss.str(); +} +} // namespace ppc \ No newline at end of file diff --git a/cpp/ppc-framework/crypto/CryptoBox.h b/cpp/ppc-framework/crypto/CryptoBox.h new file mode 100644 index 00000000..b57c18d1 --- /dev/null +++ b/cpp/ppc-framework/crypto/CryptoBox.h @@ -0,0 +1,41 @@ +/** + * Copyright (C) 2022 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 CryptoBox.h + * @author: yujiechen + * @date 2022-11-7 + */ +#pragma once +#include "EccCrypto.h" +#include "Hash.h" +namespace ppc::crypto +{ +class CryptoBox +{ +public: + using Ptr = std::shared_ptr; + CryptoBox() = delete; + CryptoBox(Hash::Ptr const& _hashImpl, EccCrypto::Ptr const& _eccCrypto) + : m_hashImpl(_hashImpl), m_eccCrypto(_eccCrypto) + {} + + Hash::Ptr const& hashImpl() const { return m_hashImpl; } + EccCrypto::Ptr const& eccCrypto() const { return m_eccCrypto; } + +private: + Hash::Ptr m_hashImpl; + EccCrypto::Ptr m_eccCrypto; +}; +} // namespace ppc::crypto \ No newline at end of file diff --git a/cpp/ppc-framework/crypto/ECDHCrypto.h b/cpp/ppc-framework/crypto/ECDHCrypto.h new file mode 100644 index 00000000..ac634836 --- /dev/null +++ b/cpp/ppc-framework/crypto/ECDHCrypto.h @@ -0,0 +1,51 @@ +/** + * Copyright (C) 2022 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 ECDHCrypto.h + * @author: yujiechen + * @date 2022-12-28 + */ +#pragma once +#include "../io/DataBatch.h" +#include "ppc-framework/crypto/CryptoBox.h" +#include +namespace ppc::crypto +{ +class ECDHCrypto +{ +public: + using Ptr = std::shared_ptr; + ECDHCrypto() = default; + virtual ~ECDHCrypto() = default; + + // calculate the ecdh public-key according to privateKey and input + virtual std::vector batchGetPublicKey(ppc::io::DataBatch::Ptr const& _input) = 0; + // calculate the ecdh shared-publicKey according to the publicKey and privateKey + virtual std::vector batchGetSharedPublicKey( + std::vector const& _publicKey) = 0; +}; + +class ECDHCryptoFactory +{ +public: + using Ptr = std::shared_ptr; + ECDHCryptoFactory() = default; + virtual ~ECDHCryptoFactory() = default; + + virtual ECDHCrypto::Ptr createECDHCrypto(int _curveType, int _hashType) const = 0; + + virtual CryptoBox::Ptr createCryptoBox(int8_t _curveType, int8_t _hashType) const = 0; +}; +} // namespace ppc::crypto \ No newline at end of file diff --git a/cpp/ppc-framework/crypto/EccCrypto.h b/cpp/ppc-framework/crypto/EccCrypto.h new file mode 100644 index 00000000..1e1942b4 --- /dev/null +++ b/cpp/ppc-framework/crypto/EccCrypto.h @@ -0,0 +1,68 @@ +/** + * Copyright (C) 2022 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 EccCrypto.h + * @author: yujiechen + * @date 2022-11-1 + */ +#pragma once +#include "../protocol/Protocol.h" +#include "Hash.h" +#include +#include + +namespace ppc::crypto +{ +class EccCrypto +{ +public: + using Ptr = std::shared_ptr; + EccCrypto() = default; + virtual ~EccCrypto() {} + + virtual uint32_t pointSizeInBytes() const = 0; + // get the curve + virtual ppc::protocol::ECCCurve getCurve() const = 0; + // generate a random group-element + virtual bcos::bytes generateRandomScalar() const = 0; + // convert the hashData into ec-point over the given curve + virtual bcos::bytes hashToCurve(bcos::bytes&& _hashData) const = 0; + virtual bcos::bytes hashToCurve(bcos::bytes const& _hashData) const = 0; + virtual bcos::bytes hashToScalar(bcos::bytes const& _hashData) const = 0; + + // get the multiplicative inverse of _data over the given curve + virtual bcos::bytes scalarInvert(bcos::bytes const& _data) const = 0; + virtual bcos::bytes scalarAdd(bcos::bytes const& _data1, bcos::bytes const& _data2) const = 0; + virtual bcos::bytes scalarSub(bcos::bytes const& _data1, bcos::bytes const& _data2) const = 0; + virtual bcos::bytes scalarMul(bcos::bytes const& _data1, bcos::bytes const& _data2) const = 0; + // multiply the _ecPoint by _scalar + virtual bcos::bytes ecMultiply( + bcos::bytes const& _ecPoint, bcos::bytes const& _scalar) const = 0; + virtual bcos::bytes ecAdd(bcos::bytes const& _ecPointA, bcos::bytes const& _ecPointB) const = 0; + virtual bcos::bytes ecSub(bcos::bytes const& _ecPointA, bcos::bytes const& _ecPointB) const = 0; + virtual bool isValidEcPoint(bcos::bytes const& _ecPoint) const = 0; + virtual bcos::bytes mulGenerator(bcos::bytes const& _scalar) const = 0; +}; + +class EccCryptoFactory +{ +public: + using Ptr = std::shared_ptr; + EccCryptoFactory() = default; + virtual ~EccCryptoFactory() = default; + + virtual EccCrypto::Ptr createEccCrypto(int8_t _curveType, Hash::Ptr const& _hashImpl) const = 0; +}; +} // namespace ppc::crypto diff --git a/cpp/ppc-framework/crypto/Hash.h b/cpp/ppc-framework/crypto/Hash.h new file mode 100644 index 00000000..66509cf0 --- /dev/null +++ b/cpp/ppc-framework/crypto/Hash.h @@ -0,0 +1,66 @@ +/** + * Copyright (C) 2022 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 Hash.h + * @author: yujiechen + * @date 2022-11-2 + */ +#pragma once +#include "../protocol/Protocol.h" +#include +#include +namespace ppc::crypto +{ +class HashState +{ +public: + using Ptr = std::shared_ptr; + HashState() = default; + virtual ~HashState() {} + virtual void* state() = 0; +}; + +class Hash +{ +public: + using Ptr = std::shared_ptr; + Hash() = default; + virtual ~Hash() = default; + + // the hashBytes length of given hash-algorithm + virtual size_t hashLen() const = 0; + // the implementation of the hash-algorithm + virtual ppc::protocol::HashImplName type() const = 0; + + // calculate-hash + virtual bcos::bytes hash(bcos::bytesConstRef _input) const = 0; + // init the hash-state + virtual HashState::Ptr init() const = 0; + // update new message into the given hash-state + virtual void update(HashState::Ptr _state, bcos::bytesConstRef _data) const = 0; + // obtain the hash-result from the given hash-state + virtual bcos::bytes final(HashState::Ptr _state) const = 0; +}; + +class HashFactory +{ +public: + using Ptr = std::shared_ptr; + HashFactory() = default; + virtual ~HashFactory() = default; + + virtual Hash::Ptr createHashImpl(int8_t _hashType) const = 0; +}; +} // namespace ppc::crypto \ No newline at end of file diff --git a/cpp/ppc-framework/crypto/Ihc.h b/cpp/ppc-framework/crypto/Ihc.h new file mode 100644 index 00000000..4372d2c6 --- /dev/null +++ b/cpp/ppc-framework/crypto/Ihc.h @@ -0,0 +1,74 @@ +/** + * Copyright (C) 2022 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 Ihc.h + * @author: asherli + * @date 2023-11-23 + */ + +#pragma once +#include "../libwrapper/BigNum.h" +#include "../libwrapper/Buffer.h" +#include +#include + +namespace ppc::homo +{ +class Ihc +{ +public: + enum class IhcMode + { + IHC_128, + IHC_256, + }; + + using Ptr = std::shared_ptr; + Ihc() = default; + virtual ~Ihc() = default; + + // generate key according to given mode + virtual bcos::bytes generateKey() const = 0; + virtual void generateKey(OutputBuffer* _result) const = 0; + + // encrypt the given value to cipher using given key + virtual void encrypt( + OutputBuffer* _cipher, bcos::bytesConstRef const& _key, BIGNUM const* _value) const = 0; + virtual bcos::bytes encrypt(bcos::bytesConstRef const& _key, BIGNUM const* _value) const = 0; + // decrypt the given cipher to value using given key + virtual ppc::crypto::BigNum decrypt( + bcos::bytesConstRef const& _key, bcos::bytesConstRef const& _cipher) const = 0; + // ihc add + virtual void add(OutputBuffer* _addResult, bcos::bytesConstRef const& _c1, + bcos::bytesConstRef const& _c2) const = 0; + virtual bcos::bytes add( + bcos::bytesConstRef const& _c1, bcos::bytesConstRef const& _c2) const = 0; + // ihc sub + virtual void sub(OutputBuffer* _subResult, bcos::bytesConstRef const& _c1, + bcos::bytesConstRef const& _c2) const = 0; + virtual bcos::bytes sub( + bcos::bytesConstRef const& _c1, bcos::bytesConstRef const& _c2) const = 0; + + // ihc scalaMul + virtual void scalaMul(OutputBuffer* _mulResult, BIGNUM const* _value, + bcos::bytesConstRef const& _cipher) const = 0; + virtual bcos::bytes scalaMul( + BIGNUM const* _value, bcos::bytesConstRef const& _cipher) const = 0; + + virtual unsigned int keyBits() const = 0; + virtual unsigned int keyBytes() const = 0; + virtual uint64_t cipherBytes() const = 0; +}; +} // namespace ppc::homo \ No newline at end of file diff --git a/cpp/ppc-framework/crypto/KeyPair.h b/cpp/ppc-framework/crypto/KeyPair.h new file mode 100644 index 00000000..384feca6 --- /dev/null +++ b/cpp/ppc-framework/crypto/KeyPair.h @@ -0,0 +1,42 @@ +/** + * Copyright (C) 2022 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 KeyPair.h + * @author: yujiechen + * @date 2023-08-04 + */ +#pragma once +#include +#include + +namespace ppc::crypto +{ +class KeyPair +{ +public: + using Ptr = std::shared_ptr; + using UniquePtr = std::unique_ptr; + KeyPair() = default; + virtual ~KeyPair() = default; + + virtual void* sk() const = 0; + virtual void* pk() const = 0; + + // serialize the sk + virtual bcos::bytes serializeSK() const = 0; + // serialize the pk + virtual bcos::bytes serializePK() const = 0; +}; +} // namespace ppc::crypto \ No newline at end of file diff --git a/cpp/ppc-framework/crypto/Oprf.h b/cpp/ppc-framework/crypto/Oprf.h new file mode 100644 index 00000000..dab7832d --- /dev/null +++ b/cpp/ppc-framework/crypto/Oprf.h @@ -0,0 +1,115 @@ +/** + * Copyright (C) 2022 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 Oprf.h + * @author: shawnhe + * @date 2022-11-3 + */ + +#pragma once +#include "ppc-framework/protocol/Protocol.h" +#include +#include + +namespace ppc::crypto +{ +/** + * reference: draft-irtf-cfrg-voprf-14 + * title: Oblivious Pseudorandom Functions (OPRFs) using Prime-Order Groups + * url: https://datatracker.ietf.org/doc/draft-irtf-cfrg-voprf/ + * + * In the OPRF mode, a client and server interact to compute output = F(skS, input), where input is + * the client's private input, skS is the server's private key, and output is the OPRF output. After + * the execution of the protocol, the client learns output and the server learns nothing. This + * interaction is shown below. + * + * Client Server(sk) + * ------------------------------------------------------------------------------------- + * blindedElement = Blind(input) + * + * blindedElement + * ----------> + * + * evaluatedElement = BlindEvaluate(sk, blindedElement) + * + * evaluatedElement + * <---------- + * + * output = Finalize(input, blind, evaluatedElement) + */ +class Oprf +{ +public: + using Ptr = std::shared_ptr; + Oprf() = default; + Oprf(ppc::protocol::OprfType _type, uint16_t _outputSize) + : m_type(_type), m_outputSize(_outputSize) + {} + virtual ~Oprf() = default; + + ppc::protocol::OprfType type() { return m_type; } + uint16_t outputSize() { return m_outputSize; } + void setOutputSize(uint16_t _size) { m_outputSize = _size; } + bcos::bytes privateKey() { return m_privateKey; } + void setPrivateKey(bcos::bytes _key) { m_privateKey = std::move(_key); } + +protected: + ppc::protocol::OprfType m_type; + uint16_t m_outputSize; + bcos::bytes m_privateKey; +}; + +class OprfClient : public Oprf +{ +public: + using Ptr = std::shared_ptr; + OprfClient() = default; + OprfClient(ppc::protocol::OprfType _type, uint16_t _outputSize) : Oprf(_type, _outputSize) {} + virtual ~OprfClient() = default; + + // blind input by private key + virtual bcos::bytes blind(const bcos::bytes& _input) const = 0; + virtual bcos::bytes blind(std::string_view _input) const = 0; + virtual std::vector blind(const std::vector& _inputs) const = 0; + + // unblind evaluated item, and hash with input + virtual bcos::bytes finalize( + std::string_view _input, const bcos::bytes& _evaluatedItem) const = 0; + virtual std::vector finalize(const std::vector& _inputs, + const std::vector& _evaluatedItems) const = 0; +}; + + +class OprfServer : public Oprf +{ +public: + using Ptr = std::shared_ptr; + OprfServer() = default; + OprfServer(ppc::protocol::OprfType _type, uint16_t _outputSize) : Oprf(_type, _outputSize) {} + virtual ~OprfServer() = default; + + // evaluate blinded item by private key + virtual bcos::bytes evaluate(const bcos::bytes& _blindedItem) const = 0; + virtual std::vector evaluate( + const std::vector& _blindedItems) const = 0; + + // compute the OPRF output with server's private key + virtual bcos::bytes fullEvaluate(const bcos::bytes& _input) const = 0; + virtual bcos::bytes fullEvaluate(const std::string_view _input) const = 0; + virtual std::vector fullEvaluate( + const std::vector& _inputs) const = 0; +}; + +} // namespace ppc::crypto \ No newline at end of file diff --git a/cpp/ppc-framework/crypto/Ore.h b/cpp/ppc-framework/crypto/Ore.h new file mode 100644 index 00000000..1100c3be --- /dev/null +++ b/cpp/ppc-framework/crypto/Ore.h @@ -0,0 +1,77 @@ +/** + * Copyright (C) 2022 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 Ore.h + * @author: shawnhe + * @date 2023-08-18 + */ +#pragma once + +#include +#include + +namespace ppc::crypto +{ +class Ore +{ +public: + using Ptr = std::shared_ptr; + Ore() = default; + virtual ~Ore() = default; + + virtual bcos::bytes generateKey() const = 0; + virtual void generateKey(OutputBuffer* sk) const = 0; + virtual int keyBytes() const = 0; + + // cipher encoded with hex + virtual std::string encrypt4String( + bcos::bytesConstRef const& _sk, const std::string& _plaintext) const = 0; + virtual void encrypt4String(OutputBuffer* _cipher, bcos::bytesConstRef const& _sk, + bcos::bytesConstRef const& _plaintext) const = 0; + + // cipher encoded with hex + virtual std::string decrypt4String( + bcos::bytesConstRef const& _sk, const std::string& _ciphertext) const = 0; + virtual void decrypt4String(OutputBuffer* plain, bcos::bytesConstRef const& _sk, + bcos::bytesConstRef const& cipher) const = 0; + + // cipher encoded with base64 + virtual std::string encrypt4Integer( + bcos::bytesConstRef const& _sk, const int64_t& _plain) const = 0; + virtual void encrypt4Integer( + OutputBuffer* _cipher, bcos::bytesConstRef const& _sk, const int64_t& _plain) const = 0; + + // cipher encoded with base64 + virtual int64_t decrypt4Integer( + bcos::bytesConstRef const& _sk, const std::string& _cipher) const = 0; + virtual void decrypt4Integer(int64_t* _plain, bcos::bytesConstRef const& _sk, + bcos::bytesConstRef const& _cipher) const = 0; + + // cipher encoded with base64 + virtual std::string encrypt4Float( + bcos::bytesConstRef const& _sk, const float50& _plain) const = 0; + virtual void encrypt4Float( + OutputBuffer* _cipher, bcos::bytesConstRef const& _sk, const float50& _plain) const = 0; + + // cipher encoded with base64 + virtual float50 decrypt4Float( + bcos::bytesConstRef const& _sk, const std::string& _cipher) const = 0; + virtual float50 decrypt4Float( + bcos::bytesConstRef const& _sk, bcos::bytesConstRef const& _cipher) const = 0; + + virtual int compare(const std::string& _ciphertext0, const std::string& _ciphertext1) const = 0; + virtual int compare(InputBuffer const* c1, InputBuffer const* c2) const = 0; +}; +} // namespace ppc::crypto \ No newline at end of file diff --git a/cpp/ppc-framework/crypto/PRNG.h b/cpp/ppc-framework/crypto/PRNG.h new file mode 100644 index 00000000..54c2e49a --- /dev/null +++ b/cpp/ppc-framework/crypto/PRNG.h @@ -0,0 +1,80 @@ +/** + * Copyright (C) 2022 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 PRNG.h + * @author: shawnhe + * @date 2022-11-29 + */ + +#pragma once +#include "../protocol/Protocol.h" +#include +#include + +namespace ppc::crypto +{ +class PRNG +{ +public: + using Ptr = std::shared_ptr; + + // default constructor is not allowed + PRNG() = delete; + virtual ~PRNG() = default; + + PRNG(const bcos::bytes& _seed) : m_seeds(_seed) {} + + virtual ppc::protocol::PRNGImplName type() const = 0; + + // generate `_bytesLen` bytes random numbers, saved in _dest + virtual void generate(bcos::byte* _dest, uint64_t _bytesLen) = 0; + bcos::bytes generate(uint64_t _bytesLen) + { + bcos::bytes res(_bytesLen); + generate(res.data(), _bytesLen); + return res; + } + + // generate one T type random + template + typename std::enable_if::value && std::is_trivial::value, T>::type + generate() + { + T ret; + generate((bcos::byte*)&ret, sizeof(T)); + return ret; + } + + // generate '_size' T type randoms + template + typename std::enable_if::value && std::is_trivial::value, + void>::type + generate(T* dest, uint64_t _size) + { + uint64_t totalLen = _size * sizeof(T); + generate((bcos::byte*)dest, totalLen); + } + + const bcos::bytes& seeds() const { return m_seeds; } + uint64_t totalOutputs() const { return m_totalOutputs; } + +protected: + bcos::bytes m_seeds; + + // the length of the random number that has been output + uint64_t m_totalOutputs{0}; +}; + +} // namespace ppc::crypto \ No newline at end of file diff --git a/cpp/ppc-framework/crypto/Paillier.h b/cpp/ppc-framework/crypto/Paillier.h new file mode 100644 index 00000000..d593e37b --- /dev/null +++ b/cpp/ppc-framework/crypto/Paillier.h @@ -0,0 +1,68 @@ +/** + * Copyright (C) 2022 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 Paillier.h + * @author: yujiechen + * @date 2023-08-04 + */ +#pragma once +#include "../libwrapper/BigNum.h" +#include "../libwrapper/Buffer.h" +#include "KeyPair.h" + +namespace ppc::homo +{ +class Paillier +{ +public: + using Ptr = std::shared_ptr; + Paillier() = default; + virtual ~Paillier() = default; + + // generate the keypair + virtual ppc::crypto::KeyPair::UniquePtr generateKeyPair(unsigned const _keyLength) const = 0; + // encrypt the _value + virtual bcos::bytes encrypt_with_crt(BIGNUM const* _value, void* _keyPair) const = 0; + // encrypt with crt optimization + virtual void encrypt_with_crt(OutputBuffer* _result, OutputBuffer* _rBuffer, + BIGNUM const* _value, void* _keyPair) const = 0; + // encrypt without crt optimization + virtual void encrypt( + OutputBuffer* _result, OutputBuffer* _rBuffer, BIGNUM const* _value, void* _pk) const = 0; + virtual bcos::bytes encrypt(BIGNUM const* _value, void* _pk) const = 0; + + // decrypt the cipher data + virtual ppc::crypto::BigNum decrypt( + bcos::bytesConstRef const& _cipherData, void* _keyPair) const = 0; + + // _cipher1 add _cipher2 + virtual bcos::bytes add(bcos::bytesConstRef const& _cipher1, + bcos::bytesConstRef const& _cipher2, void* _publicKey) const = 0; + virtual void add(OutputBuffer* _result, bcos::bytesConstRef const& _cipher1, + bcos::bytesConstRef const& _cipher2, void* _publicKey) const = 0; + + // _cipher1 sub _cipher2 + virtual bcos::bytes sub(bcos::bytesConstRef const& _cipher1, + bcos::bytesConstRef const& _cipher2, void* _publicKey) const = 0; + virtual void sub(OutputBuffer* _result, bcos::bytesConstRef const& _cipher1, + bcos::bytesConstRef const& _cipher2, void* _publicKey) const = 0; + + // v * _cipher + virtual bcos::bytes scalaMul( + BIGNUM const* v, bcos::bytesConstRef const& _cipher, void* _publicKey) const = 0; + virtual void scalaMul(OutputBuffer* _result, BIGNUM const* v, + bcos::bytesConstRef const& _cipher, void* _publicKey) const = 0; +}; +} // namespace ppc::homo \ No newline at end of file diff --git a/cpp/ppc-framework/crypto/RA2018OprfInterface.h b/cpp/ppc-framework/crypto/RA2018OprfInterface.h new file mode 100644 index 00000000..49ceb853 --- /dev/null +++ b/cpp/ppc-framework/crypto/RA2018OprfInterface.h @@ -0,0 +1,46 @@ +/** + * Copyright (C) 2022 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 RA2018OprfInterface.h + * @author: yujiechen + * @date 2022-12-6 + */ +#pragma once +#include "ppc-framework/io/DataBatch.h" +#include +namespace ppc::crypto +{ +class RA2018OprfInterface +{ +public: + using Ptr = std::shared_ptr; + RA2018OprfInterface() = default; + virtual ~RA2018OprfInterface() = default; + + virtual bcos::bytes generatePrivateKey() = 0; + virtual bcos::bytes inv(bcos::bytes const& _data) = 0; + + virtual void blind(ppc::io::DataBatch::Ptr const& _plainData, bcos::bytes const& _privateKey, + std::vector& _blindResult) = 0; + + virtual void finalize(std::vector const& _evaluatedData, + bcos::bytes const& _invPrivateKey, std::vector& _finalizedResult) = 0; + + virtual void fullEvaluate( + ppc::io::DataBatch::Ptr const& _input, std::vector& _result) = 0; + virtual void evaluate( + std::vector const& _blindData, std::vector& _result) = 0; +}; +} // namespace ppc::crypto \ No newline at end of file diff --git a/cpp/ppc-framework/crypto/SymCrypto.h b/cpp/ppc-framework/crypto/SymCrypto.h new file mode 100644 index 00000000..b073c38f --- /dev/null +++ b/cpp/ppc-framework/crypto/SymCrypto.h @@ -0,0 +1,73 @@ +/** + * Copyright (C) 2022 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 SymCrypto.h + * @author: shawnhe + * @date 2022-11-29 + */ + +#pragma once + +#include "../Common.h" +#include "../libwrapper/Buffer.h" +#include "../protocol/Protocol.h" +#include +#include +#include + +namespace ppc::crypto +{ +class SymCrypto +{ +public: + using Ptr = std::shared_ptr; + static constexpr uint32_t DEFAULT_BLOCK_SIZE_BYTE = 16; + enum class OperationMode : int + { + ECB, + CBC, + CFB, + OFB, + CTR, + }; + SymCrypto() : m_blockSize(16) {} + virtual ~SymCrypto() = default; + + + virtual ppc::protocol::SymCryptoImplName type() const = 0; + + virtual bcos::bytes generateKey(OperationMode _mode) const = 0; + virtual void generateKey(OutputBuffer* _key, OperationMode _mode) const = 0; + + virtual bcos::bytes encrypt(OperationMode _mode, bcos::bytesConstRef const& _sk, + bcos::bytesConstRef const& _iv, bcos::bytesConstRef const& _plaintext) const = 0; + virtual void encrypt(OutputBuffer* _cipher, OperationMode _mode, bcos::bytesConstRef const& _sk, + bcos::bytesConstRef const& _iv, bcos::bytesConstRef const& _plaintext) const = 0; + + virtual void decrypt(OutputBuffer* plain, OperationMode _mode, bcos::bytesConstRef const& _sk, + bcos::bytesConstRef const& _iv, bcos::bytesConstRef const& _ciphertext) const = 0; + + virtual bcos::bytes decrypt(OperationMode _mode, bcos::bytesConstRef const& _sk, + bcos::bytesConstRef const& _iv, bcos::bytesConstRef const& _ciphertext) const = 0; + + virtual unsigned int keyBytes(OperationMode _mode) const = 0; + unsigned int blockSize() const { return m_blockSize; } + +protected: + // the length of the block + unsigned int m_blockSize = DEFAULT_BLOCK_SIZE_BYTE; +}; + +} // namespace ppc::crypto diff --git a/cpp/ppc-framework/front/Channel.h b/cpp/ppc-framework/front/Channel.h new file mode 100644 index 00000000..c344578e --- /dev/null +++ b/cpp/ppc-framework/front/Channel.h @@ -0,0 +1,79 @@ +/** + * Copyright (C) 2022 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. + * + * @brief interface for channel which is the abstract communication unit of the privacy service + * @file Channel.h + * @author: shawnhe + * @date 2022-10-27 + */ + +#pragma once +#include "FrontInterface.h" +#include "ppc-framework/protocol/PPCMessageFace.h" +#include "ppc-framework/protocol/Task.h" +#include +#include + +namespace ppc +{ +namespace front +{ +/** + * Each task hold a channel instance. + * The front can dispatch the message to the specific channel by task ID. + */ +class Channel +{ +public: + using Ptr = std::shared_ptr; + Channel() = default; + virtual ~Channel() {} + +public: + /** + * @brief notice task info to gateway by front + * @param _taskInfo the latest task information + */ + virtual bcos::Error::Ptr notifyTaskInfo(std::string const& taskID) = 0; + + /** + * @brief: send message + * @param _agencyID: message receiver + * @return void + */ + virtual void asyncSendMessage(const std::string& _agencyID, front::PPCMessageFace::Ptr _message, + uint32_t _timeout, ErrorCallbackFunc _callback, CallbackFunc _respCallback) = 0; + + /** + * @brief: receive message, note that one message will consume one handler + * @param _messageType: the message type is defined by each crypto algorithm + * @param _seq: message seq + * @param _secondsTimeout: timeout by seconds + * @return void + */ + virtual void asyncReceiveMessage(uint8_t _messageType, uint32_t _seq, uint32_t _secondsTimeout, + std::function _handler) = 0; + + + /** + * @brief: used for front to dispatch message + * @param _messageType: the message type is defined by each crypto algorithm + * @return void + */ + virtual void onMessageArrived(uint8_t _messageType, front::PPCMessageFace::Ptr _message) = 0; +}; + +} // namespace front +} // namespace ppc \ No newline at end of file diff --git a/cpp/ppc-framework/front/FrontConfig.h b/cpp/ppc-framework/front/FrontConfig.h new file mode 100644 index 00000000..40e0a48a --- /dev/null +++ b/cpp/ppc-framework/front/FrontConfig.h @@ -0,0 +1,117 @@ +/** + * 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 "ppc-framework/protocol/EndPoint.h" +#include "ppc-framework/protocol/GrpcConfig.h" +#include "ppc-framework/protocol/INodeInfo.h" +#include +#include +#include +#include + +namespace ppc::front +{ +// Note: swig explosed interface +class FrontConfig +{ +public: + using Ptr = std::shared_ptr; + FrontConfig() = default; + + FrontConfig(int threadPoolSize, std::string nodeID) + : m_threadPoolSize(threadPoolSize), m_nodeID(std::move(nodeID)) + {} + virtual ~FrontConfig() = default; + + virtual int threadPoolSize() const { return m_threadPoolSize; } + virtual void setThreadPoolSize(int threadPoolSize) { m_threadPoolSize = threadPoolSize; } + + virtual std::string const& nodeID() const { return m_nodeID; } + virtual void setNodeID(std::string const& nodeID) { m_nodeID = nodeID; } + + ppc::protocol::EndPoint const& selfEndPoint() const { return m_selfEndPoint; } + ppc::protocol::EndPoint& mutableSelfEndPoint() { return m_selfEndPoint; } + + void setSelfEndPoint(ppc::protocol::EndPoint const& endPoint) { m_selfEndPoint = endPoint; } + + void setGatewayGrpcTarget(std::string const& gatewayGrpcTarget) + { + m_gatewayGrpcTarget = gatewayGrpcTarget; + } + // refer to: https://github.com/grpc/grpc-node/issues/2066 + // grpc prefer to using ipv4:${host1}:${port1},${host2}:${port2} as target to support multiple + // servers + std::string const& gatewayGrpcTarget() const { return m_gatewayGrpcTarget; } + + void setGrpcConfig(ppc::protocol::GrpcConfig::Ptr grpcConfig) + { + m_grpcConfig = std::move(grpcConfig); + } + ppc::protocol::GrpcConfig::Ptr const& grpcConfig() const { return m_grpcConfig; } + + // generate the nodeInfo + virtual ppc::protocol::INodeInfo::Ptr generateNodeInfo() const = 0; + + virtual std::vector const& getComponents() const { return m_components; } + void setComponents(std::vector const& components) { m_components = components; } + + void addComponent(std::string const& component) { m_components.emplace_back(component); } + + std::vector& mutableComponents() { return m_components; } + + std::string const meta() const { return m_meta; } + void setMeta(std::string meta) { m_meta = std::move(meta); } + +protected: + ppc::protocol::GrpcConfig::Ptr m_grpcConfig; + ppc::protocol::EndPoint m_selfEndPoint; + int m_threadPoolSize; + std::string m_nodeID; + std::string m_gatewayGrpcTarget; + std::vector m_components; + std::string m_meta; +}; + +class FrontConfigBuilder +{ +public: + using Ptr = std::shared_ptr; + FrontConfigBuilder() = default; + virtual ~FrontConfigBuilder() = default; + + virtual FrontConfig::Ptr build() const = 0; + virtual FrontConfig::Ptr build(int threadPoolSize, std::string nodeID) const = 0; +}; + +inline std::string printFrontDesc(FrontConfig::Ptr const& config) +{ + if (!config) + { + return "nullptr"; + } + std::ostringstream stringstream; + stringstream << LOG_KV("endPoint", config->selfEndPoint().entryPoint()) + << LOG_KV("nodeID", config->nodeID()) + << LOG_KV("poolSize", config->threadPoolSize()) + << LOG_KV("target", config->gatewayGrpcTarget()); + return stringstream.str(); +} +} // namespace ppc::front \ No newline at end of file diff --git a/cpp/ppc-framework/front/FrontInterface.h b/cpp/ppc-framework/front/FrontInterface.h new file mode 100644 index 00000000..767afc02 --- /dev/null +++ b/cpp/ppc-framework/front/FrontInterface.h @@ -0,0 +1,86 @@ +/** + * Copyright (C) 2022 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. + * + * @brief interface for front service module + * @file FrontInterface.h + * @author: shawnhe + * @date 2022-10-19 + */ + +#pragma once +#include "../protocol/PPCMessageFace.h" +#include "ppc-framework/protocol/Task.h" +#include + +namespace ppc +{ +namespace front +{ +using ErrorCallbackFunc = std::function; +using ResponseFunc = std::function; +using CallbackFunc = std::function; + +using GetAgencyListCallback = std::function&&)>; + +/** + * @brief: the interface provided by the front service + */ +class FrontInterface +{ +public: + using Ptr = std::shared_ptr; + FrontInterface() = default; + virtual ~FrontInterface() {} + + /** + * @brief: send message to other party by gateway + * @param _agencyID: agency ID of receiver + * @param _message: ppc message data + * @param _callback: callback called when the message sent successfully + * @param _respCallback: callback called when receive the response from peer + * @return void + */ + virtual void asyncSendMessage(const std::string& _agencyID, front::PPCMessageFace::Ptr _message, + uint32_t _timeout, ErrorCallbackFunc _callback, CallbackFunc _respCallback) = 0; + + // send response when receiving message from given agencyID + virtual void asyncSendResponse(bcos::bytes const& dstNode, std::string const& traceID, + front::PPCMessageFace::Ptr message, ErrorCallbackFunc _callback) = 0; + + virtual void registerMessageHandler(uint8_t _taskType, uint8_t _algorithmType, + std::function _handler) = 0; + /** + * @brief notice task info to gateway + * @param _taskInfo the latest task information + */ + virtual bcos::Error::Ptr notifyTaskInfo(std::string const& taskID) = 0; + + // erase the task-info when task finished + virtual bcos::Error::Ptr eraseTaskInfo(std::string const& _taskID) = 0; + + virtual std::string const& selfEndPoint() const { return m_selfEndPoint; } + + virtual std::vector agencies() const = 0; + virtual void start() = 0; + virtual void stop() = 0; + +protected: + // the selfEndPoint for the air-mode-node can be localhost + std::string m_selfEndPoint = "localhost"; +}; + +} // namespace front +} // namespace ppc diff --git a/cpp/ppc-framework/front/IFront.h b/cpp/ppc-framework/front/IFront.h new file mode 100644 index 00000000..9470686b --- /dev/null +++ b/cpp/ppc-framework/front/IFront.h @@ -0,0 +1,312 @@ +/** + * 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 "INodeDiscovery.h" +#include "ppc-framework/protocol/Handler.h" +#include "ppc-framework/protocol/INodeInfo.h" +#include "ppc-framework/protocol/Message.h" +#include "ppc-framework/protocol/RouteType.h" +#include + +namespace ppc::front +{ +class IFrontClient +{ +public: + using Ptr = std::shared_ptr; + IFrontClient() = default; + virtual ~IFrontClient() = default; + /** + * @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; +}; + +///////// the callback definition for sdk wrapper ///////// +class ErrorCallback +{ +public: + using Ptr = std::shared_ptr; + ErrorCallback() = default; + virtual ~ErrorCallback() {} + + virtual void onError(bcos::Error::Ptr error) = 0; +}; + +class MessageDispatcherHandler +{ +public: + using Ptr = std::shared_ptr; + MessageDispatcherHandler() = default; + virtual ~MessageDispatcherHandler() {} + + virtual void onMessage(ppc::protocol::Message::Ptr msg) = 0; +}; + + +class SendResponseHandler +{ +public: + using Ptr = std::shared_ptr; + SendResponseHandler(ppc::protocol::SendResponseFunction responseFunc) + : m_responseFunc(responseFunc) + {} + virtual ~SendResponseHandler() {} + + virtual void sendResponse(std::shared_ptr&& payload) + { + m_responseFunc(std::move(payload)); + } + +private: + ppc::protocol::SendResponseFunction m_responseFunc; +}; + +class IMessageHandler +{ +public: + using Ptr = std::shared_ptr; + IMessageHandler() = default; + virtual ~IMessageHandler() {} + + virtual void onMessage(bcos::Error::Ptr e, ppc::protocol::Message::Ptr msg, + SendResponseHandler sendResponseHandler) = 0; +}; + +class GetPeersInfoHandler +{ +public: + using Ptr = std::shared_ptr; + GetPeersInfoHandler() = default; + virtual ~GetPeersInfoHandler() {} + + virtual void onPeersInfo(bcos::Error::Ptr e, std::string const& peersInfo) = 0; +}; + +///////// the callback definition for sdk wrapper ///////// + +class IFront : virtual public IFrontClient +{ +public: + using Ptr = std::shared_ptr; + + IFront() = default; + ~IFront() override = default; + + /** + * @brief start the IFront + * + * @param front the IFront to start + */ + virtual void start() = 0; + /** + * @brief stop the IFront + * + * @param front the IFront to stop + */ + virtual void stop() = 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::MessageDispatcherCallback callback) = 0; + + /////// to simplify SDK wrapper //// + virtual void register_topic_handler( + std::string const& topic, MessageDispatcherHandler::Ptr callback) + { + registerTopicHandler(topic, populateMessageDispatcherCallback(callback)); + } + + virtual void registerMessageHandler( + std::string const& componentType, ppc::protocol::MessageDispatcherCallback callback) = 0; + + /////// to simplify SDK wrapper //// + virtual void register_msg_handler( + std::string const& componentType, MessageDispatcherHandler::Ptr callback) + { + registerMessageHandler(componentType, populateMessageDispatcherCallback(callback)); + } + + /** + * @brief async send message + * + * @param routeType the route type + * @param routeInfo the route info, include + * - topic the topic + * - dstInst the dst agency(must set when 'route by agency' and 'route by + * component') + * - dstNodeID the dst nodeID(must set when 'route by nodeID') + * - 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(uint16_t routeType, + ppc::protocol::MessageOptionalHeader::Ptr const& routeInfo, bcos::bytesConstRef payload, + int seq, long timeout, ppc::protocol::ReceiveMsgFunc errorCallback, + ppc::protocol::MessageCallback callback) = 0; + + /////// to simplify SDK wrapper //// + + // !!! Note: the 'payload' type(char*) should not been changed, since it used to pass-in java + // byte[] data + virtual void async_send_message(uint16_t routeType, + ppc::protocol::MessageOptionalHeader::Ptr const& routeInfo, char* payload, + uint64_t payloadSize, int seq, long timeout, ErrorCallback::Ptr errorCallback, + IMessageHandler::Ptr msgHandler) + { + asyncSendMessage(routeType, routeInfo, + bcos::bytesConstRef((bcos::byte*)payload, payloadSize), seq, timeout, + populateErrorCallback(errorCallback), populateMsgCallback(msgHandler)); + } + + virtual void asyncSendResponse(bcos::bytesConstRef dstNode, std::string const& traceID, + bcos::bytesConstRef payload, int seq, ppc::protocol::ReceiveMsgFunc errorCallback) = 0; + + /////// to simplify SDK wrapper //// + + // !!! Note: the 'payload ' type(char*) should not been changed, since it used to pass-in java + // byte[] data + virtual void async_send_response(char* dstNode, uint64_t dstNodeSize, + std::string const& traceID, char* payload, uint64_t payloadSize, int seq, + ErrorCallback::Ptr errorCallback) + { + asyncSendResponse(bcos::bytesConstRef((bcos::byte*)dstNode, dstNodeSize), traceID, + bcos::bytesConstRef((bcos::byte*)payload, payloadSize), seq, + populateErrorCallback(errorCallback)); + } + + // the sync interface for async_send_message + virtual bcos::Error::Ptr push(uint16_t routeType, + ppc::protocol::MessageOptionalHeader::Ptr const& routeInfo, bcos::bytesConstRef payload, + int seq, long timeout) = 0; + + // Note: the python not support function overload, for different interfaces with the same + // functionality, it is best to define methods with different names the 'payload', 'payloadSize' + // should not been changed any more, since the swig has defined by the name to convert python + // bytes to cpp (char*, uint64_t) %pybuffer_binary(char* payload, uint64_t payloadSize) + virtual bcos::Error::Ptr push_msg(uint16_t routeType, + ppc::protocol::MessageOptionalHeader::Ptr const& routeInfo, char* payload, + uint64_t payloadSize, int seq, long timeout) + { + return push(routeType, routeInfo, bcos::bytesConstRef((bcos::byte*)payload, payloadSize), + seq, timeout); + } + virtual ppc::protocol::Message::Ptr pop(std::string const& topic, long timeoutMs) = 0; + virtual ppc::protocol::Message::Ptr peek(std::string const& topic) = 0; + + virtual void asyncGetAgencies(std::vector const& components, + std::function)> callback) = 0; + + virtual void asyncGetPeers(GetPeersInfoHandler::Ptr getPeersCallback) = 0; + + /** + * @brief register the nodeInfo to the gateway + * @param nodeInfo the nodeInfo + */ + virtual bcos::Error::Ptr registerNodeInfo(ppc::protocol::INodeInfo::Ptr const& nodeInfo) = 0; + + /** + * @brief unRegister the nodeInfo to the gateway + */ + virtual bcos::Error::Ptr unRegisterNodeInfo() = 0; + + virtual ppc::protocol::INodeInfo::Ptr const& nodeInfo() = 0; + + /** + * @brief register the topic + * + * @param topic the topic to register + */ + virtual bcos::Error::Ptr registerTopic(std::string const& topic) = 0; + + /** + * @brief unRegister the topic + * + * @param topic the topic to unregister + */ + virtual bcos::Error::Ptr unRegisterTopic(std::string const& topic) = 0; + + virtual void registerComponent(std::string const& component) = 0; + virtual void unRegisterComponent(std::string const& component) = 0; + + virtual void updateMetaInfo(std::string const& meta) = 0; + + // get the target nodeList according to the routeInfo + virtual std::vector selectNodesByRoutePolicy( + int16_t routeType, ppc::protocol::MessageOptionalHeader::Ptr const& routeInfo) = 0; + + virtual INodeDiscovery::Ptr const getNodeDiscovery() = 0; + +private: + ppc::protocol::ReceiveMsgFunc populateErrorCallback(ErrorCallback::Ptr errorCallback) + { + if (errorCallback == nullptr) + { + return nullptr; + } + return [errorCallback](bcos::Error::Ptr error) { errorCallback->onError(error); }; + } + + ppc::protocol::MessageDispatcherCallback populateMessageDispatcherCallback( + MessageDispatcherHandler::Ptr handler) + { + if (handler == nullptr) + { + return nullptr; + } + return [handler](ppc::protocol::Message::Ptr msg) { handler->onMessage(msg); }; + } + + ppc::protocol::MessageCallback populateMsgCallback(IMessageHandler::Ptr msgHandler) + { + if (msgHandler == nullptr) + { + return nullptr; + } + return [msgHandler](bcos::Error::Ptr e, ppc::protocol::Message::Ptr msg, + ppc::protocol::SendResponseFunction resFunc) { + SendResponseHandler sendResponseHandler(resFunc); + msgHandler->onMessage(e, msg, sendResponseHandler); + }; + } +}; + +class IFrontBuilder +{ +public: + using Ptr = std::shared_ptr; + IFrontBuilder() = default; + virtual ~IFrontBuilder() = default; + + virtual IFrontClient::Ptr buildClient(std::string endPoint, + std::function onUnHealthHandler, bool removeHandlerOnUnhealth) const = 0; +}; +} // namespace ppc::front \ No newline at end of file diff --git a/cpp/ppc-framework/front/INodeDiscovery.h b/cpp/ppc-framework/front/INodeDiscovery.h new file mode 100644 index 00000000..b0c4792c --- /dev/null +++ b/cpp/ppc-framework/front/INodeDiscovery.h @@ -0,0 +1,39 @@ +/** + * 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 INodeDiscovery.h + * @author: yujiechen + * @date 2024-11-06 + */ +#pragma once +#include "ppc-framework/protocol/INodeInfo.h" +#include + +namespace ppc::front +{ +class INodeDiscovery +{ +public: + using Ptr = std::shared_ptr; + INodeDiscovery() = default; + virtual ~INodeDiscovery() = default; + + virtual void start() = 0; + virtual void stop() = 0; + + // Note: use std::shared_ptr here for swig wrapper + virtual std::vector> getAliveNodeList() 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 new file mode 100644 index 00000000..ebd9b7a3 --- /dev/null +++ b/cpp/ppc-framework/gateway/GatewayProtocol.h @@ -0,0 +1,52 @@ +/** + * 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, + BroadcastMessage = 0x01, + RouterTableSyncSeq = 0x10, + RouterTableResponse = 0x11, + RouterTableRequest = 0x12, + SyncNodeSeq = 0x20, + RequestNodeStatus = 0x21, + ResponseNodeStatus = 0x22, +}; + +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..e917ce20 --- /dev/null +++ b/cpp/ppc-framework/gateway/IGateway.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 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, + ppc::protocol::MessageOptionalHeader::Ptr const& routeInfo, std::string const& traceID, + bcos::bytes&& payload, long timeout, ppc::protocol::ReceiveMsgFunc callback) = 0; + + virtual void asyncSendbroadcastMessage(ppc::protocol::RouteType routeType, + ppc::protocol::MessageOptionalHeader::Ptr const& routeInfo, std::string const& traceID, + bcos::bytes&& payload) = 0; + + virtual void asyncGetPeers(std::function callback) = 0; + virtual void asyncGetAgencies(std::vector const& components, + std::function)> callback) = 0; + + virtual bcos::Error::Ptr registerNodeInfo(ppc::protocol::INodeInfo::Ptr const& nodeInfo) = 0; + virtual bcos::Error::Ptr unRegisterNodeInfo(bcos::bytesConstRef nodeID) = 0; + virtual bcos::Error::Ptr registerTopic( + bcos::bytesConstRef nodeID, std::string const& topic) = 0; + virtual bcos::Error::Ptr unRegisterTopic( + bcos::bytesConstRef nodeID, std::string const& topic) = 0; + + // get the target nodeList according to the routeInfo + virtual std::vector selectNodesByRoutePolicy(ppc::protocol::RouteType routeType, + ppc::protocol::MessageOptionalHeader::Ptr const& routeInfo) = 0; + + virtual std::vector getAliveNodeList() const = 0; +}; + +} // namespace ppc::gateway diff --git a/cpp/ppc-framework/http/HttpInterface.h b/cpp/ppc-framework/http/HttpInterface.h new file mode 100644 index 00000000..e99d7af4 --- /dev/null +++ b/cpp/ppc-framework/http/HttpInterface.h @@ -0,0 +1,55 @@ +/** + * Copyright (C) 2022 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 HttpInterface.h + * @author: zachma + * @date 2023-8-34 + */ + +#pragma once +#include "../protocol/Protocol.h" +#include "../protocol/Task.h" +#include +#include +#include +#include + +#define HTTP_LOG(LEVEL) BCOS_LOG(LEVEL) << LOG_BADGE("HTTP") + +namespace bcos +{ +namespace boostssl +{ +class MessageFace; +class WsSession; +} // namespace boostssl +} // namespace bcos +namespace ppc::http +{ +using RespUrlFunc = std::function; +class HttpInterface +{ +public: + using Ptr = std::shared_ptr; + HttpInterface() = default; + virtual ~HttpInterface() = default; + + virtual void start() = 0; + virtual void stop() = 0; + + virtual void registerUrlHandler(std::string const& _urlName, + std::function _handler) = 0; +}; +} // namespace ppc::http \ No newline at end of file diff --git a/cpp/ppc-framework/http/HttpTypeDef.h b/cpp/ppc-framework/http/HttpTypeDef.h new file mode 100644 index 00000000..d8375e8f --- /dev/null +++ b/cpp/ppc-framework/http/HttpTypeDef.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2022 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 HttpTypeDef.h + * @author: zachma + * @date 2023-8-23 + */ + +#pragma once +#include + +namespace ppc::http +{ + enum class HttpError : int32_t +{ + UriNotFound = -32605, +}; + +} // namespace ppc::http + diff --git a/cpp/ppc-framework/io/DataBatch.h b/cpp/ppc-framework/io/DataBatch.h new file mode 100644 index 00000000..310fd1c0 --- /dev/null +++ b/cpp/ppc-framework/io/DataBatch.h @@ -0,0 +1,219 @@ +/* + * Copyright (C) 2022 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 DataBatch.h + * @author: yujiechen + * @date 2022-10-17 + */ +#pragma once +#include "../Common.h" +#include +#include +#include +#include +#include + +namespace ppc::io +{ +using DataType = std::variant; + +enum DataSchema +{ + String, + Bytes, + Sint, + Uint, + Double, + Float, + Null, // the data-schema not setted +}; + +// the DataBatch +class DataBatch +{ +public: + using Ptr = std::shared_ptr; + using ConstPtr = std::shared_ptr; + DataBatch() : m_data(std::make_shared>()) {} + DataBatch(std::vector _data) : DataBatch() { *m_data = std::move(_data); } + ~DataBatch() = default; + + template + void setData(std::vector&& _data) + { + m_data->clear(); + for (auto& it : _data) + { + append(std::move(it)); + } + } + + template + void setData(std::vector const& _data) + { + m_data->clear(); + for (auto const& it : _data) + { + append(it); + } + } + + // append to different line + template + void append(T _data) + { + if constexpr (std::is_same::value || std::is_same::value) + { + m_capacityBytes += _data.size(); + } + else + { + m_capacityBytes += sizeof(_data); + } + m_data->emplace_back(_data); + } + + // append to the last line + // Note: only bcos::bytes, std::string can use this function + template + void appendToLine(T&& _data) + { + auto dataIndex = m_data->size() - 1; + auto& data = std::get((*m_data)[dataIndex]); + data.insert(data.end(), _data.begin(), _data.end()); + if constexpr (std::is_same::value || std::is_same::value) + { + m_capacityBytes += _data.size(); + } + } + + // Note: can't pass-in a invalid index + template + T const& get(uint64_t _index) const + { + return std::get(m_data->at(_index)); + } + + // Note: This introduces additional copy overhead + // convert to bytes + bcos::bytes getBytes(uint64_t _index) + { + if (m_dataSchema == DataSchema::Null) + { + BOOST_THROW_EXCEPTION(DataSchemaNotSetted() << bcos::errinfo_comment( + "Must set DataSchema before calling getBytes!")); + } + switch (m_dataSchema) + { + case DataSchema::String: + { + auto const& item = get(_index); + return bcos::bytes(item.begin(), item.end()); + } + case DataSchema::Bytes: + { + return get(_index); + } + case DataSchema::Uint: + { + auto const& value = get(_index); + auto result = boost::lexical_cast(value); + return bcos::bytes(result.begin(), result.end()); + } + case DataSchema::Sint: + { + auto const& value = get(_index); + auto result = boost::lexical_cast(value); + return bcos::bytes(result.begin(), result.end()); + } + case DataSchema::Double: + { + auto const& value = get(_index); + auto result = boost::lexical_cast(value); + return bcos::bytes(result.begin(), result.end()); + } + case DataSchema::Float: + { + auto const& value = get(_index); + auto result = boost::lexical_cast(value); + return bcos::bytes(result.begin(), result.end()); + } + default: + { + BOOST_THROW_EXCEPTION( + UnsupportedDataSchema() << bcos::errinfo_comment("unsupported data schema")); + } + } + } + + uint64_t size() const { return m_data->size(); } + + template + uint64_t elementSize(uint64_t _offset) const + { + if constexpr (std::is_same::value || std::is_same::value) + { + return std::get((*m_data)[_offset]).size(); + } + else + { + return sizeof(T); + } + } + uint64_t capacityBytes() const { return m_capacityBytes; } + + void resize(uint64_t _size) { m_data->resize(_size); } + + template + void resizeElement(uint64_t _index, uint64_t _size) + { + std::get((*m_data)[_index]).resize(_size); + } + + template + void set(uint64_t _offset, T&& _data) + { + if constexpr (std::is_same::value || std::is_same::value) + { + auto orgDataSize = elementSize(_offset); + m_capacityBytes -= orgDataSize; + m_capacityBytes += _data.size(); + } + (*m_data)[_offset].emplace(std::move(_data)); + } + + void setDataSchema(DataSchema _dataSchema) { m_dataSchema = _dataSchema; } + + DataSchema getDataSchema() const { return m_dataSchema; } + + + std::shared_ptr>& mutableData() { return m_data; } + + void release() + { + if (!m_data) + { + return; + } + m_data->clear(); + m_data.reset(); + } + +private: + std::shared_ptr> m_data; + uint64_t m_capacityBytes = 0; + DataSchema m_dataSchema = DataSchema::Null; +}; +} // namespace ppc::io \ No newline at end of file diff --git a/cpp/ppc-framework/io/DataResourceLoader.h b/cpp/ppc-framework/io/DataResourceLoader.h new file mode 100644 index 00000000..25a36492 --- /dev/null +++ b/cpp/ppc-framework/io/DataResourceLoader.h @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2022 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 DataResourceLoader.h + * @author: yujiechen + * @date 2022-11-4 + */ + +#pragma once +#include "../protocol/DataResource.h" +#include "../protocol/Protocol.h" +#include "../storage/FileStorage.h" +#include "LineReader.h" +#include "LineWriter.h" + +namespace ppc::io +{ +class DataResourceLoader +{ +public: + using Ptr = std::shared_ptr; + DataResourceLoader() = default; + virtual ~DataResourceLoader() = default; + + // load resource according to the dataResource + // Note: the FILE type data resource only support parsed by line + // the FILE type data resource can be loaded by segment + // the SQL type data resource support parsed by both line and column + // all the data returned from the SQL will be loaded into the memory + virtual LineReader::Ptr loadReader(ppc::protocol::DataResourceDesc::ConstPtr _dataResourceDesc, + ppc::io::DataSchema _schema = ppc::io::DataSchema::String, bool _parseByColumn = true, + ppc::storage::FileStorage::Ptr const& _storage = nullptr) = 0; + + // create a LineWriter to store data into the data-resource specified by outputDesc + // Note: only support file/hdfs now + virtual LineWriter::Ptr loadWriter(ppc::protocol::DataResourceDesc::ConstPtr _dataResourceDesc, + bool _truncate = false, ppc::storage::FileStorage::Ptr const& _storage = nullptr) = 0; + + virtual void checkResourceExists(ppc::protocol::DataResourceDesc::ConstPtr _desc, + ppc::storage::FileStorage::Ptr const& _storage = nullptr) = 0; + + virtual void deleteResource(ppc::protocol::DataResourceDesc::ConstPtr _desc, + ppc::storage::FileStorage::Ptr const& _storage = nullptr) = 0; + + virtual void renameResource(ppc::protocol::DataResourceDesc::ConstPtr _desc, + std::string const& _new_path, ppc::storage::FileStorage::Ptr const& _storage = nullptr) = 0; +}; +} // namespace ppc::io \ No newline at end of file diff --git a/cpp/ppc-framework/io/LineReader.h b/cpp/ppc-framework/io/LineReader.h new file mode 100644 index 00000000..5672490e --- /dev/null +++ b/cpp/ppc-framework/io/LineReader.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2022 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 Reader.h + * @author: yujiechen + * @date 2022-10-13 + */ +#pragma once +#include "../protocol/Protocol.h" +#include "DataBatch.h" + +namespace ppc::io +{ +class LineReader +{ +public: + using Ptr = std::shared_ptr; + LineReader() = default; + virtual ~LineReader() = default; + + // get the next _offset line data + virtual DataBatch::Ptr next(int64_t _size, DataSchema schema = DataSchema::String) = 0; + virtual bcos::bytes readBytes() = 0; + // the capacity of the file or memory-bytes + virtual uint64_t capacity() const = 0; + virtual uint64_t columnSize() const = 0; + virtual ppc::protocol::DataResourceType type() const = 0; + virtual void clean() {} + virtual bool readFinished() const = 0; +}; + +class LineReaderFactory +{ +public: + using Ptr = std::shared_ptr; + LineReaderFactory() = default; + virtual ~LineReaderFactory() = default; + + virtual LineReader::Ptr createLineReader(std::string const& _filePath, + uint64_t _mmapGranularity = 500 * 1024 * 1024, char _lineSpliter = '\n') = 0; +}; +} // namespace ppc::io \ No newline at end of file diff --git a/cpp/ppc-framework/io/LineWriter.h b/cpp/ppc-framework/io/LineWriter.h new file mode 100644 index 00000000..ba4d1907 --- /dev/null +++ b/cpp/ppc-framework/io/LineWriter.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2022 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 Writer.h + * @author: yujiechen + * @date 2022-10-17 + */ +#pragma once +#include "../protocol/Protocol.h" +#include "DataBatch.h" +namespace ppc::io +{ +class LineWriter +{ +public: + using Ptr = std::shared_ptr; + LineWriter() = default; + virtual ~LineWriter() = default; + + virtual ppc::protocol::DataResourceType type() const = 0; + + // write the data into the writer(Note: only support row-data) + virtual bool writeLine( + DataBatch::ConstPtr _data, DataSchema _schema, std::string _lineSplitter = "\n") = 0; + + virtual void writeBytes(bcos::bytesConstRef _data) = 0; + + // flush the data into the storage-backend + virtual void flush() = 0; + // close the storage-backend resource(Note: flush before close) + virtual void close() = 0; + + void setFileInfo(protocol::FileInfo::Ptr _fileInfo) { m_fileInfo = std::move(_fileInfo); } + protocol::FileInfo::Ptr const& fileInfo() const { return m_fileInfo; } + + virtual void upload() {} + + virtual void clean() {} + +private: + protocol::FileInfo::Ptr m_fileInfo; +}; +} // namespace ppc::io \ No newline at end of file diff --git a/cpp/ppc-framework/libwrapper/BigNum.h b/cpp/ppc-framework/libwrapper/BigNum.h new file mode 100644 index 00000000..4a43de70 --- /dev/null +++ b/cpp/ppc-framework/libwrapper/BigNum.h @@ -0,0 +1,479 @@ +/** + * Copyright (C) 2022 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 BigNum.h + * @author: yujiechen + * @date 2022-12-5 + */ +#pragma once +#include "Buffer.h" +#include "openssl/bn.h" +#include "openssl/err.h" +#include "ppc-framework/Common.h" +#include +#include +#include + +namespace ppc::crypto +{ +DERIVE_PPC_EXCEPTION(ConvertBytesToBigNumError); +DERIVE_PPC_EXCEPTION(CreateBNContextError); +DERIVE_PPC_EXCEPTION(BigNumSubError); +DERIVE_PPC_EXCEPTION(BigNumAddError); +DERIVE_PPC_EXCEPTION(BigNumMultiError); +DERIVE_PPC_EXCEPTION(GeneratePrimeError); +DERIVE_PPC_EXCEPTION(BigNumGCDError); +DERIVE_PPC_EXCEPTION(BigNumDivError); +DERIVE_PPC_EXCEPTION(BigNumModExpError); +DERIVE_PPC_EXCEPTION(ConvertIntToBigNumError); +DERIVE_PPC_EXCEPTION(BigNumRandError); +DERIVE_PPC_EXCEPTION(BigNumSetWordError); +DERIVE_PPC_EXCEPTION(BigNumGetBytesLenError); +DERIVE_PPC_EXCEPTION(NotEnoughBufferSize); + +struct BNCtxDeleter +{ +public: + void operator()(BN_CTX* _bnctx) { BN_CTX_free(_bnctx); } +}; +using BNCtxPtr = std::unique_ptr; + +struct BNDeleter +{ + void operator()(BIGNUM* bn) { BN_clear_free(bn); } +}; +using BNPtr = std::shared_ptr; + +inline BNCtxPtr createBNContext() +{ + BNCtxPtr bnContext(BN_CTX_new()); + if (!bnContext) + { + BOOST_THROW_EXCEPTION(CreateBNContextError()); + } + return bnContext; +} + +class BigNum +{ +public: + BigNum() : m_bn(BNPtr(BN_new(), BNDeleter())) {} + BigNum(bcos::bytesConstRef const& _data, bool _signed = true) : BigNum() + { + fromBytes(_data, _signed); + } + BigNum(bcos::bytesConstRef const& _data, BigNum const& p, bool _signed) : BigNum() + { + fromBytesModP(_data, p, _signed); + } + + explicit BigNum(int64_t const _value) : BigNum() + { + auto absV = _value > 0 ? _value : (-_value); + auto ret = BN_set_word(m_bn.get(), absV); + if (1 != ret) + { + BOOST_THROW_EXCEPTION( + ConvertIntToBigNumError() << bcos::errinfo_comment( + "BN_hex2bn error: " + std::string(ERR_error_string(ERR_get_error(), NULL)))); + } + BN_set_negative(m_bn.get(), (_value >= 0 ? 0 : 1)); + } + + BigNum(s1024 const& _value) : BigNum() + { + bcos::bytes encodedData(128, 0); + u1024 unsignedValue = u1024(_value); + bool negative = false; + if (_value < 0) + { + unsignedValue = u1024(-_value); + negative = true; + } + bcos::toBigEndian(unsignedValue, encodedData); + fromBigEndianBytes(encodedData.data(), encodedData.size(), negative); + } + + ~BigNum() = default; + + // swap _data with m_bn + void swap(BIGNUM* _data) { BN_swap(m_bn.get(), _data); } + void copy(BIGNUM* _data) { BN_copy(_data, m_bn.get()); } + int64_t getWord() const { return (int64_t)BN_get_word(m_bn.get()); } + + // convert bytes to BIGNUM + void fromBytes(bcos::bytesConstRef const& _data, bool _signed = true) + { + if (_data.size() == 0) + { + BOOST_THROW_EXCEPTION( + ConvertBytesToBigNumError() << bcos::errinfo_comment("Invalid BigNum data")); + } + if (_signed) + { + bool negative = false; + if (_data[0] == 0xff) + { + negative = true; + } + fromBigEndianBytes((bcos::byte*)(_data.data() + 1), _data.size() - 1, negative); + return; + } + fromBigEndianBytes((bcos::byte*)(_data.data()), _data.size(), false); + } + + void fromBigEndianBytes(bcos::byte* _start, int64_t _size, bool _negative) + { + if (!BN_bin2bn(_start, _size, m_bn.get())) + { + BOOST_THROW_EXCEPTION(ConvertBytesToBigNumError()); + } + if (_negative) + { + BN_set_negative(m_bn.get(), 1); + } + } + + void fromBytesModP(bcos::bytesConstRef const& _data, BigNum const& p, bool _signed = true) const + { + BigNum value(_data, _signed); + auto bnContext = createBNContext(); + if (BN_nnmod(m_bn.get(), value.bn().get(), p.bn().get(), bnContext.get()) != 1) + { + BOOST_THROW_EXCEPTION(ConvertBytesToBigNumError()); + } + } + + // convert BIGNUM to bytes + void toBytes(bcos::bytes& _output, bool _signed = true) const + { + auto bytesLen = BN_num_bytes(m_bn.get()); + if (bytesLen < 0) + { + BOOST_THROW_EXCEPTION( + BigNumGetBytesLenError() << bcos::errinfo_comment( + "BN_num_bytes error:" + std::string(ERR_error_string(ERR_get_error(), NULL)))); + } + auto bufferSize = _signed ? (bytesLen + 1) : bytesLen; + _output.resize(bufferSize); + OutputBuffer buffer{_output.data(), _output.size()}; + toOutputBuffer(&buffer, _signed); + } + + // convert to s1024 + s1024 toS1024() const + { + auto bytesLen = BN_num_bytes(m_bn.get()); + bcos::bytes bigEndianBytes(bytesLen, 0); + BN_bn2bin(m_bn.get(), (bcos::byte*)bigEndianBytes.data()); + auto result = bcos::fromBigEndian(bigEndianBytes); + if (BN_is_negative(m_bn.get())) + { + return s1024(0 - result); + } + return result; + } + + void toOutputBuffer(OutputBuffer* _output, bool _signed = true) const + { + auto bytesLen = BN_num_bytes(m_bn.get()); + if (bytesLen < 0) + { + BOOST_THROW_EXCEPTION( + BigNumGetBytesLenError() << bcos::errinfo_comment( + "BN_num_bytes error:" + std::string(ERR_error_string(ERR_get_error(), NULL)))); + } + auto bufferSize = _signed ? (bytesLen + 1) : bytesLen; + if (_output->len < (uint64_t)bufferSize) + { + BOOST_THROW_EXCEPTION( + NotEnoughBufferSize() << bcos::errinfo_comment( + "toOutputBuffer error for not enough buffer size, min buffer size is " + + std::to_string(bufferSize))); + } + _output->len = bufferSize; + if (_signed) + { + if (!BN_is_negative(m_bn.get())) + { + *(_output->data) = 0x00; + } + else + { + *(_output->data) = 0xff; + } + BN_bn2bin(m_bn.get(), (bcos::byte*)_output->data + 1); + return; + } + BN_bn2bin(m_bn.get(), (bcos::byte*)_output->data); + } + + // invert: (m_bn)^-1 mod _p + BigNum Invert(BigNum const& _p) const + { + auto bnContext = createBNContext(); + BigNum inversedNum; + BN_mod_inverse(inversedNum.bn().get(), m_bn.get(), _p.bn().get(), bnContext.get()); + return inversedNum; + } + + // m_bn + _value + BigNum add(BIGNUM const* _v) const + { + BigNum result; + add(result.bn().get(), _v); + return result; + } + + void add(BIGNUM* _result, BIGNUM const* _v) const + { + auto ret = BN_add(_result, m_bn.get(), _v); + if (1 != ret) + [[unlikely]] + { + BOOST_THROW_EXCEPTION( + BigNumAddError() << bcos::errinfo_comment( + "BN_add error:" + std::string(ERR_error_string(ERR_get_error(), NULL)))); + } + } + + // (m_bn + _v) mod _m + BigNum modAdd(BIGNUM const* _v, BIGNUM const* _m) const + { + BigNum result; + auto ret = BN_mod_add_quick(result.bn().get(), m_bn.get(), _v, _m); + if (1 != ret) + [[unlikely]] + { + BOOST_THROW_EXCEPTION(BigNumAddError() << bcos::errinfo_comment( + "BN_mod_add_quick error:" + + std::string(ERR_error_string(ERR_get_error(), NULL)))); + } + return result; + } + + // sub + BigNum sub(BIGNUM const* _subValue) const + { + BigNum result; + auto ret = BN_sub(result.bn().get(), m_bn.get(), _subValue); + if (1 != ret) + [[unlikely]] + { + BOOST_THROW_EXCEPTION( + BigNumSubError() << bcos::errinfo_comment( + "BN_sub error:" + std::string(ERR_error_string(ERR_get_error(), NULL)))); + } + return result; + } + + // multiply + void mul(BIGNUM* _result, BIGNUM const* _value, BN_CTX* _ctx) const + { + auto ret = BN_mul(_result, m_bn.get(), _value, _ctx); + if (1 != ret) + [[unlikely]] + { + BOOST_THROW_EXCEPTION( + BigNumMultiError() << bcos::errinfo_comment( + "BN_mul error: " + std::string(ERR_error_string(ERR_get_error(), NULL)))); + } + } + + // mud sub + void modSub(BIGNUM* _result, BIGNUM const* _value, BIGNUM const* _p, BN_CTX* _ctx) const + { + BigNum result; + auto ret = BN_mod_sub(_result, m_bn.get(), _value, _p, _ctx); + if (1 != ret) + [[unlikely]] + { + BOOST_THROW_EXCEPTION(BigNumAddError() << bcos::errinfo_comment( + "BN_mod_sub error:" + + std::string(ERR_error_string(ERR_get_error(), NULL)))); + } + } + + // mod multiply + void modMul(BIGNUM* _result, BIGNUM const* _value, BIGNUM const* _p, BN_CTX* _ctx) const + { + auto ret = BN_mod_mul(_result, m_bn.get(), _value, _p, _ctx); + if (1 != ret) + [[unlikely]] + { + BOOST_THROW_EXCEPTION(BigNumMultiError() << bcos::errinfo_comment( + "BN_mod_mul error: " + + std::string(ERR_error_string(ERR_get_error(), NULL)))); + } + } + + // generate prime bn + void generatePrime(unsigned int const _keyLength) + { + // Note: here set safe to 0 to improve the performance + // if set safe to 1, generate prime will cost multiple ms + auto ret = BN_generate_prime_ex(m_bn.get(), _keyLength, 0, NULL, NULL, NULL); + if (1 != ret) + [[unlikely]] + { + BOOST_THROW_EXCEPTION(GeneratePrimeError() << bcos::errinfo_comment( + "BN_generate_prime_ex error: " + + std::string(ERR_error_string(ERR_get_error(), NULL)))); + } + } + + // gcd(m_bn, _q) + void gcd(BIGNUM* _result, BIGNUM const* _q, BN_CTX* _bnctx) const + { + auto ret = BN_gcd(_result, m_bn.get(), _q, _bnctx); + if (1 != ret) + [[unlikely]] + { + BOOST_THROW_EXCEPTION( + BigNumGCDError() << bcos::errinfo_comment( + "BN_gcd error: " + std::string(ERR_error_string(ERR_get_error(), NULL)))); + } + } + + // m_bn/_q + void div(BIGNUM* _div, BIGNUM* _r, BIGNUM const* _q, BN_CTX* _bnctx) const + { + auto ret = BN_div(_div, _r, m_bn.get(), _q, _bnctx); + if (1 != ret) + [[unlikely]] + { + BOOST_THROW_EXCEPTION( + BigNumDivError() << bcos::errinfo_comment( + "BN_div error: " + std::string(ERR_error_string(ERR_get_error(), NULL)))); + } + } + + // (m_bn)^p mod m + BigNum modExp(const BIGNUM* _p, const BIGNUM* _m, BN_CTX* _ctx) const + { + BigNum result; + auto ret = BN_mod_exp(result.bn().get(), m_bn.get(), _p, _m, _ctx); + if (1 != ret) + [[unlikely]] + { + BOOST_THROW_EXCEPTION(BigNumModExpError() << bcos::errinfo_comment( + "BN_mod_exp error: " + + std::string(ERR_error_string(ERR_get_error(), NULL)))); + } + return result; + } + + // m_bn ^p + BigNum exp(const BIGNUM* _p, BN_CTX* _ctx) const + { + BigNum result; + auto ret = BN_exp(result.bn().get(), m_bn.get(), _p, _ctx); + if (1 != ret) + [[unlikely]] + { + BOOST_THROW_EXCEPTION( + BigNumModExpError() << bcos::errinfo_comment( + "BN_exp error: " + std::string(ERR_error_string(ERR_get_error(), NULL)))); + } + return result; + } + + int isBitSet(int n) { return BN_is_bit_set(m_bn.get(), n); } + + int cmp(const BIGNUM* b) const { return BN_cmp(m_bn.get(), b); } + + // set m_bn to _v + void setWord(BN_ULONG _v) + { + auto ret = BN_set_word(m_bn.get(), _v); + if (1 != ret) + [[unlikely]] + { + BOOST_THROW_EXCEPTION(BigNumSetWordError() << bcos::errinfo_comment( + "BN_set_word error: " + + std::string(ERR_error_string(ERR_get_error(), NULL)))); + } + } + + // divide m_bn by _v + void divConst(BN_ULONG w) + { + auto ret = BN_div_word(m_bn.get(), w); + if ((BN_ULONG)-1 == ret) + { + BOOST_THROW_EXCEPTION( + BigNumDivError() << bcos::errinfo_comment( + "BN_div_word error: " + std::string(ERR_error_string(ERR_get_error(), NULL)))); + } + } + + BigNum add(BigNum const& _num, BigNum const& _p) const + { + auto bnContext = createBNContext(); + BigNum addNum; + BN_mod_add(addNum.bn().get(), m_bn.get(), _num.bn().get(), _p.bn().get(), bnContext.get()); + return addNum; + } + + BigNum sub(BigNum const& _num, BigNum const& _p) const + { + auto bnContext = createBNContext(); + BigNum subNum; + BN_mod_sub(subNum.bn().get(), m_bn.get(), _num.bn().get(), _p.bn().get(), bnContext.get()); + return subNum; + } + + BigNum mul(BigNum const& _num, BigNum const& _p) const + { + auto bnContext = createBNContext(); + BigNum mulNum; + BN_mod_mul(mulNum.bn().get(), m_bn.get(), _num.bn().get(), _p.bn().get(), bnContext.get()); + return mulNum; + } + BNPtr const& bn() const { return m_bn; } + +private: + BNPtr m_bn; +}; + +// generate random in range of (0, _n) +inline void randRange(BIGNUM* _r, const BIGNUM* _n) +{ + auto ret = BN_rand_range(_r, _n); + if (1 != ret) + [[unlikely]] + { + BOOST_THROW_EXCEPTION(BigNumRandError() << bcos::errinfo_comment( + "BN_rand_range error: " + + std::string(ERR_error_string(ERR_get_error(), NULL)))); + } +} + +// generate random with bits size +inline BigNum generateRand(int _bits) +{ + BigNum r; + auto ret = BN_rand(r.bn().get(), _bits, BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY); + if (1 != ret) + [[unlikely]] + { + BOOST_THROW_EXCEPTION( + BigNumRandError() << bcos::errinfo_comment( + "BN_rand error: " + std::string(ERR_error_string(ERR_get_error(), NULL)))); + } + return r; +} + +} // namespace ppc::crypto \ No newline at end of file diff --git a/cpp/ppc-framework/libwrapper/Buffer.h b/cpp/ppc-framework/libwrapper/Buffer.h new file mode 100644 index 00000000..15d984cc --- /dev/null +++ b/cpp/ppc-framework/libwrapper/Buffer.h @@ -0,0 +1,44 @@ +/** + * 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 buffer.h + * @author: yujiechen + * @date 2023-08-11 + */ +#ifndef __BUFFER_H__ +#define __BUFFER_H__ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif +typedef struct +{ + const unsigned char* data; + uint64_t len; +} InputBuffer; + +typedef struct +{ + unsigned char* data; + uint64_t len; +} OutputBuffer; + +#ifdef __cplusplus +} +#endif +#endif diff --git a/cpp/ppc-framework/libwrapper/FloatingPointNumber.h b/cpp/ppc-framework/libwrapper/FloatingPointNumber.h new file mode 100644 index 00000000..6c286ab2 --- /dev/null +++ b/cpp/ppc-framework/libwrapper/FloatingPointNumber.h @@ -0,0 +1,41 @@ +/** + * Copyright (C) 2022 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 FloatingPointNumber.h + * @author: yujiechen + * @date 2023-08-16 + */ +#pragma once +#include "BigNum.h" +#include "openssl/bn.h" +#include +#include +#include +namespace ppc +{ +DERIVE_PPC_EXCEPTION(FloatingPointNumberError); +struct FloatingPointNumber +{ + ppc::crypto::BigNum value; + int16_t exponent; + + using Ptr = std::shared_ptr; + FloatingPointNumber() = default; + FloatingPointNumber(ppc::crypto::BigNum&& _value, int _exponent) + : value(std::move(_value)), exponent(_exponent) + {} + virtual ~FloatingPointNumber() = default; +}; +} // namespace ppc \ No newline at end of file diff --git a/cpp/ppc-framework/libwrapper/OreFloatingNumber.h b/cpp/ppc-framework/libwrapper/OreFloatingNumber.h new file mode 100644 index 00000000..14b03f01 --- /dev/null +++ b/cpp/ppc-framework/libwrapper/OreFloatingNumber.h @@ -0,0 +1,80 @@ +/** + * Copyright (C) 2022 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 OreFloatingNumber.h + * @author: shawnhe + * @date 2023-12-06 + */ +#pragma once + +#include "ppc-framework/Common.h" +#include "ppc-tools/src/common/TransTools.h" +#include +#include +#include +#include + +namespace ppc +{ +DERIVE_PPC_EXCEPTION(OreFloatingNumberError); + +struct OreFloatingNumber +{ + int64_t integerPart; + std::string decimalPart; + + OreFloatingNumber() = default; + virtual ~OreFloatingNumber() = default; + + OreFloatingNumber(const float50& _value) + { + if (_value > (std::numeric_limits::max)() / 2 - 1 || + _value <= (std::numeric_limits::min)() / 2 + 1) + { + BOOST_THROW_EXCEPTION( + OreFloatingNumberError() << bcos::errinfo_comment( + "plain is too large or too small, must be in range (-2^62 + 1, 2^62 - 1)")); + } + // set to positive + // Note: If there are too many decimal, there will be a problem of precision truncation. + float50 value = _value + (std::numeric_limits::max)() / 2; + std::string valueStr = value.str(); + auto dotPos = valueStr.find('.'); + int64_t intValue = std::stoll(valueStr.substr(0, dotPos)); + + integerPart = tools::toBigEndian(intValue); + + if (dotPos != std::string::npos) + { + decimalPart = valueStr.substr(dotPos + 1, valueStr.size()); + } + } + + float50 value() + { + std::string valueStr; + if (decimalPart.empty()) + { + valueStr = std::to_string(ppc::tools::fromBigEndian(integerPart)); + } + else + { + valueStr = std::to_string(ppc::tools::fromBigEndian(integerPart)) + "." + decimalPart; + } + + return float50(valueStr) - (std::numeric_limits::max)() / 2; + } +}; +} // namespace ppc diff --git a/cpp/ppc-framework/protocol/Constant.h b/cpp/ppc-framework/protocol/Constant.h new file mode 100644 index 00000000..0b441f4b --- /dev/null +++ b/cpp/ppc-framework/protocol/Constant.h @@ -0,0 +1,31 @@ +/** + * 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 Constant.h + * @author: yujiechen + * @date 2024-11-07 + */ + +#pragma once +#include +#include + +namespace ppc::protocol +{ +const static std::string PSI_SERVICE_TYPE = "PSI"; +const static std::string MPC_SERVICE_TYPE = "MPC"; +const static std::string SPDZ_SERVICE_TYPE = "SPDZ"; +const static size_t LARGE_MSG_THRESHOLD = 30 * 1024 * 1024; +} // namespace ppc::protocol diff --git a/cpp/ppc-framework/protocol/DataResource.h b/cpp/ppc-framework/protocol/DataResource.h new file mode 100644 index 00000000..b69a5f65 --- /dev/null +++ b/cpp/ppc-framework/protocol/DataResource.h @@ -0,0 +1,141 @@ +/* + * Copyright (C) 2022 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 DataResource.h + * @author: yujiechen + * @date 2022-10-13 + */ +#pragma once +#include "Protocol.h" +#include +#include +#include + +namespace ppc::protocol +{ +class DataResourceDesc +{ +public: + using Ptr = std::shared_ptr; + using ConstPtr = std::shared_ptr; + DataResourceDesc() = default; + virtual ~DataResourceDesc() = default; + + virtual uint16_t type() const { return m_type; } + virtual void setType(uint16_t _type) { m_type = _type; } + + virtual std::string const& path() const { return m_path; } + virtual void setPath(std::string const& _path) { m_path = _path; } + + virtual std::string const& accessCommand() const { return m_accessCommand; } + virtual void setAccessCommand(std::string const& _command) { m_accessCommand = _command; } + + virtual std::string const& fileID() const { return m_fileID; } + virtual void setFileID(std::string const& _fileID) { m_fileID = _fileID; } + + virtual std::string const& fileMd5() const { return m_fileMd5; } + virtual void setFileMd5(std::string const& _fileMd5) { m_fileMd5 = _fileMd5; } + + virtual std::string const& bizSeqNo() const { return m_bizSeqNo; } + virtual void setBizSeqNo(std::string const& _bizSeqNo) { m_bizSeqNo = _bizSeqNo; } + + virtual SQLConnectionOption::Ptr const& sqlConnectionOption() const + { + return m_sqlConnectionOption; + } + virtual void setSQLConnectionOption(SQLConnectionOption::Ptr const& _option) + { + m_sqlConnectionOption = _option; + } + + // the hdfs connection + ppc::protocol::FileStorageConnectionOption::Ptr const& fileStorageConnectionOption() const + { + return m_fileStorageConnectionOption; + } + virtual void setFileStorageConnectOption( + ppc::protocol::FileStorageConnectionOption::Ptr const& _fileStorageConnectionOption) + { + m_fileStorageConnectionOption = _fileStorageConnectionOption; + } + + +private: + std::string m_path; + std::string m_accessCommand; + std::string m_fileID; + std::string m_fileMd5; + std::string m_bizSeqNo; + + // the sql-connection-option + SQLConnectionOption::Ptr m_sqlConnectionOption; + // the file-storage-connection-option + FileStorageConnectionOption::Ptr m_fileStorageConnectionOption; + + uint16_t m_type; +}; + +class DataResource +{ +public: + using Ptr = std::shared_ptr; + using ConstPtr = std::shared_ptr; + using OriginData = std::vector>; + DataResource() = default; + DataResource(std::string const& _resourceID) : m_resourceID(_resourceID) {} + + virtual ~DataResource() = default; + virtual std::string const& resourceID() const { return m_resourceID; } + + virtual DataResourceDesc::ConstPtr desc() const { return m_desc; } + virtual DataResourceDesc::Ptr mutableDesc() const { return m_desc; } + virtual DataResourceDesc::ConstPtr outputDesc() const { return m_outputDesc; } + virtual DataResourceDesc::Ptr mutableOutputDesc() const { return m_outputDesc; } + virtual OriginData const& rawData() const { return m_rawData; } + + virtual void setResourceID(std::string const& _id) { m_resourceID = _id; } + virtual void setDesc(DataResourceDesc::Ptr _desc) { m_desc = _desc; } + virtual void setOutputDesc(DataResourceDesc::Ptr _desc) { m_outputDesc = _desc; } + virtual void setRawData(OriginData const& _data) { m_rawData = _data; } + +private: + std::string m_resourceID; + DataResourceDesc::Ptr m_desc; + DataResourceDesc::Ptr m_outputDesc; + OriginData m_rawData; +}; + +inline std::string printDataResourceInfo(DataResource::ConstPtr _dataResource) +{ + if (!_dataResource) + { + return "empty"; + } + std::ostringstream stringstream; + stringstream << LOG_KV("dataResource", _dataResource->resourceID()); + if (_dataResource->desc()) + { + stringstream << LOG_KV("dataType", _dataResource->desc()->type()) + << LOG_KV("command", _dataResource->desc()->accessCommand()) + << LOG_KV("path", _dataResource->desc()->path()); + } + if (_dataResource->outputDesc()) + { + stringstream << LOG_KV("outputType", _dataResource->outputDesc()->type()) + << LOG_KV("outputPath", _dataResource->outputDesc()->path()); + } + return stringstream.str(); +} +} // namespace ppc::protocol \ No newline at end of file diff --git a/cpp/ppc-framework/protocol/EndPoint.h b/cpp/ppc-framework/protocol/EndPoint.h new file mode 100644 index 00000000..293b6268 --- /dev/null +++ b/cpp/ppc-framework/protocol/EndPoint.h @@ -0,0 +1,60 @@ +/** + * 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 EndPoint.h + * @author: yujiechen + * @date 2024-08-22 + */ + +#pragma once +#include +#include +#include + +namespace ppc::protocol +{ +/** + * @brief the endpoint + * + */ +class EndPoint +{ +public: + EndPoint() = default; + EndPoint(std::string const& host, uint16_t port) : m_host(std::move(host)), m_port(port) {} + virtual ~EndPoint() = 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; } + void setListenIp(std::string const& listenIp) { m_listenIp = listenIp; } + + std::string entryPoint() const { return m_host + ":" + std::to_string(m_port); } + + std::string listenEndPoint() const { return m_listenIp + ":" + std::to_string(m_port); } + + std::string const& listenIp() const { return m_listenIp; } + +private: + // the listenIp + std::string m_listenIp = "0.0.0.0"; + // the host + std::string m_host; + // the port + uint16_t m_port; +}; +} // namespace ppc::protocol \ No newline at end of file diff --git a/cpp/ppc-framework/protocol/GlobalConfig.h b/cpp/ppc-framework/protocol/GlobalConfig.h new file mode 100644 index 00000000..e223a746 --- /dev/null +++ b/cpp/ppc-framework/protocol/GlobalConfig.h @@ -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 GlobalConfig.h + * @author: yujiechen + * @date 2023-1-3 + */ +#pragma once +#include "../Common.h" +#include "Protocol.h" +namespace ppc::protocol +{ +class GlobalConfig +{ +public: + static GlobalConfig& instance() + { + static GlobalConfig ins; + return ins; + } + GlobalConfig() + { + // set the supported-curves for ecdh-psi + auto key = calculateKey((uint8_t)TaskType::PSI, (uint8_t)TaskAlgorithmType::ECDH_PSI_2PC); +#ifdef ENABLE_CRYPTO_MB +#ifdef ENABLE_CPU_FEATURES + if (ppc::CPU_FEATURES.avx512ifma) + { + c_supportedCurves[key] = {(int)ECCCurve::IPP_X25519}; + } +#endif +#endif + c_supportedCurves[key].emplace_back((int)ECCCurve::P256); + c_supportedCurves[key].emplace_back((int)ECCCurve::ED25519); + c_supportedCurves[key].emplace_back((int)ECCCurve::SM2); + c_supportedCurves[key].emplace_back((int)ECCCurve::SECP256K1); + + // set the supported-hash algorithm for ecdh-psi + c_supportedHashList[key] = {(int)HashImplName::BLAKE2b, (int)HashImplName::SHA256, + (int)HashImplName::SM3, (int)HashImplName::SHA512}; + } + + std::vector supportedCurves(uint8_t _taskType, uint8_t _algorithmType) + { + auto key = calculateKey(_taskType, _algorithmType); + auto it = c_supportedCurves.find(key); + if (it != c_supportedCurves.end()) + { + return it->second; + } + return std::vector(); + } + + std::vector supportedHashList(uint8_t _taskType, uint8_t _algorithmType) + { + auto key = calculateKey(_taskType, _algorithmType); + auto it = c_supportedHashList.find(key); + if (it != c_supportedHashList.end()) + { + return it->second; + } + return std::vector(); + } + + void setSMCrypto(bool _smCrypto) { m_smCrypto = _smCrypto; } + bool smCrypto() const { return m_smCrypto; } + +private: + uint16_t calculateKey(uint8_t _taskType, uint8_t _algorithmType) + { + return (uint16_t)_taskType << 8 | (uint16_t)(_algorithmType); + } + +private: + std::map> c_supportedCurves; + std::map> c_supportedHashList; + bool m_smCrypto = false; +}; +} // namespace ppc::protocol +#define g_PPCConfig ppc::protocol::GlobalConfig::instance() \ No newline at end of file diff --git a/cpp/ppc-framework/protocol/GrpcConfig.h b/cpp/ppc-framework/protocol/GrpcConfig.h new file mode 100644 index 00000000..7a5b2f33 --- /dev/null +++ b/cpp/ppc-framework/protocol/GrpcConfig.h @@ -0,0 +1,166 @@ +/** + * 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 GrpcConfig.h + * @author: yujiechen + * @date 2024-09-02 + */ +#pragma once +#include "ppc-framework/Common.h" +#include "ppc-framework/protocol/EndPoint.h" +#include +#include +#include + +namespace ppc::protocol +{ +class GrpcConfig +{ +public: + using Ptr = std::shared_ptr; + GrpcConfig() = default; + virtual ~GrpcConfig() = default; + + std::string const& loadBalancePolicy() const { return m_loadBalancePolicy; } + void setLoadBalancePolicy(std::string const& loadBalancePolicy) + { + m_loadBalancePolicy = loadBalancePolicy; + } + + bool enableHealthCheck() const { return m_enableHealthCheck; } + void setEnableHealthCheck(bool enableHealthCheck) { m_enableHealthCheck = enableHealthCheck; } + void setEnableDnslookup(bool enableDnslookup) { m_enableDnslookup = enableDnslookup; } + + bool enableDnslookup() const { return m_enableDnslookup; } + + uint64_t maxSendMessageSize() const { return m_maxSendMessageSize; } + uint64_t maxReceivedMessageSize() const { return m_maxReceivedMessageSize; } + + void setMaxSendMessageSize(uint64_t maxSendMessageSize) + { + if (maxSendMessageSize > c_maxMsgSize) + { + BOOST_THROW_EXCEPTION( + WeDPRException() << bcos::errinfo_comment( + "The MaxSendMessageSize limit is " + std::to_string(c_maxMsgSize))); + } + m_maxSendMessageSize = maxSendMessageSize; + } + void setMaxReceivedMessageSize(uint64_t maxReceivedMessageSize) + { + if (maxReceivedMessageSize > c_maxMsgSize) + { + BOOST_THROW_EXCEPTION( + WeDPRException() << bcos::errinfo_comment( + "The MaxReceivedMessageSize limit is " + std::to_string(c_maxMsgSize))); + } + m_maxReceivedMessageSize = maxReceivedMessageSize; + } + + /* + typedef enum { + GRPC_COMPRESS_NONE = 0, + GRPC_COMPRESS_DEFLATE, + GRPC_COMPRESS_GZIP, + GRPC_COMPRESS_ALGORITHMS_COUNT + } grpc_compression_algorithm; + */ + int compressAlgorithm() const { return m_compressAlgorithm; } + + void setCompressAlgorithm(int compressAlgorithm) + { + if (compressAlgorithm < 0 || compressAlgorithm > 2) + { + BOOST_THROW_EXCEPTION(WeDPRException() << bcos::errinfo_comment( + "Invalid compress algorithm, must between 0-3")); + } + m_compressAlgorithm = compressAlgorithm; + } + + uint64_t maxMsgSize() const { return m_maxMsgSize; } + void setMaxMsgSize(uint64_t maxMsgSize) + { + if (maxMsgSize > c_maxMsgSize) + { + BOOST_THROW_EXCEPTION(WeDPRException() << bcos::errinfo_comment( + "The maxMsgSize limit is " + std::to_string(c_maxMsgSize))); + } + m_maxMsgSize = maxMsgSize; + } + +protected: + bool m_enableHealthCheck = true; + std::string m_loadBalancePolicy = "round_robin"; + bool m_enableDnslookup = false; + + // Note: grpc use int to set the maxMsgSize + uint64_t const c_maxMsgSize = INT_MAX; + + // the max send message size in bytes + uint64_t m_maxSendMessageSize = c_maxMsgSize; + // the max received message size in bytes + uint64_t m_maxReceivedMessageSize = c_maxMsgSize; + // the max msg size + uint64_t m_maxMsgSize = c_maxMsgSize; + int m_compressAlgorithm = 0; +}; + +class GrpcServerConfig +{ +public: + using Ptr = std::shared_ptr; + GrpcServerConfig() { m_grpcConfig = std::make_shared(); } + GrpcServerConfig(EndPoint endPoint, bool enableHealthCheck) : GrpcServerConfig() + { + m_endPoint = std::move(endPoint); + m_enableHealthCheck = enableHealthCheck; + } + virtual ~GrpcServerConfig() = default; + + std::string listenEndPoint() const { return m_endPoint.listenEndPoint(); } + + void setEndPoint(EndPoint endPoint) { m_endPoint = endPoint; } + void setEnableHealthCheck(bool enableHealthCheck) { m_enableHealthCheck = enableHealthCheck; } + + EndPoint const& endPoint() const { return m_endPoint; } + EndPoint& mutableEndPoint() { return m_endPoint; } + bool enableHealthCheck() const { return m_enableHealthCheck; } + + GrpcConfig::Ptr const& grpcConfig() const { return m_grpcConfig; } + +protected: + ppc::protocol::EndPoint m_endPoint; + bool m_enableHealthCheck = true; + // the grpc config + GrpcConfig::Ptr m_grpcConfig; +}; + + +inline std::string printGrpcConfig(ppc::protocol::GrpcConfig::Ptr const& grpcConfig) +{ + if (!grpcConfig) + { + return "nullptr"; + } + std::ostringstream stringstream; + stringstream << LOG_KV("loadBalancePolicy", grpcConfig->loadBalancePolicy()) + << LOG_KV("enableHealthCheck", grpcConfig->enableHealthCheck()) + << LOG_KV("enableDnslookup", grpcConfig->enableDnslookup()) + << LOG_KV("maxSendMessageSize", grpcConfig->maxSendMessageSize()) + << LOG_KV("maxReceivedMessageSize", grpcConfig->maxReceivedMessageSize()) + << LOG_KV("compressAlgorithm", grpcConfig->compressAlgorithm()); + return stringstream.str(); +} +} // namespace ppc::protocol \ No newline at end of file diff --git a/cpp/ppc-framework/protocol/Handler.h b/cpp/ppc-framework/protocol/Handler.h new file mode 100644 index 00000000..aecf774b --- /dev/null +++ b/cpp/ppc-framework/protocol/Handler.h @@ -0,0 +1,41 @@ +/** + * 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 EndPoint.h + * @author: yujiechen + * @date 2024-08-22 + */ + +#pragma once +#include +#include +#include + +namespace ppc::protocol +{ +struct HealthCheckHandler +{ + using Ptr = std::shared_ptr; + HealthCheckHandler(std::string const& _serviceName) : serviceName(_serviceName) {} + + std::string serviceName; + // handler used to check the health + std::function checkHealthHandler; + // handler called when the service un-health + std::function onUnHealthHandler; + // remove the handler when the service un-health + bool removeHandlerOnUnhealth = true; +}; +} // namespace ppc::protocol \ No newline at end of file diff --git a/cpp/ppc-framework/protocol/INodeInfo.h b/cpp/ppc-framework/protocol/INodeInfo.h new file mode 100644 index 00000000..ae1b61f7 --- /dev/null +++ b/cpp/ppc-framework/protocol/INodeInfo.h @@ -0,0 +1,101 @@ +/** + * 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/Helper.h" +#include +#include +#include +#include +#include +#include + +namespace ppc::front +{ +class IFrontClient; +} +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; + virtual void setNodeID(bcos::bytesConstRef nodeID) = 0; + virtual void setEndPoint(std::string const& endPoint) = 0; + + // components + virtual void setComponents(std::set const& components) = 0; + virtual bool addComponent(std::string const& component) = 0; + virtual bool eraseComponent(std::string const& component) = 0; + virtual bool componentExist(std::string const& component) const = 0; + virtual std::set const& components() const = 0; + virtual std::vector copiedComponents() const = 0; + + virtual void encode(bcos::bytes& data) const = 0; + virtual void decode(bcos::bytesConstRef data) = 0; + + virtual void setFront(std::shared_ptr&& front) = 0; + virtual std::shared_ptr getFront() const = 0; + + virtual bool equal(INodeInfo::Ptr const& info) + { + return (nodeID().toBytes() == info->nodeID().toBytes()) && (endPoint() == info->endPoint()); + } + + virtual std::string meta() const = 0; + // the node meta information + virtual void setMeta(std::string const& meta) = 0; + virtual void toJson(Json::Value& jsonObject) const = 0; +}; +class INodeInfoFactory +{ +public: + using Ptr = std::shared_ptr; + INodeInfoFactory() = default; + virtual ~INodeInfoFactory() = default; + + virtual INodeInfo::Ptr build() = 0; + virtual INodeInfo::Ptr build(bcos::bytesConstRef nodeID, std::string const& endPoint) = 0; + virtual INodeInfo::Ptr build(bcos::bytesConstRef data) = 0; +}; + +inline std::string printNodeInfo(INodeInfo::Ptr const& nodeInfo) +{ + if (!nodeInfo) + { + return "nullptr"; + } + std::ostringstream stringstream; + stringstream << LOG_KV("endPoint", nodeInfo->endPoint()) + << LOG_KV("nodeID", printNodeID(nodeInfo->nodeID())); + std::string components = ""; + for (auto const& it : nodeInfo->copiedComponents()) + { + components = components + it + ","; + } + stringstream << LOG_KV("components", components) << LOG_KV("meta", nodeInfo->meta()); + return stringstream.str(); +} +} // namespace ppc::protocol \ No newline at end of file diff --git a/cpp/ppc-framework/protocol/Krb5AuthConfig.h b/cpp/ppc-framework/protocol/Krb5AuthConfig.h new file mode 100644 index 00000000..a7ed09b3 --- /dev/null +++ b/cpp/ppc-framework/protocol/Krb5AuthConfig.h @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2022 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 Krb5AuthConfig.h + * @author: yujiechen + * @date 2024-12-2 + */ +#pragma once +#include "ppc-framework/Common.h" +#include +#include +#include + +namespace ppc::protocol +{ +struct Krb5AuthConfig +{ + using Ptr = std::shared_ptr; + std::string principal; + std::string password; + std::string ccachePath; + std::string authConfigFilePath = "./conf/krb5.conf"; + void check() const + { + if (principal.size() == 0) + { + BOOST_THROW_EXCEPTION(WeDPRException() << bcos::errinfo_comment( + "Invalid krb5 auth config: Must set the principal!")); + } + if (password.size() == 0) + { + BOOST_THROW_EXCEPTION(WeDPRException() << bcos::errinfo_comment( + "Invalid krb5 auth config: Must set the password!")); + } + if (ccachePath.size() == 0) + { + BOOST_THROW_EXCEPTION(WeDPRException() << bcos::errinfo_comment( + "Invalid krb5 auth config: Must set the ccachePath!")); + } + if (authConfigFilePath.size() == 0) + { + BOOST_THROW_EXCEPTION( + WeDPRException() << bcos::errinfo_comment( + "Invalid krb5 auth config: Must set the authConfigFilePath!")); + } + } + + inline std::string desc() const + { + std::stringstream oss; + oss << LOG_KV("principal", principal) << LOG_KV("ccachePath", ccachePath) + << LOG_KV("authConfigFilePath", authConfigFilePath); + return oss.str(); + } +}; +} // 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 new file mode 100644 index 00000000..205f1ce3 --- /dev/null +++ b/cpp/ppc-framework/protocol/Message.h @@ -0,0 +1,352 @@ +/** + * 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 "MessagePayload.h" +#include "RouteType.h" +#include "ppc-framework/Helper.h" +#include "ppc-framework/libwrapper/Buffer.h" +#include +#include +#include +#include +#include +#include +namespace ppc::protocol +{ +class MessageOptionalHeader +{ +public: + using Ptr = std::shared_ptr; + MessageOptionalHeader() = default; + virtual ~MessageOptionalHeader() = default; + + virtual void encode(bcos::bytes& buffer) const = 0; + virtual int64_t decode(bcos::bytesConstRef data, uint64_t const _offset) = 0; + + // the 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; } + /// for swig-wrapper(pass the binary data) + OutputBuffer srcNodeBuffer() const + { + // Note: this will be copied to java through jni + return OutputBuffer{(unsigned char*)m_srcNode.data(), m_srcNode.size()}; + } + + virtual void setSrcNode(bcos::bytes const& srcNode) { m_srcNode = srcNode; } + + // !!! Note: the first paramater type should not been changed, for it's used for pass-in java + // byte[] into c bytes + virtual void setSrcNodeBuffer(char* data, uint64_t length) + { + m_srcNode.assign(data, data + length); + } + + // the target nodeID that should receive the message + virtual bcos::bytes const& dstNode() const { return m_dstNode; } + + // for swig-wrapper(pass the binary to java) + OutputBuffer dstNodeBuffer() const + { + // Note: this will be copied to java through jni + return OutputBuffer{(unsigned char*)m_dstNode.data(), m_dstNode.size()}; + } + virtual void setDstNode(bcos::bytes const& dstNode) { m_dstNode = dstNode; } + // !!! Note: the first paramater type(char*) should not been changed, for it's used for pass-in + // java byte[] into c bytes + // Note: the python not support function override + virtual void setDstNodeBuffer(char* data, uint64_t length) + { + m_dstNode.assign(data, data + length); + } + + // the target agency that need receive the message + 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; } + + virtual std::string srcInst() const { return m_srcInst; } + virtual void setSrcInst(std::string const& srcInst) { m_srcInst = srcInst; } + +protected: + std::string m_topic; + // the componentType + std::string m_componentType; + // the source nodeID that send the message + bcos::bytes m_srcNode; + // the source agency + std::string m_srcInst; + // the target nodeID that should receive the message + bcos::bytes m_dstNode; + // the target agency that need receive the message + std::string m_dstInst; +}; + +class MessageHeader +{ +public: + using Ptr = std::shared_ptr; + MessageHeader() = default; + virtual ~MessageHeader() = default; + + 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 std::string const& srcGwNode() const { return m_srcGwNode; } + virtual void setSrcGwNode(std::string const& srcGwNode) { m_srcGwNode = srcGwNode; } + + // the 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; } + 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); + } + + virtual uint16_t length() const { return m_length; } + + virtual bool isRespPacket() const = 0; + virtual void setRespPacket() = 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); } + + virtual uint16_t routeType() const = 0; + virtual void setRouteType(ppc::protocol::RouteType type) = 0; + virtual bool hasOptionalField() const = 0; + +protected: + // Note: must init here to 0, otherwise, it will be unexpected value in some other platform + // the msg version, used to support compatibility + uint8_t m_version = 0; + // the traceID + std::string m_traceID; + // the srcGwNode + std::string m_srcGwNode; + // the dstGwNode + std::string m_dstGwNode; + // the packetType + uint16_t m_packetType = 0; + // the ttl + int16_t m_ttl = 0; + // the ext(contains the router policy and response flag) + uint16_t m_ext = 0; + //// the optional field(used to route between components and nodes) + MessageOptionalHeader::Ptr m_optionalField; + uint16_t mutable m_length; +}; + +class Message +{ +public: + using Ptr = std::shared_ptr; + Message() = default; + virtual ~Message() {} + + virtual MessageHeader::Ptr header() const { return m_header; } + virtual void setHeader(MessageHeader::Ptr header) { m_header = std::move(header); } + /// the overloaed implementation === + uint16_t version() const { return m_header->version(); } + void setVersion(uint16_t version) { m_header->setVersion(version); } + uint16_t packetType() const { return m_header->packetType(); } + void setPacketType(uint16_t packetType) { m_header->setPacketType(packetType); } + std::string const& seq() const { return m_header->traceID(); } + void setSeq(std::string traceID) { m_header->setTraceID(traceID); } + uint16_t ext() const { return m_header->ext(); } + void setExt(uint16_t ext) { m_header->setExt(ext); } + + bool isRespPacket() const { return m_header->isRespPacket(); } + void setRespPacket() { m_header->setRespPacket(); } + void setPayload(std::shared_ptr _payload) + { + m_payload = std::move(_payload); + if (m_payload) + { + m_payloadLen = m_payload->size(); + } + } + // for swig wrapper + OutputBuffer payloadBuffer() const + { + if (!m_payload) + { + return OutputBuffer{nullptr, 0}; + } + return OutputBuffer{(unsigned char*)m_payload->data(), m_payload->size()}; + } + + void setFrontMessage(MessagePayload::Ptr frontMessage, bool releasePayload = false) + { + m_frontMessage = std::move(frontMessage); + if (!releasePayload) + { + return; + } + if (m_payload) + { + m_payload->clear(); + bcos::bytes().swap(*m_payload); + } + } + + MessagePayload::Ptr const& frontMessage() const { return m_frontMessage; } + + // Note: swig wrapper require define all methods + virtual bool encode(bcos::bytes& _buffer) = 0; + virtual int64_t decode(bcos::bytesConstRef _buffer) = 0; + + virtual uint32_t length() const { return m_header->length() + m_payloadLen; } + + virtual std::shared_ptr payload() const { return m_payload; } + + void releasePayload() + { + if (m_payload) + { + m_payload->clear(); + bcos::bytes().swap(*m_payload); + } + if (m_frontMessage) + { + m_frontMessage->releasePayload(); + } + } + +protected: + MessageHeader::Ptr m_header; + // Note: allocate here in case of wsService nullptr access caused coredump + std::shared_ptr m_payload = std::make_shared(); + uint64_t m_payloadLen = 0; + ; + + MessagePayload::Ptr m_frontMessage = nullptr; +}; + +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; + virtual MessageOptionalHeader::Ptr build(MessageOptionalHeader::Ptr const& optionalHeader) = 0; +}; + +class MessageBuilder +{ +public: + using Ptr = std::shared_ptr; + MessageBuilder() = default; + virtual ~MessageBuilder() = default; + + virtual Message::Ptr build() = 0; + virtual Message::Ptr build(bcos::bytesConstRef buffer) = 0; + virtual Message::Ptr build(ppc::protocol::RouteType routeType, + ppc::protocol::MessageOptionalHeader::Ptr const& routeInfo, bcos::bytes&& payload) = 0; +}; + +class MessageOptionalHeaderBuilder +{ +public: + using Ptr = std::shared_ptr; + MessageOptionalHeaderBuilder() = default; + virtual ~MessageOptionalHeaderBuilder() = default; + + virtual MessageOptionalHeader::Ptr build(MessageOptionalHeader::Ptr const& optionalHeader) = 0; + virtual MessageOptionalHeader::Ptr build() = 0; +}; + +inline std::string printOptionalField(MessageOptionalHeader::Ptr optionalHeader) +{ + if (!optionalHeader) + { + return "nullptr"; + } + std::ostringstream stringstream; + stringstream << LOG_KV("topic", optionalHeader->topic()) + << LOG_KV("componentType", optionalHeader->componentType()) + << LOG_KV("srcNode", printNodeID(optionalHeader->srcNode())) + << LOG_KV("dstNode", printNodeID(optionalHeader->dstNode())) + << LOG_KV("srcInst", printNodeID(optionalHeader->srcInst())) + << LOG_KV("dstInst", printNodeID(optionalHeader->dstInst())); + return stringstream.str(); +} + +inline std::string printMessage(Message::Ptr const& _msg) +{ + if (!_msg) + { + return "nullptr"; + } + std::ostringstream stringstream; + stringstream << LOG_KV("from", _msg->header()->srcP2PNodeIDView()) + << LOG_KV("to", _msg->header()->dstP2PNodeIDView()) + << LOG_KV("routeType", (ppc::protocol::RouteType)_msg->header()->routeType()) + << 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()); + if (_msg->header()->hasOptionalField()) + { + stringstream << printOptionalField(_msg->header()->optionalField()); + } + return stringstream.str(); +} +// function to send response +using SendResponseFunction = std::function&& payload)>; +using ReceiveMsgFunc = std::function; +using MessageCallback = std::function; +using MessageDispatcherCallback = 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 new file mode 100644 index 00000000..68ba0739 --- /dev/null +++ b/cpp/ppc-framework/protocol/MessagePayload.h @@ -0,0 +1,110 @@ +/** + * 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 "ppc-framework/libwrapper/Buffer.h" +#include +#include + +namespace ppc::protocol +{ +enum class FrontMsgExtFlag : uint16_t +{ + Response = 0x1 +}; +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; } + // data + virtual bcos::bytes const& data() const { return m_data; } + // for swig wrapper here + virtual OutputBuffer dataBuffer() const + { + return OutputBuffer{(unsigned char*)m_dataPtr.data(), m_dataPtr.size()}; + } + virtual void setData(bcos::bytes&& data) + { + m_data = std::move(data); + m_dataPtr = bcos::bytesConstRef((bcos::byte*)m_data.data(), m_data.size()); + } + virtual void setData(bcos::bytes const& data) + { + m_data = data; + m_dataPtr = bcos::bytesConstRef((bcos::byte*)m_data.data(), m_data.size()); + } + virtual void setDataPtr(bcos::bytesConstRef dataPtr) { m_dataPtr = dataPtr; } + virtual bcos::bytesConstRef const& dataPtr() const { return m_dataPtr; } + // 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; } + + // the traceID + virtual std::string const& traceID() const { return m_traceID; } + virtual void setTraceID(std::string const& traceID) { m_traceID = traceID; } + + virtual uint16_t ext() const { return m_ext; } + virtual void setExt(uint16_t ext) { m_ext = ext; } + + virtual void setRespPacket() { m_ext |= (uint16_t)FrontMsgExtFlag::Response; } + + virtual bool isRespPacket() { return m_ext &= (uint16_t)FrontMsgExtFlag::Response; } + + void releasePayload() + { + m_data.clear(); + bcos::bytes().swap(m_data); + } + +protected: + // the front payload version, used to support compatibility + // Note: must init here to 0, otherwise, it will be unexpected value in some other platform + uint8_t m_version = 0; + // the seq + uint16_t m_seq = 0; + // the traceID + std::string m_traceID; + bcos::bytes m_data; + // used to decrease the copy-overhead + bcos::bytesConstRef m_dataPtr; + uint16_t m_ext = 0; + 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-framework/protocol/P2PMessage.h b/cpp/ppc-framework/protocol/P2PMessage.h new file mode 100644 index 00000000..735668d6 --- /dev/null +++ b/cpp/ppc-framework/protocol/P2PMessage.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 Message.h + * @author: yujiechen + * @date 2024-08-22 + */ +#pragma once +#include "Message.h" +#include +namespace ppc::protocol +{ +// the wrapper for override bcos::boostssl::MessageFace while use implementation for Message +class P2PMessage : virtual public bcos::boostssl::MessageFace +{ +public: + using Ptr = std::shared_ptr; + P2PMessage(Message::Ptr msg) : m_msg(std::move(msg)) {} + ~P2PMessage() override {} + + /// the overloaed implementation === + uint16_t version() const override { return m_msg->version(); } + void setVersion(uint16_t version) override { m_msg->setVersion(version); } + uint16_t packetType() const override { return m_msg->packetType(); } + void setPacketType(uint16_t packetType) override { m_msg->setPacketType(packetType); } + std::string const& seq() const override { return m_msg->seq(); } + void setSeq(std::string seq) override { m_msg->setSeq(seq); } + uint16_t ext() const override { return m_msg->ext(); } + void setExt(uint16_t ext) override { m_msg->setExt(ext); } + std::shared_ptr payload() const override { return m_msg->payload(); } + void setPayload(std::shared_ptr payload) override + { + m_msg->setPayload(std::move(payload)); + } + + bool encode(bcos::bytes& _buffer) override { return m_msg->encode(_buffer); } + + int64_t decode(bcos::bytesConstRef _buffer) override { return m_msg->decode(_buffer); } + + bool isRespPacket() const override { return m_msg->isRespPacket(); } + void setRespPacket() override { m_msg->setRespPacket(); } + uint32_t length() const override { return m_msg->length(); } + + // encode and return the {header, payload} + virtual bool encode(bcos::boostssl::EncodedMsg& _encodedMsg) = 0; + + Message::Ptr const& msg() { return m_msg; } + MessageHeader::Ptr header() const { return m_msg->header(); } + +protected: + Message::Ptr m_msg; +}; + + +class P2PMessageBuilder : virtual public bcos::boostssl::MessageFaceFactory +{ +public: + using Ptr = std::shared_ptr; + P2PMessageBuilder() = default; + ~P2PMessageBuilder() override = default; + + virtual P2PMessage::Ptr build() = 0; + virtual P2PMessage::Ptr build(ppc::protocol::RouteType routeType, + ppc::protocol::MessageOptionalHeader::Ptr const& routeInfo, bcos::bytes&& payload) = 0; +}; +inline std::string printWsMessage(bcos::boostssl::MessageFace::Ptr const& _msg) +{ + if (!_msg) + { + return "nullptr"; + } + std::ostringstream stringstream; + stringstream << LOG_KV("rsp", _msg->isRespPacket()) << LOG_KV("traceID", _msg->seq()) + << LOG_KV("packetType", _msg->packetType()) << LOG_KV("length", _msg->length()) + << LOG_KV("ext", _msg->ext()); + return stringstream.str(); +} +inline std::string printP2PMessage(P2PMessage::Ptr const& _msg) +{ + if (_msg->msg() == nullptr) + { + return ""; + } + return printMessage(_msg->msg()); +} +} // namespace ppc::protocol diff --git a/cpp/ppc-framework/protocol/PPCMessageFace.h b/cpp/ppc-framework/protocol/PPCMessageFace.h new file mode 100644 index 00000000..263750da --- /dev/null +++ b/cpp/ppc-framework/protocol/PPCMessageFace.h @@ -0,0 +1,119 @@ +/** + * Copyright (C) 2022 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. + * + * @brief ppc network message interface + * @file PPCMessageFace.h + * @author: shawnhe + * @date 2022-10-19 + */ + +#pragma once +#include "Protocol.h" +#include "ppc-framework/protocol/Message.h" +#include +#include +#include +#include +#include +#include + +namespace ppc +{ +namespace front +{ +class PPCMessageFace +{ +public: + using Ptr = std::shared_ptr; + +public: + virtual ~PPCMessageFace() {} + + virtual uint8_t version() const = 0; + virtual void setVersion(uint8_t) = 0; + virtual uint8_t taskType() const = 0; + virtual void setTaskType(uint8_t) = 0; + virtual uint8_t algorithmType() const = 0; + virtual void setAlgorithmType(uint8_t) = 0; + virtual uint8_t messageType() const = 0; + virtual void setMessageType(uint8_t) = 0; + virtual uint32_t seq() const = 0; + virtual void setSeq(uint32_t) = 0; + virtual std::string const& taskID() const = 0; + virtual void setTaskID(std::string const&) = 0; + virtual std::string const& sender() const = 0; + virtual bcos::bytes const& senderNode() const = 0; + virtual void setSender(std::string const&) = 0; + virtual void setSenderNode(bcos::bytes const&) = 0; + + virtual std::shared_ptr data() const = 0; + virtual void setData(std::shared_ptr) = 0; + virtual std::map header() = 0; + virtual void setHeader(std::map) = 0; + virtual void encode(bcos::bytes& _buffer) = 0; + virtual int64_t decode(bcos::bytesPointer _buffer) = 0; + virtual int64_t decode(bcos::bytesConstRef _buffer) = 0; + + virtual uint32_t length() const = 0; + + virtual std::string uuid() const = 0; + virtual void setUuid(std::string const& _uuid) = 0; + + // determine the message is response or not + virtual bool response() const = 0; + // set the message to be response + virtual void setResponse() = 0; + + virtual void releasePayload() {} +}; + +class PPCMessageFaceFactory +{ +public: + using Ptr = std::shared_ptr; + +public: + virtual ~PPCMessageFaceFactory() {} + virtual PPCMessageFace::Ptr buildPPCMessage() = 0; + virtual PPCMessageFace::Ptr decodePPCMessage(ppc::protocol::Message::Ptr msg) = 0; + virtual ppc::protocol::Message::Ptr buildMessage( + ppc::protocol::MessageBuilder::Ptr const& msgBuilder, + ppc::protocol::MessagePayloadBuilder::Ptr const& msgPayloadBuilder, + PPCMessageFace::Ptr const& ppcMessage) = 0; + + virtual ppc::protocol::MessagePayload::Ptr buildMessage( + ppc::protocol::MessagePayloadBuilder::Ptr const& msgPayloadBuilder, + PPCMessageFace::Ptr const& ppcMessage) = 0; + + virtual PPCMessageFace::Ptr buildPPCMessage(bcos::bytesConstRef _data) = 0; + virtual PPCMessageFace::Ptr buildPPCMessage(bcos::bytesPointer _buffer) = 0; + virtual PPCMessageFace::Ptr buildPPCMessage(uint8_t _taskType, uint8_t _algorithmType, + std::string const& _taskID, bcos::bytesPointer _data) = 0; +}; + +inline std::string printPPCMsg(PPCMessageFace::Ptr _msg) +{ + std::ostringstream stringstream; + stringstream << LOG_KV("sender", _msg->sender()) + << LOG_KV("taskType", (ppc::protocol::TaskType)(_msg->taskType())) + << LOG_KV("algorithm", int(_msg->algorithmType())) + << LOG_KV("messageType", int(_msg->messageType())) + << LOG_KV("task", _msg->taskID()) << LOG_KV("seq", _msg->seq()) + << LOG_KV("uuid", _msg->uuid()) << LOG_KV("response", _msg->response()) + << LOG_KV("size", _msg->data()->size()); + return stringstream.str(); +} +} // namespace front +} // namespace ppc diff --git a/cpp/ppc-framework/protocol/PartyResource.h b/cpp/ppc-framework/protocol/PartyResource.h new file mode 100644 index 00000000..0c0e66f7 --- /dev/null +++ b/cpp/ppc-framework/protocol/PartyResource.h @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2022 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 PartyResource.h + * @author: yujiechen + * @date 2022-10-13 + */ +#pragma once +#include "DataResource.h" +#include "Protocol.h" +#include +#include +#include +#include + +namespace ppc::protocol +{ +class PartyResource +{ +public: + using Ptr = std::shared_ptr; + using ConstPtr = std::shared_ptr; + PartyResource() = default; + PartyResource(std::string const& _id, uint16_t _partyIndex) + : m_id(_id), m_partyIndex(_partyIndex) + {} + + virtual ~PartyResource() = default; + + // the party index that represents the role in the task + virtual uint16_t partyIndex() const { return m_partyIndex; } + // the party id + virtual std::string const& id() const { return m_id; } + virtual std::string const& desc() const { return m_desc; } + virtual DataResource::ConstPtr dataResource() const { return m_dataResource; } + virtual DataResource::Ptr mutableDataResource() const { return m_dataResource; } + + virtual void setId(std::string const& _id) { m_id = _id; } + virtual void setDesc(std::string _desc) { m_desc = _desc; } + virtual void setDataResource(DataResource::Ptr _dataResource) + { + m_dataResource = _dataResource; + } + // the mpc index + virtual void setPartyIndex(uint16_t _partyIndex) { m_partyIndex = _partyIndex; } + +private: + std::string m_id; + uint16_t m_partyIndex; + std::string m_desc; + DataResource::Ptr m_dataResource; +}; +using Parties = std::vector; +using ConstParties = std::vector; + +inline std::string printPartyInfo(PartyResource::ConstPtr _party) +{ + if (!_party) + { + return "empty"; + } + std::ostringstream stringstream; + stringstream << LOG_KV("partyId", _party->id()) << LOG_KV("partyIndex", _party->partyIndex()) + << LOG_KV("desc", _party->desc()); + + if (_party->dataResource()) + { + auto const& dataResource = _party->dataResource(); + stringstream << printDataResourceInfo(dataResource); + } + return stringstream.str(); +} +} // namespace ppc::protocol diff --git a/cpp/ppc-framework/protocol/Protocol.h b/cpp/ppc-framework/protocol/Protocol.h new file mode 100644 index 00000000..ee893d81 --- /dev/null +++ b/cpp/ppc-framework/protocol/Protocol.h @@ -0,0 +1,539 @@ +/* + * Copyright (C) 2022 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 Protocol.h + * @author: yujiechen + * @date 2022-10-13 + */ +#pragma once + +#if defined(WIN32) || defined(WIN64) || defined(_WIN32) || defined(_WIN32_) +#define WIN32_LEAN_AND_MEAN +#include +#endif +#include "Krb5AuthConfig.h" +#include "ppc-framework/Common.h" +#include +#include +#include +#include +#include + +namespace ppc::protocol +{ +// the task type +enum class TaskType : uint8_t +{ + PSI = 0x00, + PIR = 0x01, +}; + +inline std::ostream& operator<<(std::ostream& _out, TaskType const& _type) +{ + switch (_type) + { + case TaskType::PSI: + _out << "PSI"; + break; + case TaskType::PIR: + _out << "PIR"; + break; + default: + _out << "UnknownTaskType"; + break; + } + return _out; +} + +// the PSIAlgorithm type +enum class TaskAlgorithmType : uint8_t +{ + // PSI implementation for https://eprint.iacr.org/2020/729.pdf(Private Set Intersection in the + // Internet Setting from Lightweight Oblivious PRF) + CM_PSI_2PC = 0x00, + // PSI implementation for https://eprint.iacr.org/2017/677.pdf(Faster Unbalanced Private Set + // Intersection) + RA_PSI_2PC = 0x01, + // PSI implementation for https://eprint.iacr.org/2021/1116(Labeled PSI from Homomorphic + // Encryption with Reduced Computation and Communication) + LABELED_PSI_2PC = 0x02, + ECDH_PSI_2PC = 0x03, + ECDH_PSI_MULTI = 0x04, + ECDH_PSI_CONN = 0x05, + OT_PIR_2PC = 0x10, + BS_ECDH_PSI = 0x06, +}; + +inline std::ostream& operator<<(std::ostream& _out, TaskAlgorithmType const& _type) +{ + switch (_type) + { + case TaskAlgorithmType::CM_PSI_2PC: + _out << "CM_PSI_2PC"; + break; + case TaskAlgorithmType::RA_PSI_2PC: + _out << "RA_PSI_2PC"; + break; + case TaskAlgorithmType::LABELED_PSI_2PC: + _out << "LABELED_PSI_2PC"; + break; + case TaskAlgorithmType::ECDH_PSI_2PC: + _out << "ECDH_PSI_2PC"; + break; + case TaskAlgorithmType::OT_PIR_2PC: + _out << "OT_PIR_2PC"; + break; + case TaskAlgorithmType::ECDH_PSI_MULTI: + _out << "ECDH_PSI_MULTI"; + break; + case TaskAlgorithmType::ECDH_PSI_CONN: + _out << "ECDH_PSI_CONN"; + break; + default: + _out << "UnknownPSIAlgorithm"; + break; + } + return _out; +} + +// the type of the data resource, now support FILE/HDFS, will support SQL in the future +enum class DataResourceType : uint16_t +{ + FILE, + MySQL, + HDFS +}; + +enum class CacheType : uint16_t +{ + Redis +}; + +enum class TaskStatus +{ + PENDING, + RUNNING, + PAUSING, + FAILED, + COMPLETED +}; + +inline bool isExecutable(TaskStatus _status) +{ + return _status == TaskStatus::PENDING || _status == TaskStatus::PAUSING || + _status == TaskStatus::RUNNING; +} + +inline bool isNotExecutable(TaskStatus _status) +{ + return _status == TaskStatus::FAILED || _status == TaskStatus::COMPLETED; +} + +inline std::string toString(TaskStatus _status) +{ + switch (_status) + { + case TaskStatus::PENDING: + return "PENDING"; + case TaskStatus::RUNNING: + return "RUNNING"; + case TaskStatus::PAUSING: + return "PAUSING"; + case TaskStatus::FAILED: + return "FAILED"; + case TaskStatus::COMPLETED: + return "COMPLETED"; + default: + return "UNKNOWN"; + } +} + +inline TaskStatus fromString(const std::string& _str) +{ + static const std::map statusMap = {{"PENDING", TaskStatus::PENDING}, + {"RUNNING", TaskStatus::RUNNING}, {"PAUSING", TaskStatus::PAUSING}, + {"FAILED", TaskStatus::FAILED}, {"COMPLETED", TaskStatus::COMPLETED}}; + + auto it = statusMap.find(_str); + if (it != statusMap.end()) + { + return it->second; + } + else + { + return TaskStatus::FAILED; + } +} + +inline std::ostream& operator<<(std::ostream& _out, DataResourceType const& _type) +{ + switch (_type) + { + case DataResourceType::FILE: + _out << "FILE"; + break; + case DataResourceType::MySQL: + _out << "MySQL"; + break; + case DataResourceType::HDFS: + _out << "HDFS"; + break; + default: + _out << "UnknownDataResourceType"; + break; + } + return _out; +} + +// the party type +// RA involves Server and Client +enum class PartyType : uint16_t +{ + Client, + Server, +}; +inline std::ostream& operator<<(std::ostream& _out, PartyType const& _type) +{ + switch (_type) + { + case PartyType::Client: + _out << "Client"; + break; + case PartyType::Server: + _out << "Server"; + break; + default: + _out << "UnknownPartyType"; + break; + } + return _out; +} + +enum class PartiesType : uint16_t +{ + Calculator, + Partner, + Master, +}; + +inline std::ostream& operator<<(std::ostream& _out, PartiesType const& _type) +{ + switch (_type) + { + case PartiesType::Calculator: + _out << "Calculator"; + break; + case PartiesType::Partner: + _out << "Partner"; + break; + case PartiesType::Master: + _out << "Master"; + break; + default: + _out << "UnknownPartiesType"; + break; + } + return _out; +} + +enum class NodeArch : uint8_t +{ + AIR, // all in one + PRO // gateway and front are independent +}; + +inline std::ostream& operator<<(std::ostream& _out, NodeArch const& _type) +{ + switch (_type) + { + case NodeArch::AIR: + _out << "AIR"; + break; + case NodeArch::PRO: + _out << "PRO"; + break; + default: + _out << "UnknownNodeArch"; + break; + } + return _out; +} + +// define the ppc ret-code +enum PPCRetCode : int +{ + SUCCESS = 0, + EXCEPTION = -100, + TIMEOUT = -101, + DECODE_PPC_MESSAGE_ERROR = -102, + NETWORK_ERROR = -103, + NOTIFY_TASK_ERROR = -104, + REGISTER_GATEWAY_URL_ERROR = -105, + + // the storage error + READ_RPC_STATUS_ERROR = -200, + WRITE_RPC_STATUS_ERROR = -201 +}; + +// the supported ecc-curve +enum class ECCCurve : int8_t +{ + ED25519, + SM2, + SECP256K1, // todo: FourQ + P256, + IPP_X25519, +}; + +// the supported oprf +enum class OprfType : int8_t +{ + EcdhOprf, +}; + +inline std::ostream& operator<<(std::ostream& _out, ECCCurve const& _type) +{ + switch (_type) + { + case ECCCurve::ED25519: + _out << "ED25519"; + break; + case ECCCurve::SM2: + _out << "SM2"; + break; + case ECCCurve::SECP256K1: + _out << "SECP256K1"; + break; + case ECCCurve::P256: + _out << "P256"; + break; + case ECCCurve::IPP_X25519: + _out << "IPP_X25519"; + break; + default: + _out << "UnknownEccCurve"; + break; + } + return _out; +} + +enum class HashImplName : int8_t +{ + SHA256, + SHA512, + SM3, + MD5, + BLAKE2b // TODO: sha3 + // TODO: blake3(https://github.com/BLAKE3-team/BLAKE3) +}; + +enum class PRNGImplName : int8_t +{ + AES, + BLAKE2b, +}; + +enum class SymCryptoImplName : int8_t +{ + AES, + DES_EDE3, + SM4, +}; + +enum class DataPaddingType : int +{ + NONE = 0, + PKCS7 = 1, + ISO7816_4 = 2, + ANSI923 = 3, + ISO10126 = 4, + ZERO = 5, +}; + + +inline std::ostream& operator<<(std::ostream& _out, HashImplName const& _type) +{ + switch (_type) + { + case HashImplName::SHA256: + _out << "SHA256"; + break; + case HashImplName::SHA512: + _out << "SHA512"; + break; + case HashImplName::SM3: + _out << "SM3"; + break; + case HashImplName::MD5: + _out << "MD5"; + break; + case HashImplName::BLAKE2b: + _out << "BLAKE2b"; + break; + default: + _out << "UnknownHashImpl"; + break; + } + return _out; +} + +enum class MessageType : uint16_t +{ + RpcRequest = 0x1000, // the rpc request type +}; + +// option used for sql-connection +struct SQLConnectionOption +{ + using Ptr = std::shared_ptr; + std::string host; + int port; + std::string user; + std::string password; + std::string database; + void check() const + { + if (host.size() == 0) + { + BOOST_THROW_EXCEPTION(WeDPRException() << bcos::errinfo_comment( + "Invalid SQL option: Must set the host!")); + } + if (user.size() == 0) + { + BOOST_THROW_EXCEPTION(WeDPRException() << bcos::errinfo_comment( + "Invalid SQL option: Must set the user!")); + } + if (password.size() == 0) + { + BOOST_THROW_EXCEPTION(WeDPRException() << bcos::errinfo_comment( + "Invalid SQL option: Must set the password!")); + } + if (database.size() == 0) + { + BOOST_THROW_EXCEPTION(WeDPRException() << bcos::errinfo_comment( + "Invalid SQL option: Must set the database!")); + } + if (port == 0 || port > 65535) + { + BOOST_THROW_EXCEPTION(WeDPRException() << bcos::errinfo_comment( + "Invalid SQL Option, Must set valid port!")); + } + } + + inline std::string desc() const + { + std::stringstream oss; + oss << LOG_KV("host", host) << LOG_KV("port", port) << LOG_KV("user", user) + << LOG_KV("database", database); + return oss.str(); + } +}; + +//// the hdfs connection-option +struct FileStorageConnectionOption +{ + using Ptr = std::shared_ptr; + std::string nameNode; + uint16_t nameNodePort; + std::string userName; + std::string token; + // replace-datanode-on-failure + bool replaceDataNodeOnFailure = false; + // the default connection-timeout for the hdfs is 1000ms + uint16_t connectionTimeout = 1000; + Krb5AuthConfig::Ptr authConfig; + + void check() const + { + if (nameNode.size() == 0) + { + BOOST_THROW_EXCEPTION(WeDPRException() << bcos::errinfo_comment( + "Invalid HDFS Option, Must set the nameNode!")); + } + if (userName.size() == 0) + { + BOOST_THROW_EXCEPTION(WeDPRException() << bcos::errinfo_comment( + "Invalid HDFS Option, Must set the userName!")); + } + if (nameNodePort == 0 || nameNodePort > 65535) + { + BOOST_THROW_EXCEPTION(WeDPRException() << bcos::errinfo_comment( + "Invalid HDFS Option, Must set valid namenodeport!")); + } + if (authConfig) + { + authConfig->check(); + } + } + inline std::string desc() const + { + std::stringstream oss; + oss << LOG_KV("nameNode", nameNode) << LOG_KV("nameNodePort", nameNodePort) + << LOG_KV("user", userName) << LOG_KV("token", token) + << LOG_KV("replace-datanode-on-failure", replaceDataNodeOnFailure) + << LOG_KV("connectionTimeout", connectionTimeout) + << LOG_KV("authInfo", authConfig ? authConfig->desc() : "null"); + return oss.str(); + } +}; + +struct RemoteStorageConnectionOption +{ + using Ptr = std::shared_ptr; + std::string host; + uint16_t port; + std::string legalPerson; + std::string user; + std::string password; + std::string obInitServer; + std::string monitorServer; + uint32_t timeoutSec = 600; + int saveCount = 3; // month + std::string logPath; + + inline std::string desc() const + { + std::stringstream oss; + oss << LOG_KV("host", host) << LOG_KV("port", port) << LOG_KV("legalPerson", legalPerson) + << LOG_KV("user", user) << LOG_KV("password", password) + << LOG_KV("obInitServer", obInitServer) << LOG_KV("monitorServer", monitorServer) + << LOG_KV("timeoutSec", timeoutSec) << LOG_KV("saveCount", saveCount) + << LOG_KV("logPath", logPath); + return oss.str(); + } +}; + +struct GatewayInfo +{ + std::string agencyID; + std::string endpoint; +}; + +struct FileInfo +{ + using Ptr = std::shared_ptr; + std::string path; + std::string bizSeqNo; + std::string fileID; + std::string fileMd5; + inline std::string desc() const + { + std::stringstream oss; + oss << LOG_KV("path", path) << LOG_KV("bizSeqNo", bizSeqNo) << LOG_KV("fileID", fileID) + << LOG_KV("fileMd5", fileMd5); + return oss.str(); + } +}; +} // namespace ppc::protocol diff --git a/cpp/ppc-framework/protocol/RouteType.h b/cpp/ppc-framework/protocol/RouteType.h new file mode 100644 index 00000000..3997931a --- /dev/null +++ b/cpp/ppc-framework/protocol/RouteType.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 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; + case RouteType::ROUTE_THROUGH_TOPIC: + _out << "RouteThroughTopic"; + break; + default: + _out << "UnknownRouteType"; + break; + } + return _out; +} +} // namespace ppc::protocol diff --git a/cpp/ppc-framework/protocol/Task.h b/cpp/ppc-framework/protocol/Task.h new file mode 100644 index 00000000..705fa670 --- /dev/null +++ b/cpp/ppc-framework/protocol/Task.h @@ -0,0 +1,187 @@ +/* + * Copyright (C) 2022 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 PartyResource.h + * @author: yujiechen + * @date 2022-10-13 + */ +#pragma once +#include "PartyResource.h" +#include +#include +#include +#include +#include +#include + +namespace ppc::protocol +{ +struct GatewayTaskInfo +{ + using Ptr = std::shared_ptr; + GatewayTaskInfo(std::string const& _taskID) : taskID(_taskID) {} + GatewayTaskInfo() = default; + + std::string taskID; + // Note: optional for the app-level + std::string serviceEndpoint; +}; + + +// Note: can extend on demand +class TaskResult +{ +public: + using Ptr = std::shared_ptr; + TaskResult(std::string const& _taskID) : m_taskID(_taskID) {} + virtual ~TaskResult() = default; + + virtual std::string const& taskID() const { return m_taskID; } + + virtual std::string const& status() const { return m_status; } + virtual void setStatus(const std::string& _status) { m_status = _status; } + + virtual bcos::Error::Ptr error() const { return m_error; } + virtual void setError(bcos::Error::Ptr _error) { m_error = std::move(_error); } + + virtual uint64_t timeCost() const { return m_timeCost; } + virtual void setTimeCost(uint64_t _cost) { m_timeCost = _cost; } + + virtual FileInfo::Ptr fileInfo() const { return m_fileInfo; } + virtual void setFileInfo(FileInfo::Ptr _fileInfo) { m_fileInfo = std::move(_fileInfo); } + + // serialize the taskResult to json + virtual Json::Value serializeToJson() + { + Json::Value response; + response["taskID"] = m_taskID; + if (m_timeCost) + { + response["timeCost"] = std::to_string(m_timeCost) + "ms"; + } + if (m_fileInfo && !m_fileInfo->bizSeqNo.empty()) + { + response["bizSeqNo"] = m_fileInfo->bizSeqNo; + response["fileID"] = m_fileInfo->fileID; + response["fileMd5"] = m_fileInfo->fileMd5; + } + if (m_error && m_error->errorCode() != 0) + { + response["code"] = m_error->errorCode(); + response["message"] = m_error->errorMessage(); + } + else + { + response["code"] = 0; + response["message"] = "success"; + } + if (!m_status.empty()) + { + response["status"] = m_status; + } + return response; + } + +protected: + std::string m_taskID; + std::string m_status; + uint64_t m_timeCost = 0; + bcos::Error::Ptr m_error = nullptr; + FileInfo::Ptr m_fileInfo = nullptr; +}; + +class Task +{ +public: + using Ptr = std::shared_ptr; + using ConstPtr = std::shared_ptr; + Task() = default; + virtual ~Task() = default; + + // the taskID + virtual std::string const& id() const = 0; + // the taskType, e.g. PSI + virtual uint8_t type() const = 0; + // the algorithm + virtual uint8_t algorithm() const = 0; + // information of the local party + virtual PartyResource::ConstPtr selfParty() const = 0; + virtual PartyResource::Ptr mutableSelfParty() const = 0; + // information of the peer party + virtual PartyResource::ConstPtr getPartyByID(std::string const& _partyID) const = 0; + virtual PartyResource::ConstPtr getPartyByIndex(uint16_t _partyIndex) const = 0; + // get all peer-parties + virtual std::map const& getAllPeerParties() const = 0; + // params of the task, can be deserialized using json + virtual std::string const& param() const = 0; + // sync the psi result to peer or not + virtual bool syncResultToPeer() const = 0; + virtual bool lowBandwidth() const = 0; + virtual std::vector const& getReceiverLists() const = 0; + + // the setters + virtual void setId(std::string const& _id) = 0; + virtual void setType(uint8_t _type) = 0; + virtual void setAlgorithm(uint8_t _algorithm) = 0; + virtual void setSelf(PartyResource::Ptr _self) = 0; + virtual void addParty(PartyResource::Ptr _party) = 0; + virtual void setParam(std::string const& _param) = 0; + virtual void setSyncResultToPeer(bool _syncResultToPeer) = 0; + virtual void setLowBandwidth(bool _lowBandwidth) = 0; + // decode the task + virtual void decode(std::string_view _taskData) = 0; + virtual std::string encode() const = 0; + + virtual bool enableOutputExists() const { return m_enableOutputExists; } + virtual void setEnableOutputExists(bool enableOutputExists) + { + m_enableOutputExists = enableOutputExists; + } + +protected: + bool m_enableOutputExists = false; +}; + +class TaskFactory +{ +public: + using Ptr = std::shared_ptr; + using ConstPtr = std::shared_ptr; + TaskFactory() = default; + virtual ~TaskFactory() = default; + + virtual Task::Ptr createTask(std::string_view _taskInfo) = 0; + virtual Task::Ptr createTask() = 0; +}; + +inline std::string printTaskInfo(Task::ConstPtr _task) +{ + std::ostringstream stringstream; + if (!_task) + { + return "empty"; + } + stringstream << LOG_KV("id", _task->id()) + << LOG_KV("type", (ppc::protocol::TaskType)_task->type()) + << LOG_KV("algorithm", (ppc::protocol::TaskAlgorithmType)_task->algorithm()) + << LOG_KV("enableOutputExists", _task->enableOutputExists()) + << LOG_KV("taskPtr", _task); + if (_task->selfParty()) + { + stringstream << printPartyInfo(_task->selfParty()); + } + return stringstream.str(); +} +} // namespace ppc::protocol diff --git a/cpp/ppc-framework/rpc/RpcInterface.h b/cpp/ppc-framework/rpc/RpcInterface.h new file mode 100644 index 00000000..05520e93 --- /dev/null +++ b/cpp/ppc-framework/rpc/RpcInterface.h @@ -0,0 +1,59 @@ +/** + * Copyright (C) 2022 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 RpcInterface.h + * @author: yujiechen + * @date 2022-11-3 + */ +#pragma once +#include "../protocol/Protocol.h" +#include "../protocol/Task.h" +#include +#include +#include +#include +#include + +#define RPC_LOG(LEVEL) BCOS_LOG(LEVEL) << LOG_BADGE("RPC") + +namespace bcos +{ +namespace boostssl +{ +class MessageFace; +class WsSession; +} // namespace boostssl +} // namespace bcos +namespace ppc::rpc +{ +using RespFunc = std::function; +using TaskHandler = std::function)>; +class RpcInterface +{ +public: + using Ptr = std::shared_ptr; + RpcInterface() = default; + virtual ~RpcInterface() = default; + + virtual void start() = 0; + virtual void stop() = 0; + virtual void registerHandler(std::string const& _methodName, + std::function _handler) = 0; + + virtual void registerTaskHandler( + ppc::protocol::TaskType _type, uint8_t _algorithm, TaskHandler _handler) = 0; +}; +} // namespace ppc::rpc \ No newline at end of file diff --git a/cpp/ppc-framework/rpc/RpcStatusInterface.h b/cpp/ppc-framework/rpc/RpcStatusInterface.h new file mode 100644 index 00000000..db971436 --- /dev/null +++ b/cpp/ppc-framework/rpc/RpcStatusInterface.h @@ -0,0 +1,48 @@ +/** + * Copyright (C) 2022 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 RpcStatusInterface.h + * @author: shawnhe + * @date 2023-02-19 + */ + +#pragma once +#include "../protocol/Protocol.h" +#include "../protocol/Task.h" +#include "../storage/SQLStorage.h" +#include +#include +#include +#include + +#define RPC_STATUS_LOG(LEVEL) BCOS_LOG(LEVEL) << LOG_BADGE("RpcStatus") + +namespace ppc::rpc +{ +class RpcStatusInterface +{ +public: + using Ptr = std::shared_ptr; + RpcStatusInterface() = default; + virtual ~RpcStatusInterface() = default; + + virtual void start() = 0; + virtual void stop() = 0; + + virtual bcos::Error::Ptr insertTask(protocol::Task::Ptr _task) = 0; + virtual bcos::Error::Ptr updateTaskStatus(protocol::TaskResult::Ptr _taskResult) = 0; + virtual protocol::TaskResult::Ptr getTaskStatus(const std::string& _taskID) = 0; +}; +} // namespace ppc::rpc \ No newline at end of file diff --git a/cpp/ppc-framework/rpc/RpcTypeDef.h b/cpp/ppc-framework/rpc/RpcTypeDef.h new file mode 100644 index 00000000..208fee40 --- /dev/null +++ b/cpp/ppc-framework/rpc/RpcTypeDef.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2022 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 RpcTypeDef.h + * @author: yujiechen + * @date 2022-11-3 + */ +#pragma once +#include + +namespace ppc::rpc +{ +enum class RpcError : int32_t +{ + LackOfMemory = -33, + InvalidRequest = -32600, + MethodNotFound = -32601, + NotImplemented = -32602, + StorageNotSet = -32603, + NoPermission = -32604, + BsModePsiNotSet = -32605, +}; + +std::string const RUN_TASK_METHOD = "runTask"; +std::string const ASYNC_RUN_TASK_METHOD = "asyncRunTask"; +std::string const GET_TASK_STATUS = "getTaskStatus"; +std::string const GET_PEERS = "getPeers"; + +std::string const ASYNC_RUN_BS_MODE_TASK = "asyncRunBsModeTask"; +std::string const FETCH_CIPHER = "fetchCipher"; +std::string const SEND_ECDH_CIPHER = "sendEcdhCipher"; +std::string const SEND_PARTNER_CIPHER = "sendPartnerCipher"; +std::string const GET_BS_MODE_TASK_STATUS = "getBsModeTaskStatus"; +std::string const KILL_BS_MODE_TASK = "killBsModeTask"; +std::string const UPDATE_BS_MODE_TASK_STATUS = "updateBsModeTaskStatus"; +} // namespace ppc::rpc \ No newline at end of file diff --git a/cpp/ppc-framework/storage/CacheStorage.h b/cpp/ppc-framework/storage/CacheStorage.h new file mode 100644 index 00000000..96da2e02 --- /dev/null +++ b/cpp/ppc-framework/storage/CacheStorage.h @@ -0,0 +1,114 @@ +/** + * Copyright (C) 2022 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 StorageCache.h + * @author: shawnhe + * @date 2022-10-21 + */ + +#pragma once +#include "ppc-framework/protocol/Protocol.h" +#include +#include +#include +#include +#include + +namespace ppc::storage +{ +struct CacheStorageConfig +{ + ppc::protocol::CacheType type; + std::string proxy; + std::string obServer; + std::string cluster; + std::string user; + std::string host; + uint16_t port; + std::string password; + uint16_t database; + uint16_t pool; + // default connection-timeout is 500ms + uint16_t connectionTimeout = 500; + // default socket-timeout is 500ms + uint16_t socketTimeout = 500; + + inline std::string desc() const + { + std::stringstream oss; + oss << LOG_KV("type", (int)type) << LOG_KV("proxy", proxy) << LOG_KV("obServer", obServer) + << LOG_KV("cluster", cluster) << LOG_KV("host", host) << LOG_KV("port", port) + << LOG_KV("database", database) << LOG_KV("poolSize", pool) + << LOG_KV("connectionTimeout", connectionTimeout) + << LOG_KV("socketTimeout", socketTimeout); + return oss.str(); + } +}; + +class CacheStorage +{ +public: + using Ptr = std::shared_ptr; + CacheStorage() = default; + virtual ~CacheStorage() {} + + /** + * @brief: check whether the key exists + * @param _key: key + * @return whether the key exists + */ + virtual bool exists(const std::string& _key) = 0; + + /** + * @brief: set key value + * @param _expirationTime: timeout of key, in seconds, when set to -1, never expire + */ + virtual void setValue( + const std::string& _key, const std::string& _value, int32_t _expirationSeconds = -1) = 0; + + /** + * @brief: get value by key + * @param _key: key + * @return std::nullopt if the key doesn't exist; + */ + virtual std::optional getValue(const std::string& _key) = 0; + + /** + * @brief: set a timeout on key + * @param _expirationTime: timeout of key, seconds + * @return whether setting is successful + */ + virtual bool expireKey(const std::string& _key, uint32_t _expirationSeconds) = 0; + + /** + * @brief: delete key + * @param _key: key + * @return the number of key deleted + */ + virtual uint64_t deleteKey(const std::string& _key) = 0; +}; + + +class CacheStorageFactory +{ +public: + using Ptr = std::shared_ptr; + CacheStorageFactory() = default; + virtual ~CacheStorageFactory() = default; + + virtual CacheStorage::Ptr createCacheStorage(CacheStorageConfig const& _config) = 0; +}; + +} // namespace ppc::storage diff --git a/cpp/ppc-framework/storage/FileStorage.h b/cpp/ppc-framework/storage/FileStorage.h new file mode 100644 index 00000000..beccc85c --- /dev/null +++ b/cpp/ppc-framework/storage/FileStorage.h @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2022 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 FileStorage.h + * @author: yujiechen + * @date 2022-11-30 + */ +#pragma once +#include "../protocol/Protocol.h" +#include + +namespace ppc::storage +{ +class FileHandler +{ +public: + using Ptr = std::shared_ptr; + FileHandler() = default; + virtual ~FileHandler() = default; + + virtual void* fileInfoHandler() const = 0; + virtual void* storageHandler() const = 0; + virtual std::string const& path() const = 0; +}; + +class FileStorage +{ +public: + using Ptr = std::shared_ptr; + FileStorage() = default; + virtual ~FileStorage() = default; + + // create the directory + virtual void createDirectory(std::string const& _dirPath) const = 0; + // open the file + virtual FileHandler::Ptr openFile( + std::string const& _path, bool _createIfNotExists = false) const = 0; + // close the file + virtual void closeFile(FileHandler::Ptr _handler) const = 0; + + // delete the specified file + virtual void deleteFile(std::string const& _path) const = 0; + + // check the specified file exists or not + virtual bool fileExists(std::string const& _path) const = 0; + + virtual void renameFile(std::string const& _old_path, std::string const& _new_path) const = 0; +}; + +class FileStorageFactory +{ +public: + using Ptr = std::shared_ptr; + FileStorageFactory() = default; + virtual ~FileStorageFactory() = default; + + virtual FileStorage::Ptr createFileStorage(ppc::protocol::DataResourceType _type, + ppc::protocol::FileStorageConnectionOption::Ptr const& _option) = 0; +}; +} // namespace ppc::storage \ No newline at end of file diff --git a/cpp/ppc-framework/storage/RemoteStorage.h b/cpp/ppc-framework/storage/RemoteStorage.h new file mode 100644 index 00000000..16906016 --- /dev/null +++ b/cpp/ppc-framework/storage/RemoteStorage.h @@ -0,0 +1,48 @@ +/** + * Copyright (C) 2022 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 RemoteStorage.h + * @author: shawnhe + * @date 2023-1-29 + */ +#pragma once +#include "../protocol/Protocol.h" +#include + +namespace ppc::storage +{ + +class RemoteStorage +{ +public: + using Ptr = std::shared_ptr; + RemoteStorage() = default; + virtual ~RemoteStorage() = default; + + virtual protocol::FileInfo::Ptr upload(std::string const& _path) = 0; + virtual void download(protocol::FileInfo::Ptr _fileInfo) = 0; +}; + +class RemoteStorageFactory +{ +public: + using Ptr = std::shared_ptr; + RemoteStorageFactory() = default; + virtual ~RemoteStorageFactory() = default; + + virtual RemoteStorage::Ptr createRemoteStorage(ppc::protocol::DataResourceType _type, + ppc::protocol::RemoteStorageConnectionOption::Ptr const& _option) = 0; +}; +} // namespace ppc::storage \ No newline at end of file diff --git a/cpp/ppc-framework/storage/SQLStorage.h b/cpp/ppc-framework/storage/SQLStorage.h new file mode 100644 index 00000000..90f3cd60 --- /dev/null +++ b/cpp/ppc-framework/storage/SQLStorage.h @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2022 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 SQLStorage.h + * @author: yujiechen + * @date 2022-10-25 + */ +#pragma once +#include "../io/DataBatch.h" +#include "ppc-framework/protocol/Protocol.h" +#include +#include +namespace ppc::storage +{ +enum FieldDataType : int +{ + SINT = 0, + UINT = 1, + DOUBLE = 2, + FLOAT = 3, + BYTES = 4, + STRING = 5, + TERMINATE, +}; + +using MetaFieldType = std::vector; +class QueryResult +{ +public: + using Ptr = std::shared_ptr; + QueryResult() = default; + virtual ~QueryResult() = default; + + MetaFieldType const& metaData() const { return m_metaData; } + std::vector const& data() const { return m_data; } + + MetaFieldType& mutableMetaData() { return m_metaData; } + std::vector& mutableData() { return m_data; } + + uint64_t size() const { return m_data.size(); } + +private: + // the meta-data + MetaFieldType m_metaData; + // the data + std::vector m_data; +}; + +class Statement +{ +public: + using Ptr = std::shared_ptr; + Statement() = default; + virtual ~Statement() = default; + // get the statementContext + virtual void* statementContext() = 0; + virtual void* takeSession() = 0; +}; + +class SQLResultContext +{ +public: + using Ptr = std::shared_ptr; + SQLResultContext() = default; + virtual ~SQLResultContext() = default; + + // get the sql-result + virtual void* result() = 0; +}; + +// Only the synchronous interface is provided here +class SQLStorage +{ +public: + using Ptr = std::shared_ptr; + + SQLStorage() = default; + virtual ~SQLStorage() = default; + + // use the database + virtual void useDataBase(const char* _database) = 0; + + // exec the sql-query-command + virtual QueryResult::Ptr execQuery(bool _parseByColumn, const char* _command, ...) const = 0; + // exec the sql-write-command: insert/update/delete + virtual void execCommit(const char* _command, ...) const = 0; + + virtual Statement::Ptr generateStatement(const char* _command, ...) const = 0; + virtual SQLResultContext::Ptr execStatement(Statement::Ptr _statement) const = 0; + virtual void appendStatement(Statement::Ptr _statement, ...) const = 0; + virtual std::string const& databaseName() const = 0; +}; + +class SQLStorageFactory +{ +public: + using Ptr = std::shared_ptr; + SQLStorageFactory() = default; + virtual ~SQLStorageFactory() = default; + + virtual SQLStorage::Ptr createSQLStorage(ppc::protocol::DataResourceType _type, + ppc::protocol::SQLConnectionOption::Ptr const& _option) = 0; +}; +} // namespace ppc::storage \ No newline at end of file diff --git a/cpp/ppc-framework/task/TaskFrameworkInterface.h b/cpp/ppc-framework/task/TaskFrameworkInterface.h new file mode 100644 index 00000000..437d94bf --- /dev/null +++ b/cpp/ppc-framework/task/TaskFrameworkInterface.h @@ -0,0 +1,47 @@ +/** + * Copyright (C) 2022 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. + * + * @brief the TaskFrameworkInterface + * @file TaskFrameworkInterface.h + * @author: yujiechen + * @date 2022-11-16 + */ +#pragma once +#include "../protocol/PPCMessageFace.h" +#include "../protocol/Task.h" +#include +#include +namespace ppc::task +{ +using TaskResponseCallback = std::function; + +class TaskFrameworkInterface +{ +public: + using Ptr = std::shared_ptr; + TaskFrameworkInterface() = default; + virtual ~TaskFrameworkInterface() = default; + + // run task + virtual void asyncRunTask( + ppc::protocol::Task::ConstPtr _task, TaskResponseCallback&& _onTaskFinished) = 0; + + // register to the front to get the message related to ra2018 + virtual void onReceiveMessage(ppc::front::PPCMessageFace::Ptr _msg) = 0; + + virtual void start() = 0; + virtual void stop() = 0; +}; +} // namespace ppc::psi \ No newline at end of file diff --git a/cpp/test-utils/FakeFront.h b/cpp/test-utils/FakeFront.h new file mode 100644 index 00000000..539c1238 --- /dev/null +++ b/cpp/test-utils/FakeFront.h @@ -0,0 +1,254 @@ +/** + * Copyright (C) 2022 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. + * + * @brief fake ppc network message interface + * @file FakeFront.h + * @author: yujiechen + * @date 2022-11-16 + */ +#pragma once +#include "ppc-framework/front/FrontInterface.h" +#include "ppc-framework/protocol/Protocol.h" +#include "ppc-framework/task/TaskFrameworkInterface.h" + +using namespace ppc::protocol; +using namespace ppc::front; +// using namespace ppc::psi; +using namespace ppc::task; + +namespace ppc::test +{ +class FakeFront : public FrontInterface +{ +public: + using Ptr = std::shared_ptr; + FakeFront() = default; + ~FakeFront() override = default; + + void registerMessageHandler(uint8_t _taskType, uint8_t _algorithmType, + std::function _handler) override + {} + + void registerRA2018(std::string const& _agencyID, TaskFrameworkInterface::Ptr _psi) + { + std::cout << "### registerRA2018: " << _agencyID << std::endl; + m_agencyToRA2018[_agencyID] = _psi; + } + + void registerEcdhPSI(std::string const& _agencyID, TaskFrameworkInterface::Ptr _psi) + { + std::cout << "### registerEcdhPSI: " << _agencyID << std::endl; + m_agencyToEcdhPSI[_agencyID] = _psi; + } + + void registerEcdhMultiPSI(std::string const& _agencyID, TaskFrameworkInterface::Ptr _psi) + { + std::cout << "### registerEcdhMultiPSI: " << _agencyID << std::endl; + m_agencyToEcdhMutliPSI[_agencyID] = _psi; + } + + void registerLabeledPSI(std::string const& _agencyID, TaskFrameworkInterface::Ptr _psi) + { + m_agencyToLabeledPSI[_agencyID] = _psi; + } + + void registerCM2020(std::string const& _agencyID, TaskFrameworkInterface::Ptr _psi) + { + m_agencyToCM2020[_agencyID] = _psi; + } + + void registerOTPIR(std::string const& _agencyID, TaskFrameworkInterface::Ptr _pir) + { + m_agencyToOTPIR[_agencyID] = _pir; + } + + void asyncSendMessage(const std::string& _agencyID, front::PPCMessageFace::Ptr _message, + uint32_t _timeout, ErrorCallbackFunc _callback, CallbackFunc _responseCallback) override + { + m_uuid++; + auto id = std::to_string(m_uuid); + if (_responseCallback) + { + insertCallback(id, _responseCallback); + _message->setUuid(id); + } + + + uint8_t type = _message->algorithmType(); + switch (type) + { + case uint8_t(TaskAlgorithmType::RA_PSI_2PC): + { + if (!m_agencyToRA2018.count(_agencyID)) + { + _callback(std::make_shared( + -1, "RA_PSI_2PC asyncSendMessage error! The gateway '" + _agencyID + + "' is not reachable!")); + return; + } + auto psi = m_agencyToRA2018.at(_agencyID); + psi->onReceiveMessage(_message); + _callback(nullptr); + break; + } + case uint8_t(TaskAlgorithmType::LABELED_PSI_2PC): + { + if (!m_agencyToLabeledPSI.count(_agencyID)) + { + _callback(std::make_shared( + -1, "LABELED_PSI_2PC asyncSendMessage error! The gateway " + _agencyID + + " is not reachable!")); + return; + } + auto psi = m_agencyToLabeledPSI.at(_agencyID); + psi->onReceiveMessage(_message); + _callback(nullptr); + break; + } + case uint8_t(TaskAlgorithmType::CM_PSI_2PC): + { + if (!m_agencyToCM2020.count(_agencyID)) + { + _callback(std::make_shared( + -1, "CM_PSI_2PC asyncSendMessage error! The gateway " + _agencyID + + " is not reachable!")); + return; + } + auto psi = m_agencyToCM2020.at(_agencyID); + psi->onReceiveMessage(_message); + _callback(nullptr); + break; + } + case uint8_t(TaskAlgorithmType::ECDH_PSI_2PC): + { + if (!m_agencyToEcdhPSI.count(_agencyID)) + { + _callback(std::make_shared( + -1, "ECDH_PSI_2PC asyncSendMessage error! The gateway " + _agencyID + + " is not reachable!")); + return; + } + auto psi = m_agencyToEcdhPSI.at(_agencyID); + psi->onReceiveMessage(_message); + _callback(nullptr); + break; + } + case uint8_t(TaskAlgorithmType::ECDH_PSI_MULTI): + { + if (!m_agencyToEcdhMutliPSI.count(_agencyID)) + { + _callback(std::make_shared( + -1, "ECDH_PSI_MULTI asyncSendMessage error! The gateway " + _agencyID + + " is not reachable!")); + return; + } + auto psi = m_agencyToEcdhMutliPSI.at(_agencyID); + psi->onReceiveMessage(_message); + _callback(nullptr); + break; + } + case uint8_t(TaskAlgorithmType::OT_PIR_2PC): + { + if (!m_agencyToOTPIR.count(_agencyID)) + { + _callback(std::make_shared( + -1, "OT_PIR_2PC asyncSendMessage error! The gateway " + _agencyID + + " is not reachable!")); + return; + } + auto pir = m_agencyToOTPIR.at(_agencyID); + pir->onReceiveMessage(_message); + _callback(nullptr); + break; + } + default: // unreachable-branch + break; + } + } + + bcos::Error::Ptr notifyTaskInfo(std::string const&) override { return nullptr; } + + // erase the task-info when task finished + bcos::Error::Ptr eraseTaskInfo(std::string const&) override { return nullptr; } + + // send response when receiving message from given agencyID + void asyncSendResponse(bcos::bytes const& peer, std::string const& _uuid, + front::PPCMessageFace::Ptr _message, ErrorCallbackFunc _callback) override + { + if (m_uuidToCallback.count(_uuid)) + { + auto callback = m_uuidToCallback[_uuid]; + removeCallback(_uuid); + if (callback) + { + callback(nullptr, std::string(peer.begin(), peer.end()), _message, nullptr); + } + } + } + + // for ut + void setAgencyList(std::vector const& agencyList) + { + bcos::WriteGuard l(x_agencyList); + m_agencyList = agencyList; + } + + std::vector agencies() const override + { + bcos::ReadGuard l(x_agencyList); + return m_agencyList; + } + + void start() override {} + void stop() override {} + +private: + // the uuid to _callback + void insertCallback(std::string const& _id, CallbackFunc _callback) + { + bcos::Guard l(m_mutex); + m_uuidToCallback[_id] = _callback; + } + + void removeCallback(std::string const& _id) + { + bcos::Guard l(m_mutex); + m_uuidToCallback.erase(_id); + } + +private: + // Note: here assume that one agency has one psi + std::map m_agencyToRA2018; + + std::map m_agencyToEcdhPSI; + + std::map m_agencyToEcdhMutliPSI; + + std::map m_agencyToLabeledPSI; + + std::map m_agencyToCM2020; + + std::map m_agencyToOTPIR; + + // uuid to callback + std::map m_uuidToCallback; + bcos::Mutex m_mutex; + std::atomic m_uuid = 0; + + // the agency list, for task-sync + std::vector m_agencyList; + mutable bcos::SharedMutex x_agencyList; +}; +} // namespace ppc::test \ No newline at end of file diff --git a/cpp/test-utils/FakePPCMessage.h b/cpp/test-utils/FakePPCMessage.h new file mode 100644 index 00000000..44fa9d56 --- /dev/null +++ b/cpp/test-utils/FakePPCMessage.h @@ -0,0 +1,138 @@ +/** + * Copyright (C) 2022 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. + * + * @brief fake ppc network message interface + * @file FakePPCMessage.h + * @author: yujiechen + * @date 2022-11-16 + */ +#pragma once +#include "ppc-framework/protocol/PPCMessageFace.h" + +using namespace ppc::front; +namespace ppc::test +{ +class FakePPCMessage : public PPCMessageFace +{ +public: + using Ptr = std::shared_ptr; + FakePPCMessage() = default; + ~FakePPCMessage() override = default; + + uint8_t version() const override { return m_version; } + void setVersion(uint8_t _version) override { m_version = _version; } + uint8_t taskType() const override { return m_taskType; } + void setTaskType(uint8_t _taskType) override { m_taskType = _taskType; } + uint8_t algorithmType() const override { return m_algorithmType; } + void setAlgorithmType(uint8_t _algorithmType) override { m_algorithmType = _algorithmType; } + uint8_t messageType() const override { return m_messageType; } + void setMessageType(uint8_t _messageType) override { m_messageType = _messageType; } + uint32_t seq() const override { return m_seq; } + void setSeq(uint32_t _seq) override { m_seq = _seq; } + std::string const& taskID() const override { return m_taskID; } + void setTaskID(std::string const& _taskID) override { m_taskID = _taskID; } + std::map header() override { return m_header; } + void setHeader(std::map _header) override { m_header = _header; } + + std::string const& sender() const override { return m_sender; } + void setSender(std::string const& _sender) override { m_sender = _sender; } + + std::shared_ptr data() const override { return m_data; } + void setData(std::shared_ptr _data) override { m_data = _data; } + // Note: we don't fake the encode-decode here + void encode(bcos::bytes&) override + { + throw std::runtime_error("FakePPCMessage: unimplemented interface!"); + } + int64_t decode(bcos::bytesPointer) override + { + throw std::runtime_error("FakePPCMessage: unimplemented interface!"); + } + int64_t decode(bcos::bytesConstRef) override + { + throw std::runtime_error("FakePPCMessage: unimplemented interface!"); + } + uint32_t length() const override { return 0; } + + std::string uuid() const override { return m_uuid; } + void setUuid(std::string const& _uuid) override { m_uuid = _uuid; } + + // determine the message is response or not + bool response() const override { return m_response; } + // set the message to be response + void setResponse() override { m_response = true; } + + + bcos::bytes const& senderNode() const override { return m_senderNode; } + + void setSenderNode(bcos::bytes const& senderNode) override { m_senderNode = senderNode; } + +private: + bcos::bytes m_senderNode; + uint8_t m_version; + uint8_t m_taskType; + uint8_t m_algorithmType; + uint8_t m_messageType; + uint32_t m_seq; + std::string m_taskID; + std::string m_sender; + uint16_t m_ext; + std::shared_ptr m_data; + std::string m_uuid; + std::map m_header; + bool m_response = false; +}; + +class FakePPCMessageFactory : public PPCMessageFaceFactory +{ +public: + using Ptr = std::shared_ptr; + FakePPCMessageFactory() = default; + ~FakePPCMessageFactory() override = default; + PPCMessageFace::Ptr buildPPCMessage() override { return std::make_shared(); } + PPCMessageFace::Ptr buildPPCMessage(bcos::bytesConstRef) override + { + throw std::runtime_error("FakePPCMessageFactory: unimplemented interface!"); + } + + PPCMessageFace::Ptr buildPPCMessage(bcos::bytesPointer) override + { + throw std::runtime_error("FakePPCMessageFactory: unimplemented interface!"); + } + + PPCMessageFace::Ptr buildPPCMessage(uint8_t _taskType, uint8_t _algorithmType, + std::string const& _taskID, bcos::bytesPointer _data) override + { + throw std::runtime_error("FakePPCMessageFactory: unimplemented interface!"); + } + PPCMessageFace::Ptr decodePPCMessage(ppc::protocol::Message::Ptr msg) override + { + throw std::runtime_error("FakePPCMessageFactory: unimplemented interface!"); + } + ppc::protocol::Message::Ptr buildMessage(ppc::protocol::MessageBuilder::Ptr const& msgBuilder, + ppc::protocol::MessagePayloadBuilder::Ptr const& msgPayloadBuilder, + PPCMessageFace::Ptr const& ppcMessage) override + { + throw std::runtime_error("FakePPCMessageFactory: unimplemented interface!"); + } + + ppc::protocol::MessagePayload::Ptr buildMessage( + ppc::protocol::MessagePayloadBuilder::Ptr const& msgPayloadBuilder, + PPCMessageFace::Ptr const& ppcMessage) override + { + throw std::runtime_error("FakePPCMessageFactory: unimplemented interface!"); + } +}; +} // namespace ppc::test \ No newline at end of file diff --git a/cpp/test-utils/FileTool.h b/cpp/test-utils/FileTool.h new file mode 100644 index 00000000..fee10152 --- /dev/null +++ b/cpp/test-utils/FileTool.h @@ -0,0 +1,134 @@ +/** + * Copyright (C) 2022 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 applicabl 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 FileTool.cpp + * @author: shawnhe + * @date 2022-12-19 + */ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace ppc::test +{ +inline void writeByMmap( + const std::string& _path, const std::shared_ptr>& _buffer) +{ + int fd = open(_path.c_str(), O_RDWR | O_CREAT, (mode_t)0600); + if (fd == -1) + { + BOOST_THROW_EXCEPTION(std::runtime_error("open file error")); + } + + uint64_t textSize = _buffer->size() * (64); + + // update the size of file + ftruncate(fd, textSize); + + char* map = (char*)mmap(nullptr, textSize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + if (map == MAP_FAILED) + { + close(fd); + BOOST_THROW_EXCEPTION(std::runtime_error("mmap file to memory error")); + } + + uint64_t count = 0; + + for (std::string line : *_buffer) + { + for (char c : line) + { + map[count++] = c; + } + map[count++] = '\n'; + } + + ftruncate(fd, count); + + // write it now to disk + if (msync(map, count, MS_SYNC) == -1) + { + BOOST_THROW_EXCEPTION(std::runtime_error("mmap file to disk error")); + } + + munmap(map, count); + + close(fd); +} + +inline void prepareInputs(const std::string& _path1, uint32_t _size1, const std::string& _path2, + uint32_t _size2, uint32_t _common) +{ + assert(_size1 >= _common && _size2 >= _common); + + uint32_t start1 = 100000, end1 = 100000 + _size1; + auto input1 = std::make_shared>(); + input1->reserve(_size1); + for (uint i = start1; i < end1; i++) + { + input1->push_back(std::to_string(i) + "\r"); + } + writeByMmap(_path1, input1); + + uint32_t start2 = end1 - _common, end2 = end1 - _common + _size2; + auto input2 = std::make_shared>(); + input2->reserve(_size2); + for (uint i = start2; i < end2; i++) + { + input2->push_back(std::to_string(i)); + } + writeByMmap(_path2, input2); +} + +inline void prepareInputs(const std::string& _path, uint32_t _size) +{ + uint32_t start = 100000, end = 100000 + _size; + auto input = std::make_shared>(); + input->reserve(_size); + for (uint i = start; i < end; i++) + { + input->push_back(std::to_string(i)); + } + writeByMmap(_path, input); +} + +inline void prepareItemsAndLabels(const std::string& _path, uint32_t _size) +{ + uint32_t start = 100000, end = 100000 + _size; + auto input = std::make_shared>(); + input->reserve(_size); + for (uint i = start; i < end; i++) + { + input->push_back( + std::to_string(i) + "," + std::to_string(i) + std::to_string(i) + std::to_string(i)); + } + writeByMmap(_path, input); +} + +} // namespace ppc::test diff --git a/cpp/test-utils/TaskMock.h b/cpp/test-utils/TaskMock.h new file mode 100644 index 00000000..7056478c --- /dev/null +++ b/cpp/test-utils/TaskMock.h @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2022 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 TaskMock.h + * @author: yujiechen + * @date 2022-10-19 + */ +#pragma once +#include "ppc-framework/protocol/Task.h" +#include + +using namespace ppc::protocol; +namespace ppc::test +{ +inline PartyResource::Ptr mockParty(uint16_t _partyIndex, std::string const& _id, + std::string const& _desc, std::string const& _dataId, ppc::protocol::DataResourceType _dataType, + std::string const& _path, const std::vector>& _rowData = {}) +{ + auto party = std::make_shared(_id, (uint16_t)_partyIndex); + party->setDesc(_desc); + auto dataResource = std::make_shared(_dataId); + auto dataDesc = std::make_shared(); + dataDesc->setType((uint16_t)_dataType); + dataDesc->setPath(_path); + dataResource->setDesc(dataDesc); + party->setDataResource(dataResource); + + if (!_rowData.empty()) + { + dataResource->setRawData(_rowData); + } + return party; +} + +inline void checkParty(PartyResource::ConstPtr _party1, PartyResource::ConstPtr _party2) +{ + BOOST_CHECK(_party1->partyIndex() == _party2->partyIndex()); + BOOST_CHECK(_party1->desc() == _party2->desc()); + BOOST_CHECK(_party1->id() == _party2->id()); + BOOST_CHECK(_party1->partyIndex() == _party2->partyIndex()); + if (!_party1->dataResource()) + { + return; + } + // check the dataResource + BOOST_CHECK(_party1->dataResource()->resourceID() == _party2->dataResource()->resourceID()); + if (!_party1->dataResource()->desc()) + { + return; + } + BOOST_CHECK(_party1->dataResource()->desc()->type() == _party2->dataResource()->desc()->type()); + // BOOST_CHECK(_party1->dataResource()->desc()->path() == + // _party2->dataResource()->desc()->path()); + BOOST_CHECK(_party1->dataResource()->desc()->accessCommand() == + _party2->dataResource()->desc()->accessCommand()); + + BOOST_CHECK( + _party1->dataResource()->rawData().size() == _party2->dataResource()->rawData().size()); +} + +inline void checkTask(Task::Ptr _task1, Task::Ptr _task2) +{ + BOOST_CHECK(_task1->id() == _task2->id()); + BOOST_CHECK(_task1->type() == _task2->type()); + BOOST_CHECK(_task1->param() == _task2->param()); + BOOST_CHECK(_task1->syncResultToPeer() == _task2->syncResultToPeer()); + // check self-party + if (_task1->selfParty()) + { + checkParty(_task1->selfParty(), _task2->selfParty()); + } + // check peersParty + auto const& peersParty = _task1->getAllPeerParties(); + BOOST_CHECK(peersParty.size() == _task2->getAllPeerParties().size()); + for (auto const& it : peersParty) + { + checkParty(it.second, _task2->getPartyByID(it.first)); + } +} +} // namespace ppc::test diff --git a/cpp/tools/build_ppc.sh b/cpp/tools/build_ppc.sh new file mode 100644 index 00000000..621f5c99 --- /dev/null +++ b/cpp/tools/build_ppc.sh @@ -0,0 +1,1003 @@ +#!/bin/bash + +dirpath="$(cd "$(dirname "$0")" && pwd)" +binary_name="ppc-air-node" +binary_path= +output_dir="ppc-nodes" + +listen_ip="0.0.0.0" + +cdn_link_header="https://osp-1257653870.cos.ap-guangzhou.myqcloud.com/FISCO-BCOS" +OPENSSL_CMD="${HOME}/.fisco/tassl-1.1.1b" + +port_start=(40300 10200 18000) +gateway_listen_port=port_start[0] +rpc_listen_port=port_start[1] +grpc_listen_port=port_start[2] + +use_ip_param= +ip_param= + +ip_array= +ip_file= + +ca_dir="" +cert_conf="${output_dir}/cert.cnf" +sm_cert_conf='sm_cert.cnf' +sm2_params="sm_sm2.param" +sm_mode="false" +days=36500 +rsa_key_length=2048 +p2p_connected_conf_name="nodes.json" +file_dir="./" + +default_version="v1.1.0" +compatibility_version=${default_version} +command="deploy" + +disable_ra2018="true" + +LOG_WARN() { + local content=${1} + echo -e "\033[31m[ERROR] ${content}\033[0m" +} + +LOG_INFO() { + local content=${1} + echo -e "\033[32m[INFO] ${content}\033[0m" +} + +LOG_FATAL() { + local content=${1} + echo -e "\033[31m[FATAL] ${content}\033[0m" + exit 1 +} + +dir_must_exists() { + if [ ! -d "$1" ]; then + LOG_FATAL "$1 DIR does not exist, please check!" + fi +} + +get_value() { + local var_name=${1} + var_name=var_${var_name//./} + local res=$(eval echo '$'"${var_name}") + echo ${res} +} + +set_value() { + local var_name=${1} + var_name=var_${var_name//./} + local var_value=${2} + eval "${var_name}=${var_value}" +} + +dir_must_not_exists() { + if [ -d "$1" ]; then + LOG_FATAL "$1 DIR already exist, please check!" + fi +} + +file_must_not_exists() { + if [ -f "$1" ]; then + LOG_FATAL "$1 file already exist, please check!" + fi +} + +file_must_exists() { + if [ ! -f "$1" ]; then + LOG_FATAL "$1 file does not exist, please check!" + fi +} + +check_env() { + if [ "$(uname)" == "Darwin" ];then + macOS="macOS" + fi + if [ "$(uname -m)" != "x86_64" ];then + x86_64_arch="false" + fi +} +check_name() { + local name="$1" + local value="$2" + [[ "$value" =~ ^[a-zA-Z0-9._-]+$ ]] || { + LOG_FATAL "$name name [$value] invalid, it should match regex: ^[a-zA-Z0-9._-]+\$" + } +} +parse_ip_config() { + local config=$1 + n=0 + while read line; do + ip_array[n]=$(echo ${line} | awk '{print $1}') + if [ -z "${ip_array[$n]}" ]; then + exit_with_clean "Please check ${config}, make sure there is no empty line!" + fi + ((++n)) + done <${config} +} +check_and_install_tassl(){ + if [ -f "${OPENSSL_CMD}" ];then + return + fi + # https://en.wikipedia.org/wiki/Uname#Examples + local x86_64_name="x86_64" + local arm_name="aarch64" + local tassl_mid_name="linux" + if [[ -n "${macOS}" ]];then + x86_64_name="x86_64" + arm_name="arm64" + tassl_mid_name="macOS" + fi + + local tassl_post_fix="x86_64" + local platform="$(uname -m)" + if [[ "${platform}" == "${arm_name}" ]];then + tassl_post_fix="aarch64" + elif [[ "${platform}" == "${x86_64_name}" ]];then + tassl_post_fix="x86_64" + else + LOG_FATAL "Unsupported platform ${platform} for ${tassl_mid_name}" + exit 1 + fi + local tassl_package_name="tassl-1.1.1b-${tassl_mid_name}-${tassl_post_fix}" + local tassl_tgz_name="${tassl_package_name}.tar.gz" + local tassl_link_prefix="${cdn_link_header}/FISCO-BCOS/tools/tassl-1.1.1b/${tassl_tgz_name}" + LOG_INFO "Downloading tassl binary from ${tassl_link_prefix}..." + wget --no-check-certificate "${tassl_link_prefix}" + tar zxvf ${tassl_tgz_name} && rm ${tassl_tgz_name} + chmod u+x ${tassl_package_name} + mkdir -p "${HOME}"/.fisco + mv ${tassl_package_name} "${HOME}"/.fisco/tassl-1.1.1b +} + + +generate_sm_sm2_param() { + local output=$1 + cat << EOF > ${output} +-----BEGIN EC PARAMETERS----- +BggqgRzPVQGCLQ== +-----END EC PARAMETERS----- + +EOF +} + +generate_sm_cert_conf() { + local output=$1 + cat <"${output}" +oid_section = new_oids + +[ new_oids ] +tsa_policy1 = 1.2.3.4.1 +tsa_policy2 = 1.2.3.4.5.6 +tsa_policy3 = 1.2.3.4.5.7 + +#################################################################### +[ ca ] +default_ca = CA_default # The default ca section + +#################################################################### +[ CA_default ] + +dir = ./demoCA # Where everything is kept +certs = $dir/certs # Where the issued certs are kept +crl_dir = $dir/crl # Where the issued crl are kept +database = $dir/index.txt # database index file. +#unique_subject = no # Set to 'no' to allow creation of + # several ctificates with same subject. +new_certs_dir = $dir/newcerts # default place for new certs. + +certificate = $dir/cacert.pem # The CA certificate +serial = $dir/serial # The current serial number +crlnumber = $dir/crlnumber # the current crl number + # must be commented out to leave a V1 CRL +crl = $dir/crl.pem # The current CRL +private_key = $dir/private/cakey.pem # The private key +RANDFILE = $dir/private/.rand # private random number file + +x509_extensions = usr_cert # The extensions to add to the cert + +name_opt = ca_default # Subject Name options +cert_opt = ca_default # Certificate field options + +default_days = 36500 # how long to certify for +default_crl_days= 30 # how long before next CRL +default_md = default # use public key default MD +preserve = no # keep passed DN ordering + +policy = policy_match + +[ policy_match ] +countryName = match +stateOrProvinceName = match +organizationName = match +organizationalUnitName = optional +commonName = supplied +emailAddress = optional + +[ policy_anything ] +countryName = optional +stateOrProvinceName = optional +localityName = optional +organizationName = optional +organizationalUnitName = optional +commonName = supplied +emailAddress = optional + +#################################################################### +[ req ] +default_bits = 2048 +default_md = sm3 +default_keyfile = privkey.pem +distinguished_name = req_distinguished_name +x509_extensions = v3_ca # The extensions to add to the self signed cert + +string_mask = utf8only + +# req_extensions = v3_req # The extensions to add to a certificate request + +[ req_distinguished_name ] +countryName = CN +countryName_default = CN +stateOrProvinceName = State or Province Name (full name) +stateOrProvinceName_default =GuangDong +localityName = Locality Name (eg, city) +localityName_default = ShenZhen +organizationalUnitName = Organizational Unit Name (eg, section) +organizationalUnitName_default = fisco +commonName = Organizational commonName (eg, fisco) +commonName_default = fisco +commonName_max = 64 + +[ usr_cert ] +basicConstraints=CA:FALSE +nsComment = "OpenSSL Generated Certificate" + +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid,issuer + +[ v3_req ] + +# Extensions to add to a certificate request + +basicConstraints = CA:FALSE +keyUsage = nonRepudiation, digitalSignature + +[ v3enc_req ] + +# Extensions to add to a certificate request +basicConstraints = CA:FALSE +keyUsage = keyAgreement, keyEncipherment, dataEncipherment + +[ v3_agency_root ] +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid:always,issuer +basicConstraints = CA:true +keyUsage = cRLSign, keyCertSign + +[ v3_ca ] +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid:always,issuer +basicConstraints = CA:true +keyUsage = cRLSign, keyCertSign + +EOF +} + +generate_cert_conf() { + local output=$1 + cat <"${output}" +[ca] +default_ca=default_ca + +[default_ca] +default_days = 36500 +default_md = sha256 + +[req] +distinguished_name = req_distinguished_name +req_extensions = v3_req + +[req_distinguished_name] +countryName = CN +countryName_default = CN +stateOrProvinceName = State or Province Name (full name) +stateOrProvinceName_default =GuangDong +localityName = Locality Name (eg, city) +localityName_default = ShenZhen +organizationalUnitName = Organizational Unit Name (eg, section) +organizationalUnitName_default = WeDPR-PPC +commonName = Organizational commonName (eg, WeDPR-PPC) +commonName_default = WeDPR-PPC +commonName_max = 64 + +[ v3_req ] +basicConstraints = CA:FALSE +keyUsage = nonRepudiation, digitalSignature, keyEncipherment + +[ v4_req ] +basicConstraints = CA:FALSE + +EOF +} +print_result() { + echo "==============================================================" + LOG_INFO "${binary_name} path : ${binary_path}" + LOG_INFO "Start port : ${port_start[*]}" + LOG_INFO "Server IP : ${ip_array[*]}" + LOG_INFO "SM model : ${sm_mode}" + LOG_INFO "Output dir : ${output_dir}" + LOG_INFO "All completed. Files in ${output_dir}" +} + +help() { + echo $1 + cat < [Optional] the command, support 'deploy' and 'expand' now, default is deploy + -v [Optional] Default is the latest ${default_version} + -l [Required] "ip1:nodeNum1,ip2:nodeNum2" e.g:"192.168.0.1:2,192.168.0.2:3" + -e [Optional] ppc-air-node binary exec + -o [Optional] output directory, default ./nodes + -p [Optional] Default 40300,10200,18000 means p2p_port start from 40300, rpc_port from 10200, grpc_port from 18000 + -s [Optional] SM SSL connection or not, default is false + -d [Optional] Disable ra2018 psi or not, default is false + -h Help + +deploy nodes e.g + bash $0 -p 40300,10200 -l 127.0.0.1:4 -o ppc-nodes -e ./ppc-air-node + bash $0 -p 40300,10200 -l 127.0.0.1:4 -o ppc-nodes -e ./ppc-air-node -s +EOF + exit 0 +} + + +generate_p2p_connected_conf() { + local output="${1}" + local ip_params="${2}" + local template="${3}" + + local p2p_host_list="" + if [[ "${template}" == "true" ]]; then + p2p_host_list="${ip_params}" + else + local ip_array=(${ip_params//,/ }) + local ip_length=${#ip_array[@]} + + local i=0 + for (( ; i < ip_length; i++)); do + local ip=${ip_array[i]} + local delim="" + if [[ $i == $((ip_length - 1)) ]]; then + delim="" + else + delim="," + fi + p2p_host_list="${p2p_host_list}\"${ip}\"${delim}" + done + fi + + cat <"${output}" +{"nodes":[${p2p_host_list}]} +EOF +} + +# generate the config.ini +generate_node_config_ini() { + local output="${1}" + local gateway_listen_ip="${2}" + local gateway_listen_port="${3}" + + local rpc_listen_ip="${4}" + local rpc_listen_port="${5}" + + local grpc_listen_ip="${6}" + local grpc_listen_port="${7}" + + local agency_id="${8}" + local index="${9}" + local nodeid="${10}" + + cat <"${output}" +[agency] + ; the agency-id of self-party + id = ${agency_id} + ; the private-key for the psi-server + private_key_path = conf/node.pem + ; disable the ra2018 or not, default enable ra2018 + disable_ra2018 = ${disable_ra2018} + ; the path that allows programs to access + ; data_location = data + ; task_timeout_minutes = 180 + ; thread_count = 8 + ; GB, reject task if available memory is less than min_needed_memory + ; min_needed_memory = 1 + +[transport] + ; the endpoint information + listen_ip = ${grpc_listen_ip} + listen_port = ${grpc_listen_port} + host_ip = + ; the threadPoolSize + thread_count = 4 + ; the gatewayService endpoint information + gateway_target = + ; the components + components = + nodeid=${nodeid} + +[crypto] + sm_crypto = ${sm_mode} + +[gateway] + listen_ip=${gateway_listen_ip} + listen_port=${gateway_listen_port} + ;the dir that contains the connected endpoint information, e.g.nodes.json + ;nodes_path=${file_dir} + ; the file that configure the connected endpoint information + ; nodes_file=${p2p_connected_conf_name} + ; thread_count = 4 + ; ssl or sm ssl + sm_ssl=${sm_mode} + ; the max allowed message size in MBytes, default is 100MBytes + max_allow_msg_size = 100 + ;ssl connection switch, if disable the ssl connection, default: false + ;disable_ssl = true + ;the time of the gateway holding and waiting to dispatcher the unsynced task, in minutes + holding_msg_minutes = 30 + ;reconnect_time = 10000 + ; the unreachable distance + ;unreachable_distance=10 + +[rpc] + listen_ip=${rpc_listen_ip} + listen_port=${rpc_listen_port} + ; token = ppcs_psi_apikey + thread_count = 4 + ; ssl or sm ssl + sm_ssl=${sm_mode} + ; ssl connection switch, if disable the ssl connection, default: false + ;disable_ssl = true + ;disable_db = true + +[cert] + ; directory the certificates located in + cert_path=./conf + + +[storage] + host = 127.0.0.1 + ; the mysqlx_port + port = 3306 + user = app + password = + database = + +[hdfs_storage] + ; the hdfs configuration + user = root + name_node = 127.0.0.1 + name_node_port = 9000 + token = + ; enable replace-datanode-on-failure or not + replace-datanode-on-failure = false + ; the connection-timeout, in ms, default is 1000ms + connection-timeout = 1000 + ; enable auth or not, default is false + ; enable_krb5_auth = false + ; the hdfs kerberos auth principal, used when enable_krb5_auth + ; auth_principal = root@NODE.DC1.CONSUL + ; the hdfs kerberos auth password, used when enable_krb5_auth + ; auth_password = + ; the ccache path, used when enable_krb5_auth + ; ccache_path = /tmp/krb5cc_ppc_node + ; the krb5.conf path + ; krb5_conf_path = conf/krb5.conf + + +[ra2018psi] + ; The database used to store cuckoo-filter + database=ra2018_${index} + ; The capacity of the cuckoo filter in MB, the default is 1MB + cuckoofilter_capacity = 1 + ; The length of each element of the cuckoo filter (bits), default 64bits + cuckoofilter_tagBits = 64 + ; The number of buckets for the cuckoo filter, the default is 4 + cuckoofilter_buckets_num = 4 + ; When the cuckoo filter replaces an element, the maximum number of element replacements allowed + cuckoofilter_max_kick_out_count = 20 + ; The trash-bucket-size for the cuckoo-filter + trash_bucket_size = 10000 + ; The cuckoo filter capacity that can be cached in memory in MB + cuckoofilter_cache_size = 256 + ; Cache size in MB + psi_cache_size = 1024 + ; When reading large files, the line size loaded into memory each time, default is 100w, -1 means load the max-size-of data + ; data_batch_size = 1000000 + ; use hdfs to store the cuckoo-filter or not + use_hdfs = false + +[ecdh-psi] + ; When reading large files, the line size loaded into memory each time, default is 100w, -1 means load the max-size-of data + ; data_batch_size = 1000000 + +[cm2020-psi] + ; Number of tasks that can be executed concurrently + parallelism = 3 + +[log] + enable=true + log_path=./log + ; info debug trace + level=debug + ; MB + max_log_file_size=200 + ; LineID, TimeStamp, ProcessID, ThreadName, ThreadID and Message + ;format=%Severity%|ppcs-psi4ef|system-id|%TimeStamp%|%ThreadName%-%ThreadID%|%Message% + format=%Severity%|%TimeStamp%|%Message% + enable_rotate_by_hour=true + log_name_pattern=ppcs-psi4ef.log + ; Y,m,d,H,M,S are supported, N is the sequence number log_%Y%m%d.%H%M%S.%N.log + rotate_name_pattern=log_%Y%m%d.%H%M.log + ; if archive_path is empty, the archive function will be disabled + ; archive_path=./log/ + compress_archive_file=true + ; ; 0: no limit, in MB + ; max_archive_files=10 + ; ; 0: no limit, in MB + ; max_archive_size=0 + ; min_free_space=0 +EOF +} + +generate_krb5_file_template() +{ + local filepath=$1 + mkdir -p $(dirname $filepath) + cat << EOF > "${filepath}" +[libdefaults] + default_realm = NODE.DC1.CONSUL + dns_lookup_realm = false + dns_lookup_kdc = false + ticket_lifetime = 24h + renew_lifetime = 7d + forwardable = true + +[realms] + NODE.DC1.CONSUL = { + kdc = + admin_server = + } + +[domain_realm] + .node.dc1.consul = NODE.DC1.CONSUL + node.dc1.consul = NODE.DC1.CONSUL +EOF +} + +generate_script_template() +{ + local filepath=$1 + mkdir -p $(dirname $filepath) + cat << EOF > "${filepath}" +#!/bin/bash +SHELL_FOLDER=\$(cd \$(dirname \$0);pwd) + +LOG_ERROR() { + content=\${1} + echo -e "\033[31m[ERROR] \${content}\033[0m" +} + +LOG_INFO() { + content=\${1} + echo -e "\033[32m[INFO] \${content}\033[0m" +} + +EOF + chmod +x ${filepath} +} + +# TODO: support docker-mode +generate_node_scripts() { + local output=${1} + local ps_cmd="\$(ps aux|grep \${ppc_psi}|grep -v grep|awk '{print \$2}')" + local start_cmd="nohup \${ppc_psi} -c config.ini >>nohup.out 2>&1 &" + local stop_cmd="kill \${node_pid}" + local pid="pid" + local log_cmd="tail -n20 nohup.out" + local check_success="\$(${log_cmd} | grep running)" + generate_script_template "$output/start.sh" + cat <> "${output}/start.sh" +ppc_psi=\${SHELL_FOLDER}/../${binary_name} +cd \${SHELL_FOLDER} +node=\$(basename \${SHELL_FOLDER}) +node_pid=${ps_cmd} +if [ ! -z \${node_pid} ];then + echo " \${node} is running, ${pid} is \$node_pid." + exit 0 +else + ${start_cmd} + sleep 1.5 +fi +try_times=4 +i=0 +while [ \$i -lt \${try_times} ] +do + node_pid=${ps_cmd} + success_flag=${check_success} + if [[ ! -z \${node_pid} && ! -z "\${success_flag}" ]];then + echo -e "\033[32m \${node} start successfully pid=\${node_pid}\033[0m" + exit 0 + fi + sleep 0.5 + ((i=i+1)) +done +echo -e "\033[31m Exceed waiting time. Please try again to start \${node} \033[0m" +${log_cmd} +EOF + chmod u+x "${output}/start.sh" + generate_script_template "$output/stop.sh" + cat <> "${output}/stop.sh" +ppc_psi=\${SHELL_FOLDER}/../${binary_name} +node=\$(basename \${SHELL_FOLDER}) +node_pid=${ps_cmd} +try_times=10 +i=0 +if [ -z \${node_pid} ];then + echo " \${node} isn't running." + exit 0 +fi +[ ! -z \${node_pid} ] && ${stop_cmd} > /dev/null +while [ \$i -lt \${try_times} ] +do + sleep 1 + node_pid=${ps_cmd} + if [ -z \${node_pid} ];then + echo -e "\033[32m stop \${node} success.\033[0m" + exit 0 + fi + ((i=i+1)) +done +echo " Exceed maximum number of retries. Please try again to stop \${node}" +exit 1 +EOF + chmod u+x "${output}/stop.sh" +} + +generate_all_node_scripts() { + local output=${1} + mkdir -p ${output} + + cat <"${output}/start_all.sh" +#!/bin/bash +dirpath="\$(cd "\$(dirname "\$0")" && pwd)" +cd "\${dirpath}" + +dirs=(\$(ls -l \${dirpath} | awk '/^d/ {print \$NF}')) +for dir in \${dirs[*]} +do + if [[ -f "\${dirpath}/\${dir}/config.ini" && -f "\${dirpath}/\${dir}/start.sh" ]];then + echo "try to start \${dir}" + bash \${dirpath}/\${dir}/start.sh & + fi +done +wait +EOF + chmod u+x "${output}/start_all.sh" + + cat <"${output}/stop_all.sh" +#!/bin/bash +dirpath="\$(cd "\$(dirname "\$0")" && pwd)" +cd "\${dirpath}" + +dirs=(\$(ls -l \${dirpath} | awk '/^d/ {print \$NF}')) +for dir in \${dirs[*]} +do + if [[ -f "\${dirpath}/\${dir}/config.ini" && -f "\${dirpath}/\${dir}/stop.sh" ]];then + echo "try to stop \${dir}" + bash \${dirpath}/\${dir}/stop.sh + fi +done +wait +EOF + chmod u+x "${output}/stop_all.sh" +} + +gen_non_sm_ca_cert() { + if [ ! -f "${cert_conf}" ]; then + generate_cert_conf "${cert_conf}" + fi + local ca_cert_dir="${1}" + file_must_not_exists "${ca_cert_dir}"/ca.key + file_must_not_exists "${ca_cert_dir}"/ca.crt + file_must_exists "${cert_conf}" + + mkdir -p "$ca_cert_dir" + dir_must_exists "$ca_cert_dir" + + ${OPENSSL_CMD} genrsa -out "${ca_cert_dir}"/ca.key "${rsa_key_length}" + ${OPENSSL_CMD} req -new -x509 -days "${days}" -subj "/CN=WeDPR-PPC/O=WeDPR-PPC/OU=chain" -key "${ca_cert_dir}"/ca.key -config "${cert_conf}" -out "${ca_cert_dir}"/ca.crt 2>/dev/null + if [ ! -f "${ca_cert_dir}/cert.cnf" ];then + mv "${cert_conf}" "${ca_cert_dir}" + fi + LOG_INFO "Generate ca cert successfully!" +} + +gen_sm_ca_cert() { + local ca_cert_dir="${1}" + name=$(basename "$ca_cert_dir") + check_name chain "$name" + + if [ ! -f "${sm_cert_conf}" ]; then + generate_sm_cert_conf ${sm_cert_conf} + fi + + generate_sm_sm2_param "${sm2_params}" + + mkdir -p "$ca_cert_dir" + dir_must_exists "$ca_cert_dir" + + "$OPENSSL_CMD" genpkey -paramfile "${sm2_params}" -out "$ca_cert_dir/sm_ca.key" 2>/dev/null + "$OPENSSL_CMD" req -config sm_cert.cnf -x509 -days "${days}" -subj "/CN=WeDPR-PPC/O=WeDPR-PPC/OU=ca" -key "$ca_cert_dir/sm_ca.key" -extensions v3_ca -out "$ca_cert_dir/sm_ca.crt" 2>/dev/null + if [ ! -f "${ca_cert_dir}/${sm_cert_conf}" ];then + cp "${sm_cert_conf}" "${ca_cert_dir}" + fi + if [ ! -f "${ca_cert_dir}/${sm2_params}" ];then + cp "${sm2_params}" "${ca_cert_dir}" + fi +} + + +gen_rsa_node_cert() { + local capath="${1}" + local ndpath="${2}" + local type="${3}" + + file_must_exists "$capath/ca.key" + file_must_exists "$capath/ca.crt" + # check_name node "$node" + + file_must_not_exists "$ndpath"/"${type}".key + file_must_not_exists "$ndpath"/"${type}".crt + + mkdir -p "${ndpath}" + dir_must_exists "${ndpath}" + + ${OPENSSL_CMD} genrsa -out "${ndpath}"/"${type}".key "${rsa_key_length}" 2>/dev/null + ${OPENSSL_CMD} req -new -sha256 -subj "/CN=WeDPR-PPC/O=WeDPR-PPC/OU=agency" -key "$ndpath"/"${type}".key -config "$capath"/cert.cnf -out "$ndpath"/"${type}".csr + ${OPENSSL_CMD} x509 -req -days "${days}" -sha256 -CA "${capath}"/ca.crt -CAkey "$capath"/ca.key -CAcreateserial \ + -in "$ndpath"/"${type}".csr -out "$ndpath"/"${type}".crt -extensions v4_req -extfile "$capath"/cert.cnf 2>/dev/null + + ${OPENSSL_CMD} pkcs8 -topk8 -in "$ndpath"/"${type}".key -out "$ndpath"/pkcs8_node.key -nocrypt + cp "$capath"/ca.crt "$capath"/cert.cnf "$ndpath"/ + + rm -f "$ndpath"/"$type".csr + rm -f "$ndpath"/"$type".key + + mv "$ndpath"/pkcs8_node.key "$ndpath"/"$type".key + + LOG_INFO "Generate ${ndpath} cert successful!" +} + +gen_sm_node_cert_with_ext() { + local capath="$1" + local certpath="$2" + local type="$3" + local extensions="$4" + + file_must_exists "$capath/sm_ca.key" + file_must_exists "$capath/sm_ca.crt" + + file_must_not_exists "$ndpath/sm_${type}.crt" + file_must_not_exists "$ndpath/sm_${type}.key" + + "$OPENSSL_CMD" genpkey -paramfile "$capath/${sm2_params}" -out "$certpath/sm_${type}.key" 2> /dev/null + "$OPENSSL_CMD" req -new -subj "/CN=WeDPR-PPC/O=WeDPR-PPC/OU=${type}" -key "$certpath/sm_${type}.key" -config "$capath/sm_cert.cnf" -out "$certpath/sm_${type}.csr" 2> /dev/null + + "$OPENSSL_CMD" x509 -sm3 -req -CA "$capath/sm_ca.crt" -CAkey "$capath/sm_ca.key" -days "${days}" -CAcreateserial -in "$certpath/sm_${type}.csr" -out "$certpath/sm_${type}.crt" -extfile "$capath/sm_cert.cnf" -extensions "$extensions" 2> /dev/null + + rm -f "$certpath/sm_${type}.csr" +} + +gen_sm_node_cert() { + local capath="${1}" + local ndpath="${2}" + local type="${3}" + + file_must_exists "$capath/sm_ca.key" + file_must_exists "$capath/sm_ca.crt" + + mkdir -p "$ndpath" + dir_must_exists "$ndpath" + local node=$(basename "$ndpath") + check_name node "$node" + + gen_sm_node_cert_with_ext "$capath" "$ndpath" "${type}" v3_req + gen_sm_node_cert_with_ext "$capath" "$ndpath" "en${type}" v3enc_req + #nodeid is pubkey + $OPENSSL_CMD ec -in "$ndpath/sm_${type}.key" -text -noout 2> /dev/null | sed -n '7,11p' | sed 's/://g' | tr "\n" " " | sed 's/ //g' | awk '{print substr($0,3);}' | cat > "${ndpath}/sm_${type}.nodeid" + cp "$capath/sm_ca.crt" "$ndpath" +} + +generate_ca_cert() { + local sm_mode="$1" + local ca_cert_path="$2" + LOG_INFO "generate ca cert, sm: ${sm_mode}, ca_cert_path: ${ca_cert_path}" + mkdir -p "${ca_cert_path}" + if [[ "${sm_mode}" == "false" ]]; then + gen_non_sm_ca_cert "${ca_cert_path}" + else + gen_sm_ca_cert "${ca_cert_path}" + fi + LOG_INFO "generate ca cert successfully, sm: ${sm_mode}, ca_cert_path: ${ca_cert_path}" +} + +generate_node_cert() { + local sm_mode="$1" + local ca_cert_path="${2}" + local node_cert_path="${3}" + + mkdir -p ${node_cert_path} + if [[ "${sm_mode}" == "false" ]]; then + gen_rsa_node_cert "${ca_cert_path}" "${node_cert_path}" "ssl" 2>&1 + else + gen_sm_node_cert "${ca_cert_path}" "${node_cert_path}" "ssl" 2>&1 + fi +} + +# we use sm_param to generate the private key +generate_private_key() { + local output_path="${1}" + if [ ! -d "${output_path}" ]; then + mkdir -p ${output_path} + fi + if [ ! -f ${sm2_params} ]; then + generate_sm_sm2_param ${sm2_params} + fi + ${OPENSSL_CMD} genpkey -paramfile ${sm2_params} -out ${output_path}/node.pem 2>/dev/null + $OPENSSL_CMD ec -in "$output_path/node.pem" -text -noout 2> /dev/null | sed -n '3,5p' | sed 's/://g' | tr "\n" " " | sed 's/ //g' | cat > "$output_path/node.privateKey" + ${OPENSSL_CMD} ec -text -noout -in "${output_path}/node.pem" 2>/dev/null | sed -n '7,11p' | tr -d ": \n" | awk '{print substr($0,3);}' | cat >"$output_path"/node.nodeid + private_key=$(cat $output_path/node.privateKey) + echo ${private_key} +} + +deploy_nodes() +{ + dir_must_not_exists "${output_dir}" + mkdir -p "$output_dir" + dir_must_exists "${output_dir}" + gateway_listen_port=port_start[0] + rpc_listen_port=port_start[1] + + # check the binary + if [[ ! -f "$binary_path" ]]; then + LOG_FATAL "wedpr-component binary exec ${binary_path} not exist, Must copy binary file ${binary_name} to ${binary_path}" + fi + + # parse the ip + [ -z $use_ip_param ] && help 'ERROR: Please set -l or -f option.' + if [ "${use_ip_param}" == "true" ]; then + ip_array=(${ip_param//,/ }) + elif [ "${use_ip_param}" == "false" ]; then + if ! parse_ip_config $ip_file; then + exit_with_clean "Parse $ip_file error!" + fi + else + help + fi + + local agency_index=0 + # generate the ca-cert + ca_dir="${output_dir}"/ca + generate_ca_cert "${sm_mode}" "${ca_dir}" + connected_nodes="" + for line in ${ip_array[*]}; do + ip=${line%:*} + num=${line#*:} + if [ -z $(echo $ip | grep -E "^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$") ]; then + LOG_WARN "Please check IP address: ${ip}, if you use domain name please ignore this." + fi + # echo $num + [ "$num" == "$ip" ] || [ -z "${num}" ] && num=${node_num} + echo "Processing IP:${ip} Total:${num}" + [ -z "$(get_value ${ip//./}_count)" ] && set_value ${ip//./}_count 0 + + nodes_dir="${output_dir}/${ip}" + # start_all.sh and stop_all.sh + generate_all_node_scripts "${nodes_dir}" + cp "${binary_path}" "${nodes_dir}" + # generate cert for the node + ca_cert_dir="${nodes_dir}"/ca + mkdir -p ${ca_cert_dir} + cp -r ${ca_dir}/* ${ca_cert_dir} + + # generate the node config + for ((i = 0; i < num; ++i)); do + local node_count=$(get_value ${ip//./}_count) + node_dir="${output_dir}/${ip}/node${node_count}" + mkdir -p "${node_dir}" + # generate the node-cert + generate_node_cert "${sm_mode}" "${ca_dir}" "${node_dir}/conf" + # generate the node-script + generate_node_scripts "${node_dir}" + local port=$((gateway_listen_port + node_count)) + connected_nodes=${connected_nodes}"${ip}:${port}, " + ((agency_index += 1)) + set_value ${ip//./}_count $(($(get_value ${ip//./}_count) + 1)) + ((++count)) + ((++node_count)) + done + done + # generate the config.ini + local i=0 + local count=0 + for line in ${ip_array[*]}; do + ip=${line%:*} + num=${line#*:} + if [ -z $(echo $ip | grep -E "^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$") ]; then + LOG_WARN "Please check IP address: ${ip}, if you use domain name please ignore this." + fi + [ "$num" == "$ip" ] || [ -z "${num}" ] && num=${node_num} + set_value ${ip//./}_count 0 + for ((i = 0; i < num; ++i)); do + local node_count=$(get_value ${ip//./}_count) + node_dir="${output_dir}/${ip}/node${node_count}" + local gateway_port=$((gateway_listen_port + node_count)) + local rpc_port=$((rpc_listen_port + node_count)) + local grpc_port=$((grpc_listen_port + node_count)) + local agency_id="agency${count}" + private_key=$(generate_private_key "${node_dir}/conf") + node_id=$(cat "${node_dir}/conf/node.nodeid") + generate_node_config_ini "${node_dir}/config.ini" "${listen_ip}" "${gateway_port}" "${listen_ip}" "${rpc_port}" "${listen_ip}" "${grpc_port}" ${agency_id} "${count}" "${node_id}" + generate_krb5_file_template "${node_dir}/conf/krb5.conf" + generate_p2p_connected_conf "${node_dir}/${p2p_connected_conf_name}" "${connected_nodes}" "false" + set_value ${ip//./}_count $(($(get_value ${ip//./}_count) + 1)) + ((++count)) + done + done + print_result +} + +parse_params() { + while getopts "l:C:o:e:p:v:sdh" option; do + case $option in + l) + ip_param=$OPTARG + use_ip_param="true" + ;; + o) + output_dir="$OPTARG" + ;; + e) + binary_path="$OPTARG" + file_must_exists "${binary_path}" + ;; + C) command="${OPTARG}" + ;; + p) + port_start=(${OPTARG//,/ }) + if [ ${#port_start[@]} -ne 2 ]; then LOG_WARN "p2p start port error. e.g: 30300" && exit 1; fi + ;; + s) sm_mode="true" ;; + d) disable_ra2018="true" ;; + v) compatibility_version="${OPTARG}";; + h) help ;; + *) help ;; + esac + done +} + +main() { + check_env + check_and_install_tassl + parse_params "$@" + cert_conf="${output_dir}/cert.cnf" + # TODO: support node-expand + if [[ "${command}" == "deploy" ]]; then + deploy_nodes + else + LOG_FATAL "Unsupported command ${command}, only support \'deploy\' and \'expand\' now!" + fi +} +main "$@" diff --git a/cpp/tools/build_wedpr_cem.sh b/cpp/tools/build_wedpr_cem.sh new file mode 100644 index 00000000..8299c61e --- /dev/null +++ b/cpp/tools/build_wedpr_cem.sh @@ -0,0 +1,738 @@ +#!/bin/bash + +dirpath="$(cd "$(dirname "$0")" && pwd)" +binary_name="wedpr-cem" +binary_path= +output_dir="wedpr-cem-node" + +listen_ip="0.0.0.0" + +cdn_link_header="https://osp-1257653870.cos.ap-guangzhou.myqcloud.com/FISCO-BCOS" +OPENSSL_CMD="${HOME}/.fisco/tassl-1.1.1b" + +ca_dir="" +cert_conf="" +sm_cert_conf='sm_cert.cnf' +sm2_params="sm_sm2.param" +sm_mode="false" +days=36500 +rsa_key_length=2048 + +default_version="v1.1.0" +compatibility_version=${default_version} +command="deploy" + + +LOG_WARN() { + local content=${1} + echo -e "\033[31m[ERROR] ${content}\033[0m" +} + +LOG_INFO() { + local content=${1} + echo -e "\033[32m[INFO] ${content}\033[0m" +} + +LOG_FATAL() { + local content=${1} + echo -e "\033[31m[FATAL] ${content}\033[0m" + exit 1 +} + +dir_must_exists() { + if [ ! -d "$1" ]; then + LOG_FATAL "$1 DIR does not exist, please check!" + fi +} + +get_value() { + local var_name=${1} + var_name=var_${var_name//./} + local res=$(eval echo '$'"${var_name}") + echo ${res} +} + +set_value() { + local var_name=${1} + var_name=var_${var_name//./} + local var_value=${2} + eval "${var_name}=${var_value}" +} + +dir_must_not_exists() { + if [ -d "$1" ]; then + LOG_FATAL "$1 DIR already exist, please check!" + fi +} + +file_must_not_exists() { + if [ -f "$1" ]; then + LOG_FATAL "$1 file already exist, please check!" + fi +} + +file_must_exists() { + if [ ! -f "$1" ]; then + LOG_FATAL "$1 file does not exist, please check!" + fi +} + +check_env() { + if [ "$(uname)" == "Darwin" ];then + macOS="macOS" + fi + if [ "$(uname -m)" != "x86_64" ];then + x86_64_arch="false" + fi +} +check_name() { + local name="$1" + local value="$2" + [[ "$value" =~ ^[a-zA-Z0-9._-]+$ ]] || { + LOG_FATAL "$name name [$value] invalid, it should match regex: ^[a-zA-Z0-9._-]+\$" + } +} +check_and_install_tassl(){ + if [ -f "${OPENSSL_CMD}" ];then + return + fi + # https://en.wikipedia.org/wiki/Uname#Examples + local x86_64_name="x86_64" + local arm_name="aarch64" + local tassl_mid_name="linux" + if [[ -n "${macOS}" ]];then + x86_64_name="x86_64" + arm_name="arm64" + tassl_mid_name="macOS" + fi + + local tassl_post_fix="x86_64" + local platform="$(uname -m)" + if [[ "${platform}" == "${arm_name}" ]];then + tassl_post_fix="aarch64" + elif [[ "${platform}" == "${x86_64_name}" ]];then + tassl_post_fix="x86_64" + else + LOG_FATAL "Unsupported platform ${platform} for ${tassl_mid_name}" + exit 1 + fi + local tassl_package_name="tassl-1.1.1b-${tassl_mid_name}-${tassl_post_fix}" + local tassl_tgz_name="${tassl_package_name}.tar.gz" + local tassl_link_prefix="${cdn_link_header}/FISCO-BCOS/tools/tassl-1.1.1b/${tassl_tgz_name}" + LOG_INFO "Downloading tassl binary from ${tassl_link_prefix}..." + wget --no-check-certificate "${tassl_link_prefix}" + tar zxvf ${tassl_tgz_name} && rm ${tassl_tgz_name} + chmod u+x ${tassl_package_name} + mkdir -p "${HOME}"/.fisco + mv ${tassl_package_name} "${HOME}"/.fisco/tassl-1.1.1b +} + + +generate_sm_sm2_param() { + local output=$1 + cat << EOF > ${output} +-----BEGIN EC PARAMETERS----- +BggqgRzPVQGCLQ== +-----END EC PARAMETERS----- + +EOF +} + +generate_sm_cert_conf() { + local output=$1 + cat <"${output}" +oid_section = new_oids + +[ new_oids ] +tsa_policy1 = 1.2.3.4.1 +tsa_policy2 = 1.2.3.4.5.6 +tsa_policy3 = 1.2.3.4.5.7 + +#################################################################### +[ ca ] +default_ca = CA_default # The default ca section + +#################################################################### +[ CA_default ] + +dir = ./demoCA # Where everything is kept +certs = $dir/certs # Where the issued certs are kept +crl_dir = $dir/crl # Where the issued crl are kept +database = $dir/index.txt # database index file. +#unique_subject = no # Set to 'no' to allow creation of + # several ctificates with same subject. +new_certs_dir = $dir/newcerts # default place for new certs. + +certificate = $dir/cacert.pem # The CA certificate +serial = $dir/serial # The current serial number +crlnumber = $dir/crlnumber # the current crl number + # must be commented out to leave a V1 CRL +crl = $dir/crl.pem # The current CRL +private_key = $dir/private/cakey.pem # The private key +RANDFILE = $dir/private/.rand # private random number file + +x509_extensions = usr_cert # The extensions to add to the cert + +name_opt = ca_default # Subject Name options +cert_opt = ca_default # Certificate field options + +default_days = 36500 # how long to certify for +default_crl_days= 30 # how long before next CRL +default_md = default # use public key default MD +preserve = no # keep passed DN ordering + +policy = policy_match + +[ policy_match ] +countryName = match +stateOrProvinceName = match +organizationName = match +organizationalUnitName = optional +commonName = supplied +emailAddress = optional + +[ policy_anything ] +countryName = optional +stateOrProvinceName = optional +localityName = optional +organizationName = optional +organizationalUnitName = optional +commonName = supplied +emailAddress = optional + +#################################################################### +[ req ] +default_bits = 2048 +default_md = sm3 +default_keyfile = privkey.pem +distinguished_name = req_distinguished_name +x509_extensions = v3_ca # The extensions to add to the self signed cert + +string_mask = utf8only + +# req_extensions = v3_req # The extensions to add to a certificate request + +[ req_distinguished_name ] +countryName = CN +countryName_default = CN +stateOrProvinceName = State or Province Name (full name) +stateOrProvinceName_default =GuangDong +localityName = Locality Name (eg, city) +localityName_default = ShenZhen +organizationalUnitName = Organizational Unit Name (eg, section) +organizationalUnitName_default = fisco +commonName = Organizational commonName (eg, fisco) +commonName_default = fisco +commonName_max = 64 + +[ usr_cert ] +basicConstraints=CA:FALSE +nsComment = "OpenSSL Generated Certificate" + +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid,issuer + +[ v3_req ] + +# Extensions to add to a certificate request + +basicConstraints = CA:FALSE +keyUsage = nonRepudiation, digitalSignature + +[ v3enc_req ] + +# Extensions to add to a certificate request +basicConstraints = CA:FALSE +keyUsage = keyAgreement, keyEncipherment, dataEncipherment + +[ v3_agency_root ] +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid:always,issuer +basicConstraints = CA:true +keyUsage = cRLSign, keyCertSign + +[ v3_ca ] +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid:always,issuer +basicConstraints = CA:true +keyUsage = cRLSign, keyCertSign + +EOF +} + +generate_cert_conf() { + local output=$1 + cat <"${output}" +[ca] +default_ca=default_ca +[default_ca] +default_days = 36500 +default_md = sha256 + +[req] +distinguished_name = req_distinguished_name +req_extensions = v3_req +[req_distinguished_name] +countryName = CN +countryName_default = CN +stateOrProvinceName = State or Province Name (full name) +stateOrProvinceName_default =GuangDong +localityName = Locality Name (eg, city) +localityName_default = ShenZhen +organizationalUnitName = Organizational Unit Name (eg, section) +organizationalUnitName_default = FISCO-BCOS +commonName = Organizational commonName (eg, FISCO-BCOS) +commonName_default = FISCO-BCOS +commonName_max = 64 + +[ v3_req ] +basicConstraints = CA:FALSE +keyUsage = nonRepudiation, digitalSignature, keyEncipherment + +[ v4_req ] +basicConstraints = CA:TRUE + +EOF +} +print_result() { + echo "==============================================================" + LOG_INFO "${binary_name} path : ${binary_path}" + LOG_INFO "SM model : ${sm_mode}" + LOG_INFO "Output dir : ${output_dir}" + LOG_INFO "All completed. Files in ${output_dir}" +} + +help() { + echo $1 + cat < [Optional] wedpr-cem binary exec + -o [Optional] output directory, default ./nodes + -s [Optional] SM SSL connection or not, default is false + -h Help + +deploy nodes e.g + bash $0 -o wedpr-cem-node -e ./wedpr-cem + bash $0 -o wedpr-cem-node -e ./wedpr-cem -s +EOF + exit 0 +} + +# generate the config.ini +generate_config_ini() { + local output="${1}" + + local rpc_listen_ip="${2}" + local rpc_listen_port="${3}" + local agency_info="${4}" + local agency_id="${5}" + + cat <"${output}" +[agency] + ; the agency-id of self-party + id = ${agency_id} + ; the agency info + +[cem] + dataset_hdfs_path = /user/ppc/ + dataset_file_path = ../../../ppc-cem/tests/data + ciphertext_suffix = -encrypted + read_per_batch_lines = 100000 + +[crypto] + sm_crypto = ${sm_mode} + +[rpc] + listen_ip=${rpc_listen_ip} + listen_port=${rpc_listen_port} + token = ppcs_psi_apikey + thread_count=4 + ; ssl or sm ssl + sm_ssl=${sm_mode} + ; ssl connection switch, if disable the ssl connection, default: false + ;disable_ssl = true + +[hdfs_storage] + ; the hdfs configuration + user = root + name_node = 127.0.0.1 + name_node_port = 9900 + token = + ; enable replace-datanode-on-failure or not + replace-datanode-on-failure = false + ; the connection-timeout, in ms, default is 1000ms + connection-timeout = 2000 + ; enable auth or not, default is false + ; enable_krb5_auth = false + ; the hdfs kerberos auth principal, used when enable_krb5_auth + ; auth_principal = root@NODE.DC1.CONSUL + ; the hdfs kerberos auth password, used when enable_krb5_auth + ; auth_password = + ; the ccache path, used when enable_krb5_auth + ; ccache_path = /tmp/krb5cc_ppc_node + ; the krb5.conf path + ; krb5_conf_path = conf/krb5.conf + +[cert] + ; directory the certificates located in + cert_path=./conf + +[log] + enable=true + log_path=./log + ; info debug trace + level=debug + ; MB + max_log_file_size=200 + ; LineID, TimeStamp, ProcessID, ThreadName, ThreadID and Message + ;format=%Severity%|ppcs-psi4ef|system-id|%TimeStamp%|%ThreadName%-%ThreadID%|%Message% + format=%Severity%|%TimeStamp%|%Message% + enable_rotate_by_hour=true + log_name_pattern=ppcs-psi4ef.log + ; Y,m,d,H,M,S are supported, N is the sequence number log_%Y%m%d.%H%M%S.%N.log + rotate_name_pattern=log_%Y%m%d.%H%M.log + ; if archive_path is empty, the archive function will be disabled + ; archive_path=./log/ + compress_archive_file=true + ; ; 0: no limit, in MB + ; max_archive_files=10 + ; ; 0: no limit, in MB + ; max_archive_size=0 + ; min_free_space=0 +EOF +} + +generate_script_template() +{ + local filepath=$1 + mkdir -p $(dirname $filepath) + cat << EOF > "${filepath}" +#!/bin/bash +SHELL_FOLDER=\$(cd \$(dirname \$0);pwd) + +LOG_ERROR() { + content=\${1} + echo -e "\033[31m[ERROR] \${content}\033[0m" +} + +LOG_INFO() { + content=\${1} + echo -e "\033[32m[INFO] \${content}\033[0m" +} + +EOF + chmod +x ${filepath} +} + +# TODO: support docker-mode +generate_node_scripts() { + local output=${1} + local ps_cmd="\$(ps aux|grep \${ppc_cem}|grep -v grep|awk '{print \$2}')" + local start_cmd="nohup \${ppc_cem} -c config.ini >>nohup.out 2>&1 &" + local stop_cmd="kill \${node_pid}" + local pid="pid" + local log_cmd="tail -n20 nohup.out" + local check_success="\$(${log_cmd} | grep running)" + generate_script_template "$output/start.sh" + cat <> "${output}/start.sh" +ppc_cem=\${SHELL_FOLDER}/${binary_name} +cd \${SHELL_FOLDER} +node=\$(basename \${SHELL_FOLDER}) +node_pid=${ps_cmd} +if [ ! -z \${node_pid} ];then + echo " \${node} is running, ${pid} is \$node_pid." + exit 0 +else + ${start_cmd} + sleep 1.5 +fi +try_times=4 +i=0 +while [ \$i -lt \${try_times} ] +do + node_pid=${ps_cmd} + success_flag=${check_success} + if [[ ! -z \${node_pid} && ! -z "\${success_flag}" ]];then + echo -e "\033[32m \${node} start successfully pid=\${node_pid}\033[0m" + exit 0 + fi + sleep 0.5 + ((i=i+1)) +done +echo -e "\033[31m Exceed waiting time. Please try again to start \${node} \033[0m" +${log_cmd} +EOF + chmod u+x "${output}/start.sh" + generate_script_template "$output/stop.sh" + cat <> "${output}/stop.sh" +ppc_cem=\${SHELL_FOLDER}/${binary_name} +node=\$(basename \${SHELL_FOLDER}) +node_pid=${ps_cmd} +try_times=10 +i=0 +if [ -z \${node_pid} ];then + echo " \${node} isn't running." + exit 0 +fi +[ ! -z \${node_pid} ] && ${stop_cmd} > /dev/null +while [ \$i -lt \${try_times} ] +do + sleep 1 + node_pid=${ps_cmd} + if [ -z \${node_pid} ];then + echo -e "\033[32m stop \${node} success.\033[0m" + exit 0 + fi + ((i=i+1)) +done +echo " Exceed maximum number of retries. Please try again to stop \${node}" +exit 1 +EOF + chmod u+x "${output}/stop.sh" +} + +generate_all_node_scripts() { + local output=${1} + mkdir -p ${output} + + cat <"${output}/start_all.sh" +#!/bin/bash +dirpath="\$(cd "\$(dirname "\$0")" && pwd)" +cd "\${dirpath}" + +dirs=(\$(ls -l \${dirpath} | awk '/^d/ {print \$NF}')) +for dir in \${dirs[*]} +do + if [[ -f "\${dirpath}/\${dir}/config.ini" && -f "\${dirpath}/\${dir}/start.sh" ]];then + echo "try to start \${dir}" + bash \${dirpath}/\${dir}/start.sh & + fi +done +wait +EOF + chmod u+x "${output}/start_all.sh" + + cat <"${output}/stop_all.sh" +#!/bin/bash +dirpath="\$(cd "\$(dirname "\$0")" && pwd)" +cd "\${dirpath}" + +dirs=(\$(ls -l \${dirpath} | awk '/^d/ {print \$NF}')) +for dir in \${dirs[*]} +do + if [[ -f "\${dirpath}/\${dir}/config.ini" && -f "\${dirpath}/\${dir}/stop.sh" ]];then + echo "try to stop \${dir}" + bash \${dirpath}/\${dir}/stop.sh + fi +done +wait +EOF + chmod u+x "${output}/stop_all.sh" +} + +gen_non_sm_ca_cert() { + if [ ! -f "${cert_conf}" ]; then + generate_cert_conf "${cert_conf}" + fi + local ca_cert_dir="${1}" + file_must_not_exists "${ca_cert_dir}"/ca.key + file_must_not_exists "${ca_cert_dir}"/ca.crt + file_must_exists "${cert_conf}" + + mkdir -p "$ca_cert_dir" + dir_must_exists "$ca_cert_dir" + + ${OPENSSL_CMD} genrsa -out "${ca_cert_dir}"/ca.key "${rsa_key_length}" + ${OPENSSL_CMD} req -new -x509 -days "${days}" -subj "/CN=FISCO-BCOS/O=FISCO-BCOS/OU=chain" -key "${ca_cert_dir}"/ca.key -config "${cert_conf}" -out "${ca_cert_dir}"/ca.crt 2>/dev/null + if [ ! -f "${ca_cert_dir}/cert.cnf" ];then + mv "${cert_conf}" "${ca_cert_dir}" + fi + LOG_INFO "Generate ca cert successfully!" +} + +gen_sm_ca_cert() { + local ca_cert_dir="${1}" + name=$(basename "$ca_cert_dir") + check_name chain "$name" + + if [ ! -f "${sm_cert_conf}" ]; then + generate_sm_cert_conf ${sm_cert_conf} + fi + + generate_sm_sm2_param "${sm2_params}" + + mkdir -p "$ca_cert_dir" + dir_must_exists "$ca_cert_dir" + + "$OPENSSL_CMD" genpkey -paramfile "${sm2_params}" -out "$ca_cert_dir/sm_ca.key" 2>/dev/null + "$OPENSSL_CMD" req -config sm_cert.cnf -x509 -days "${days}" -subj "/CN=wedpr/O=wedpr/OU=ca" -key "$ca_cert_dir/sm_ca.key" -extensions v3_ca -out "$ca_cert_dir/sm_ca.crt" 2>/dev/null + if [ ! -f "${ca_cert_dir}/${sm_cert_conf}" ];then + cp "${sm_cert_conf}" "${ca_cert_dir}" + fi + if [ ! -f "${ca_cert_dir}/${sm2_params}" ];then + cp "${sm2_params}" "${ca_cert_dir}" + fi +} + + +gen_rsa_node_cert() { + local capath="${1}" + local ndpath="${2}" + local type="${3}" + + file_must_exists "$capath/ca.key" + file_must_exists "$capath/ca.crt" + # check_name node "$node" + + file_must_not_exists "$ndpath"/"${type}".key + file_must_not_exists "$ndpath"/"${type}".crt + + mkdir -p "${ndpath}" + dir_must_exists "${ndpath}" + + ${OPENSSL_CMD} genrsa -out "${ndpath}"/"${type}".key "${rsa_key_length}" 2>/dev/null + ${OPENSSL_CMD} req -new -sha256 -subj "/CN=FISCO-BCOS/O=fisco-bcos/OU=agency" -key "$ndpath"/"${type}".key -config "$capath"/cert.cnf -out "$ndpath"/"${type}".csr + ${OPENSSL_CMD} x509 -req -days "${days}" -sha256 -CA "${capath}"/ca.crt -CAkey "$capath"/ca.key -CAcreateserial \ + -in "$ndpath"/"${type}".csr -out "$ndpath"/"${type}".crt -extensions v4_req -extfile "$capath"/cert.cnf 2>/dev/null + + ${OPENSSL_CMD} pkcs8 -topk8 -in "$ndpath"/"${type}".key -out "$ndpath"/pkcs8_node.key -nocrypt + cp "$capath"/ca.crt "$capath"/cert.cnf "$ndpath"/ + + rm -f "$ndpath"/"$type".csr + rm -f "$ndpath"/"$type".key + + mv "$ndpath"/pkcs8_node.key "$ndpath"/"$type".key + + LOG_INFO "Generate ${ndpath} cert successful!" +} + +gen_sm_node_cert_with_ext() { + local capath="$1" + local certpath="$2" + local type="$3" + local extensions="$4" + + file_must_exists "$capath/sm_ca.key" + file_must_exists "$capath/sm_ca.crt" + + file_must_not_exists "$ndpath/sm_${type}.crt" + file_must_not_exists "$ndpath/sm_${type}.key" + + "$OPENSSL_CMD" genpkey -paramfile "$capath/${sm2_params}" -out "$certpath/sm_${type}.key" 2> /dev/null + "$OPENSSL_CMD" req -new -subj "/CN=FISCO-BCOS/O=fisco-bcos/OU=${type}" -key "$certpath/sm_${type}.key" -config "$capath/sm_cert.cnf" -out "$certpath/sm_${type}.csr" 2> /dev/null + + "$OPENSSL_CMD" x509 -sm3 -req -CA "$capath/sm_ca.crt" -CAkey "$capath/sm_ca.key" -days "${days}" -CAcreateserial -in "$certpath/sm_${type}.csr" -out "$certpath/sm_${type}.crt" -extfile "$capath/sm_cert.cnf" -extensions "$extensions" 2> /dev/null + + rm -f "$certpath/sm_${type}.csr" +} + +gen_sm_node_cert() { + local capath="${1}" + local ndpath="${2}" + local type="${3}" + + file_must_exists "$capath/sm_ca.key" + file_must_exists "$capath/sm_ca.crt" + + mkdir -p "$ndpath" + dir_must_exists "$ndpath" + local node=$(basename "$ndpath") + check_name node "$node" + + gen_sm_node_cert_with_ext "$capath" "$ndpath" "${type}" v3_req + gen_sm_node_cert_with_ext "$capath" "$ndpath" "en${type}" v3enc_req + #nodeid is pubkey + $OPENSSL_CMD ec -in "$ndpath/sm_${type}.key" -text -noout 2> /dev/null | sed -n '7,11p' | sed 's/://g' | tr "\n" " " | sed 's/ //g' | awk '{print substr($0,3);}' | cat > "${ndpath}/sm_${type}.nodeid" + cp "$capath/sm_ca.crt" "$ndpath" +} + +generate_ca_cert() { + local sm_mode="$1" + local ca_cert_path="$2" + LOG_INFO "generate ca cert, sm: ${sm_mode}, ca_cert_path: ${ca_cert_path}" + mkdir -p "${ca_cert_path}" + if [[ "${sm_mode}" == "false" ]]; then + gen_non_sm_ca_cert "${ca_cert_path}" + else + gen_sm_ca_cert "${ca_cert_path}" + fi + LOG_INFO "generate ca cert successfully, sm: ${sm_mode}, ca_cert_path: ${ca_cert_path}" +} + +generate_node_cert() { + local sm_mode="$1" + local ca_cert_path="${2}" + local node_cert_path="${3}" + + mkdir -p ${node_cert_path} + if [[ "${sm_mode}" == "false" ]]; then + gen_rsa_node_cert "${ca_cert_path}" "${node_cert_path}" "ssl" 2>&1 + else + gen_sm_node_cert "${ca_cert_path}" "${node_cert_path}" "ssl" 2>&1 + fi +} + + +deploy_nodes() +{ + echo "output_dir:${output_dir}" + dir_must_not_exists "${output_dir}" + mkdir -p "$output_dir" + dir_must_exists "${output_dir}" + + # check the binary + if [[ ! -f "$binary_path" ]]; then + LOG_FATAL "wedpr-component binary exec ${binary_path} not exist, Must copy binary file ${binary_name} to ${binary_path}" + fi + + local agency_index=0 + local agency_info="" + # generate the ca-cert + ca_dir="${output_dir}"/ca + cert_conf="${output_dir}/cert.cnf" + generate_ca_cert "${sm_mode}" "${ca_dir}" + # start_all.sh and stop_all.sh + # generate_all_node_scripts "${output_dir}" + cp "${binary_path}" "${output_dir}" + # generate cert for the node + ca_cert_dir="${output_dir}"/ca + mkdir -p ${ca_cert_dir} + # cp -r ${ca_dir}/* ${ca_cert_dir} + + # generate the node config + mkdir -p "${output_dir}" + # generate the node-cert + generate_node_cert "${sm_mode}" "${ca_dir}" "${output_dir}/conf" + # generate the node-script + generate_node_scripts "${output_dir}" + # generate the config.ini + local rpc_port=5895 + local agency_id="agency${count}" + generate_config_ini "${output_dir}/config.ini" "${listen_ip}" "${rpc_port}" "${agency_info}" ${agency_id} + print_result +} + +parse_params() { + while getopts "o:e:sh" option; do + case $option in + o) + output_dir="$OPTARG" + ;; + e) + binary_path="$OPTARG" + file_must_exists "${binary_path}" + ;; + s) sm_mode="true" ;; + h) help ;; + *) help ;; + esac + done +} + +main() { + check_env + check_and_install_tassl + parse_params "$@" + deploy_nodes +} +main "$@" \ No newline at end of file diff --git a/cpp/tools/build_wedpr_mpc.sh b/cpp/tools/build_wedpr_mpc.sh new file mode 100644 index 00000000..c3d109dd --- /dev/null +++ b/cpp/tools/build_wedpr_mpc.sh @@ -0,0 +1,788 @@ +#!/bin/bash + +dirpath="$(cd "$(dirname "$0")" && pwd)" +binary_name="wedpr-mpc" +binary_path= +output_dir="wedpr-mpc-node" + +listen_ip="0.0.0.0" + +cdn_link_header="https://osp-1257653870.cos.ap-guangzhou.myqcloud.com/FISCO-BCOS" +OPENSSL_CMD="${HOME}/.fisco/tassl-1.1.1b" + +ca_dir="" +cert_conf="" +sm_cert_conf='sm_cert.cnf' +sm2_params="sm_sm2.param" +sm_mode="false" +days=36500 +rsa_key_length=2048 + +default_version="v1.1.0" +compatibility_version=${default_version} +command="deploy" + + +LOG_WARN() { + local content=${1} + echo -e "\033[31m[ERROR] ${content}\033[0m" +} + +LOG_INFO() { + local content=${1} + echo -e "\033[32m[INFO] ${content}\033[0m" +} + +LOG_FATAL() { + local content=${1} + echo -e "\033[31m[FATAL] ${content}\033[0m" + exit 1 +} + +dir_must_exists() { + if [ ! -d "$1" ]; then + LOG_FATAL "$1 DIR does not exist, please check!" + fi +} + +get_value() { + local var_name=${1} + var_name=var_${var_name//./} + local res=$(eval echo '$'"${var_name}") + echo ${res} +} + +set_value() { + local var_name=${1} + var_name=var_${var_name//./} + local var_value=${2} + eval "${var_name}=${var_value}" +} + +dir_must_not_exists() { + if [ -d "$1" ]; then + LOG_FATAL "$1 DIR already exist, please check!" + fi +} + +file_must_not_exists() { + if [ -f "$1" ]; then + LOG_FATAL "$1 file already exist, please check!" + fi +} + +file_must_exists() { + if [ ! -f "$1" ]; then + LOG_FATAL "$1 file does not exist, please check!" + fi +} + +check_env() { + if [ "$(uname)" == "Darwin" ];then + macOS="macOS" + fi + if [ "$(uname -m)" != "x86_64" ];then + x86_64_arch="false" + fi +} +check_name() { + local name="$1" + local value="$2" + [[ "$value" =~ ^[a-zA-Z0-9._-]+$ ]] || { + LOG_FATAL "$name name [$value] invalid, it should match regex: ^[a-zA-Z0-9._-]+\$" + } +} +check_and_install_tassl(){ + if [ -f "${OPENSSL_CMD}" ];then + return + fi + # https://en.wikipedia.org/wiki/Uname#Examples + local x86_64_name="x86_64" + local arm_name="aarch64" + local tassl_mid_name="linux" + if [[ -n "${macOS}" ]];then + x86_64_name="x86_64" + arm_name="arm64" + tassl_mid_name="macOS" + fi + + local tassl_post_fix="x86_64" + local platform="$(uname -m)" + if [[ "${platform}" == "${arm_name}" ]];then + tassl_post_fix="aarch64" + elif [[ "${platform}" == "${x86_64_name}" ]];then + tassl_post_fix="x86_64" + else + LOG_FATAL "Unsupported platform ${platform} for ${tassl_mid_name}" + exit 1 + fi + local tassl_package_name="tassl-1.1.1b-${tassl_mid_name}-${tassl_post_fix}" + local tassl_tgz_name="${tassl_package_name}.tar.gz" + local tassl_link_prefix="${cdn_link_header}/FISCO-BCOS/tools/tassl-1.1.1b/${tassl_tgz_name}" + LOG_INFO "Downloading tassl binary from ${tassl_link_prefix}..." + wget --no-check-certificate "${tassl_link_prefix}" + tar zxvf ${tassl_tgz_name} && rm ${tassl_tgz_name} + chmod u+x ${tassl_package_name} + mkdir -p "${HOME}"/.fisco + mv ${tassl_package_name} "${HOME}"/.fisco/tassl-1.1.1b +} + + +generate_sm_sm2_param() { + local output=$1 + cat << EOF > ${output} +-----BEGIN EC PARAMETERS----- +BggqgRzPVQGCLQ== +-----END EC PARAMETERS----- + +EOF +} + +generate_sm_cert_conf() { + local output=$1 + cat <"${output}" +oid_section = new_oids + +[ new_oids ] +tsa_policy1 = 1.2.3.4.1 +tsa_policy2 = 1.2.3.4.5.6 +tsa_policy3 = 1.2.3.4.5.7 + +#################################################################### +[ ca ] +default_ca = CA_default # The default ca section + +#################################################################### +[ CA_default ] + +dir = ./demoCA # Where everything is kept +certs = $dir/certs # Where the issued certs are kept +crl_dir = $dir/crl # Where the issued crl are kept +database = $dir/index.txt # database index file. +#unique_subject = no # Set to 'no' to allow creation of + # several ctificates with same subject. +new_certs_dir = $dir/newcerts # default place for new certs. + +certificate = $dir/cacert.pem # The CA certificate +serial = $dir/serial # The current serial number +crlnumber = $dir/crlnumber # the current crl number + # must be commented out to leave a V1 CRL +crl = $dir/crl.pem # The current CRL +private_key = $dir/private/cakey.pem # The private key +RANDFILE = $dir/private/.rand # private random number file + +x509_extensions = usr_cert # The extensions to add to the cert + +name_opt = ca_default # Subject Name options +cert_opt = ca_default # Certificate field options + +default_days = 36500 # how long to certify for +default_crl_days= 30 # how long before next CRL +default_md = default # use public key default MD +preserve = no # keep passed DN ordering + +policy = policy_match + +[ policy_match ] +countryName = match +stateOrProvinceName = match +organizationName = match +organizationalUnitName = optional +commonName = supplied +emailAddress = optional + +[ policy_anything ] +countryName = optional +stateOrProvinceName = optional +localityName = optional +organizationName = optional +organizationalUnitName = optional +commonName = supplied +emailAddress = optional + +#################################################################### +[ req ] +default_bits = 2048 +default_md = sm3 +default_keyfile = privkey.pem +distinguished_name = req_distinguished_name +x509_extensions = v3_ca # The extensions to add to the self signed cert + +string_mask = utf8only + +# req_extensions = v3_req # The extensions to add to a certificate request + +[ req_distinguished_name ] +countryName = CN +countryName_default = CN +stateOrProvinceName = State or Province Name (full name) +stateOrProvinceName_default =GuangDong +localityName = Locality Name (eg, city) +localityName_default = ShenZhen +organizationalUnitName = Organizational Unit Name (eg, section) +organizationalUnitName_default = fisco +commonName = Organizational commonName (eg, fisco) +commonName_default = fisco +commonName_max = 64 + +[ usr_cert ] +basicConstraints=CA:FALSE +nsComment = "OpenSSL Generated Certificate" + +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid,issuer + +[ v3_req ] + +# Extensions to add to a certificate request + +basicConstraints = CA:FALSE +keyUsage = nonRepudiation, digitalSignature + +[ v3enc_req ] + +# Extensions to add to a certificate request +basicConstraints = CA:FALSE +keyUsage = keyAgreement, keyEncipherment, dataEncipherment + +[ v3_agency_root ] +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid:always,issuer +basicConstraints = CA:true +keyUsage = cRLSign, keyCertSign + +[ v3_ca ] +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid:always,issuer +basicConstraints = CA:true +keyUsage = cRLSign, keyCertSign + +EOF +} + +generate_cert_conf() { + local output=$1 + cat <"${output}" +[ca] +default_ca=default_ca +[default_ca] +default_days = 36500 +default_md = sha256 + +[req] +distinguished_name = req_distinguished_name +req_extensions = v3_req +[req_distinguished_name] +countryName = CN +countryName_default = CN +stateOrProvinceName = State or Province Name (full name) +stateOrProvinceName_default =GuangDong +localityName = Locality Name (eg, city) +localityName_default = ShenZhen +organizationalUnitName = Organizational Unit Name (eg, section) +organizationalUnitName_default = FISCO-BCOS +commonName = Organizational commonName (eg, FISCO-BCOS) +commonName_default = FISCO-BCOS +commonName_max = 64 + +[ v3_req ] +basicConstraints = CA:FALSE +keyUsage = nonRepudiation, digitalSignature, keyEncipherment + +[ v4_req ] +basicConstraints = CA:TRUE + +EOF +} +print_result() { + echo "==============================================================" + LOG_INFO "${binary_name} path : ${binary_path}" + LOG_INFO "SM model : ${sm_mode}" + LOG_INFO "Output dir : ${output_dir}" + LOG_INFO "All completed. Files in ${output_dir}" +} + +help() { + echo $1 + cat < [Optional] wedpr-mpc binary exec + -o [Optional] output directory, default ./nodes + -s [Optional] SM SSL connection or not, default is false + -h Help + +deploy nodes e.g + bash $0 -o wedpr-mpc-node -e ./wedpr-mpc + bash $0 -o wedpr-mpc-node -e ./wedpr-mpc -s +EOF + exit 0 +} + +# generate the config.ini +generate_config_ini() { + local output="${1}" + + local rpc_listen_ip="${2}" + local rpc_listen_port="${3}" + local agency_info="${4}" + local agency_id="${5}" + local grpc_listen_ip="${6}" + local grpc_listen_port="${7}" + local nodeid="${8}" + + cat <"${output}" +[agency] + ; the agency-id of self-party + id = ${agency_id} + ; the agency info + +[mpc] + dataset_hdfs_path = /user/ppc/ + job_path = /data/app/ppc/mpc-job/ + mpc_root_path = /ppc/scripts/ppc-mpc/ + mpc_root_path_no_gateway = /ppc/scripts/ppc-mpc-no-gateway/ + read_per_batch_lines = 100000 + +[crypto] + sm_crypto = ${sm_mode} + +[rpc] + listen_ip=${rpc_listen_ip} + listen_port=${rpc_listen_port} + token = ppcs_psi_apikey + thread_count=4 + ; ssl or sm ssl + sm_ssl=${sm_mode} + ; ssl connection switch, if disable the ssl connection, default: false + ;disable_ssl = true + +[hdfs_storage] + ; the hdfs configuration + user = root + name_node = 127.0.0.1 + name_node_port = 9900 + token = + ; enable replace-datanode-on-failure or not + replace-datanode-on-failure = false + ; the connection-timeout, in ms, default is 1000ms + connection-timeout = 2000 + ; enable auth or not, default is false + ; enable_krb5_auth = false + ; the hdfs kerberos auth principal, used when enable_krb5_auth + ; auth_principal = root@NODE.DC1.CONSUL + ; the hdfs kerberos auth password, used when enable_krb5_auth + ; auth_password = + ; the ccache path, used when enable_krb5_auth + ; ccache_path = /tmp/krb5cc_ppc_node + ; the krb5.conf path + ; krb5_conf_path = conf/krb5.conf + +[transport] + ; the endpoint information + listen_ip = ${grpc_listen_ip} + listen_port = ${grpc_listen_port} + host_ip = + ; the threadPoolSize + thread_count = 4 + ; the gatewayService endpoint information + gateway_target = + ; the components + components = + nodeid=${nodeid} + +[cert] + ; directory the certificates located in + cert_path=./conf + +[log] + enable=true + ; print the log to std::cout or not, default print to the log files + enable_console_output = false + log_path=./log + ; info debug trace + level=info + ; MB + max_log_file_size=200 +EOF +} + +generate_krb5_file_template() +{ + local filepath=$1 + mkdir -p $(dirname $filepath) + cat << EOF > "${filepath}" +[libdefaults] + default_realm = NODE.DC1.CONSUL + dns_lookup_realm = false + dns_lookup_kdc = false + ticket_lifetime = 24h + renew_lifetime = 7d + forwardable = true + +[realms] + NODE.DC1.CONSUL = { + kdc = + admin_server = + } + +[domain_realm] + .node.dc1.consul = NODE.DC1.CONSUL + node.dc1.consul = NODE.DC1.CONSUL +EOF +} + +generate_script_template() +{ + local filepath=$1 + mkdir -p $(dirname $filepath) + cat << EOF > "${filepath}" +#!/bin/bash +SHELL_FOLDER=\$(cd \$(dirname \$0);pwd) + +LOG_ERROR() { + content=\${1} + echo -e "\033[31m[ERROR] \${content}\033[0m" +} + +LOG_INFO() { + content=\${1} + echo -e "\033[32m[INFO] \${content}\033[0m" +} + +EOF + chmod +x ${filepath} +} + +# TODO: support docker-mode +generate_node_scripts() { + local output=${1} + local ps_cmd="\$(ps aux|grep \${ppc_mpc}|grep -v grep|awk '{print \$2}')" + local start_cmd="nohup \${ppc_mpc} -c config.ini >>nohup.out 2>&1 &" + local stop_cmd="kill \${node_pid}" + local pid="pid" + local log_cmd="tail -n20 nohup.out" + local check_success="\$(${log_cmd} | grep running)" + generate_script_template "$output/start.sh" + cat <> "${output}/start.sh" +ppc_mpc=\${SHELL_FOLDER}/${binary_name} +cd \${SHELL_FOLDER} +node=\$(basename \${SHELL_FOLDER}) +node_pid=${ps_cmd} +if [ ! -z \${node_pid} ];then + echo " \${node} is running, ${pid} is \$node_pid." + exit 0 +else + ${start_cmd} + sleep 1.5 +fi +try_times=4 +i=0 +while [ \$i -lt \${try_times} ] +do + node_pid=${ps_cmd} + success_flag=${check_success} + if [[ ! -z \${node_pid} && ! -z "\${success_flag}" ]];then + echo -e "\033[32m \${node} start successfully pid=\${node_pid}\033[0m" + exit 0 + fi + sleep 0.5 + ((i=i+1)) +done +echo -e "\033[31m Exceed waiting time. Please try again to start \${node} \033[0m" +${log_cmd} +EOF + chmod u+x "${output}/start.sh" + generate_script_template "$output/stop.sh" + cat <> "${output}/stop.sh" +ppc_mpc=\${SHELL_FOLDER}/${binary_name} +node=\$(basename \${SHELL_FOLDER}) +node_pid=${ps_cmd} +try_times=10 +i=0 +if [ -z \${node_pid} ];then + echo " \${node} isn't running." + exit 0 +fi +[ ! -z \${node_pid} ] && ${stop_cmd} > /dev/null +while [ \$i -lt \${try_times} ] +do + sleep 1 + node_pid=${ps_cmd} + if [ -z \${node_pid} ];then + echo -e "\033[32m stop \${node} success.\033[0m" + exit 0 + fi + ((i=i+1)) +done +echo " Exceed maximum number of retries. Please try again to stop \${node}" +exit 1 +EOF + chmod u+x "${output}/stop.sh" +} + +generate_all_node_scripts() { + local output=${1} + mkdir -p ${output} + + cat <"${output}/start_all.sh" +#!/bin/bash +dirpath="\$(cd "\$(dirname "\$0")" && pwd)" +cd "\${dirpath}" + +dirs=(\$(ls -l \${dirpath} | awk '/^d/ {print \$NF}')) +for dir in \${dirs[*]} +do + if [[ -f "\${dirpath}/\${dir}/config.ini" && -f "\${dirpath}/\${dir}/start.sh" ]];then + echo "try to start \${dir}" + bash \${dirpath}/\${dir}/start.sh & + fi +done +wait +EOF + chmod u+x "${output}/start_all.sh" + + cat <"${output}/stop_all.sh" +#!/bin/bash +dirpath="\$(cd "\$(dirname "\$0")" && pwd)" +cd "\${dirpath}" + +dirs=(\$(ls -l \${dirpath} | awk '/^d/ {print \$NF}')) +for dir in \${dirs[*]} +do + if [[ -f "\${dirpath}/\${dir}/config.ini" && -f "\${dirpath}/\${dir}/stop.sh" ]];then + echo "try to stop \${dir}" + bash \${dirpath}/\${dir}/stop.sh + fi +done +wait +EOF + chmod u+x "${output}/stop_all.sh" +} + +gen_non_sm_ca_cert() { + if [ ! -f "${cert_conf}" ]; then + generate_cert_conf "${cert_conf}" + fi + local ca_cert_dir="${1}" + file_must_not_exists "${ca_cert_dir}"/ca.key + file_must_not_exists "${ca_cert_dir}"/ca.crt + file_must_exists "${cert_conf}" + + mkdir -p "$ca_cert_dir" + dir_must_exists "$ca_cert_dir" + + ${OPENSSL_CMD} genrsa -out "${ca_cert_dir}"/ca.key "${rsa_key_length}" + ${OPENSSL_CMD} req -new -x509 -days "${days}" -subj "/CN=FISCO-BCOS/O=FISCO-BCOS/OU=chain" -key "${ca_cert_dir}"/ca.key -config "${cert_conf}" -out "${ca_cert_dir}"/ca.crt 2>/dev/null + if [ ! -f "${ca_cert_dir}/cert.cnf" ];then + mv "${cert_conf}" "${ca_cert_dir}" + fi + LOG_INFO "Generate ca cert successfully!" +} + +gen_sm_ca_cert() { + local ca_cert_dir="${1}" + name=$(basename "$ca_cert_dir") + check_name chain "$name" + + if [ ! -f "${sm_cert_conf}" ]; then + generate_sm_cert_conf ${sm_cert_conf} + fi + + generate_sm_sm2_param "${sm2_params}" + + mkdir -p "$ca_cert_dir" + dir_must_exists "$ca_cert_dir" + + "$OPENSSL_CMD" genpkey -paramfile "${sm2_params}" -out "$ca_cert_dir/sm_ca.key" 2>/dev/null + "$OPENSSL_CMD" req -config sm_cert.cnf -x509 -days "${days}" -subj "/CN=wedpr/O=wedpr/OU=ca" -key "$ca_cert_dir/sm_ca.key" -extensions v3_ca -out "$ca_cert_dir/sm_ca.crt" 2>/dev/null + if [ ! -f "${ca_cert_dir}/${sm_cert_conf}" ];then + cp "${sm_cert_conf}" "${ca_cert_dir}" + fi + if [ ! -f "${ca_cert_dir}/${sm2_params}" ];then + cp "${sm2_params}" "${ca_cert_dir}" + fi +} + + +gen_rsa_node_cert() { + local capath="${1}" + local ndpath="${2}" + local type="${3}" + + file_must_exists "$capath/ca.key" + file_must_exists "$capath/ca.crt" + # check_name node "$node" + + file_must_not_exists "$ndpath"/"${type}".key + file_must_not_exists "$ndpath"/"${type}".crt + + mkdir -p "${ndpath}" + dir_must_exists "${ndpath}" + + ${OPENSSL_CMD} genrsa -out "${ndpath}"/"${type}".key "${rsa_key_length}" 2>/dev/null + ${OPENSSL_CMD} req -new -sha256 -subj "/CN=FISCO-BCOS/O=fisco-bcos/OU=agency" -key "$ndpath"/"${type}".key -config "$capath"/cert.cnf -out "$ndpath"/"${type}".csr + ${OPENSSL_CMD} x509 -req -days "${days}" -sha256 -CA "${capath}"/ca.crt -CAkey "$capath"/ca.key -CAcreateserial \ + -in "$ndpath"/"${type}".csr -out "$ndpath"/"${type}".crt -extensions v4_req -extfile "$capath"/cert.cnf 2>/dev/null + + ${OPENSSL_CMD} pkcs8 -topk8 -in "$ndpath"/"${type}".key -out "$ndpath"/pkcs8_node.key -nocrypt + cp "$capath"/ca.crt "$capath"/cert.cnf "$ndpath"/ + + rm -f "$ndpath"/"$type".csr + rm -f "$ndpath"/"$type".key + + mv "$ndpath"/pkcs8_node.key "$ndpath"/"$type".key + + LOG_INFO "Generate ${ndpath} cert successful!" +} + +# we use sm_param to generate the private key +generate_private_key() { + local output_path="${1}" + if [ ! -d "${output_path}" ]; then + mkdir -p ${output_path} + fi + if [ ! -f ${sm2_params} ]; then + generate_sm_sm2_param ${sm2_params} + fi + ${OPENSSL_CMD} genpkey -paramfile ${sm2_params} -out ${output_path}/node.pem 2>/dev/null + $OPENSSL_CMD ec -in "$output_path/node.pem" -text -noout 2> /dev/null | sed -n '3,5p' | sed 's/://g' | tr "\n" " " | sed 's/ //g' | cat > "$output_path/node.privateKey" + ${OPENSSL_CMD} ec -text -noout -in "${output_path}/node.pem" 2>/dev/null | sed -n '7,11p' | tr -d ": \n" | awk '{print substr($0,3);}' | cat >"$output_path"/node.nodeid + private_key=$(cat $output_path/node.privateKey) + echo ${private_key} +} + +gen_sm_node_cert_with_ext() { + local capath="$1" + local certpath="$2" + local type="$3" + local extensions="$4" + + file_must_exists "$capath/sm_ca.key" + file_must_exists "$capath/sm_ca.crt" + + file_must_not_exists "$ndpath/sm_${type}.crt" + file_must_not_exists "$ndpath/sm_${type}.key" + + "$OPENSSL_CMD" genpkey -paramfile "$capath/${sm2_params}" -out "$certpath/sm_${type}.key" 2> /dev/null + "$OPENSSL_CMD" req -new -subj "/CN=FISCO-BCOS/O=fisco-bcos/OU=${type}" -key "$certpath/sm_${type}.key" -config "$capath/sm_cert.cnf" -out "$certpath/sm_${type}.csr" 2> /dev/null + + "$OPENSSL_CMD" x509 -sm3 -req -CA "$capath/sm_ca.crt" -CAkey "$capath/sm_ca.key" -days "${days}" -CAcreateserial -in "$certpath/sm_${type}.csr" -out "$certpath/sm_${type}.crt" -extfile "$capath/sm_cert.cnf" -extensions "$extensions" 2> /dev/null + + rm -f "$certpath/sm_${type}.csr" +} + +gen_sm_node_cert() { + local capath="${1}" + local ndpath="${2}" + local type="${3}" + + file_must_exists "$capath/sm_ca.key" + file_must_exists "$capath/sm_ca.crt" + + mkdir -p "$ndpath" + dir_must_exists "$ndpath" + local node=$(basename "$ndpath") + check_name node "$node" + + gen_sm_node_cert_with_ext "$capath" "$ndpath" "${type}" v3_req + gen_sm_node_cert_with_ext "$capath" "$ndpath" "en${type}" v3enc_req + #nodeid is pubkey + $OPENSSL_CMD ec -in "$ndpath/sm_${type}.key" -text -noout 2> /dev/null | sed -n '7,11p' | sed 's/://g' | tr "\n" " " | sed 's/ //g' | awk '{print substr($0,3);}' | cat > "${ndpath}/sm_${type}.nodeid" + cp "$capath/sm_ca.crt" "$ndpath" +} + +generate_ca_cert() { + local sm_mode="$1" + local ca_cert_path="$2" + LOG_INFO "generate ca cert, sm: ${sm_mode}, ca_cert_path: ${ca_cert_path}" + mkdir -p "${ca_cert_path}" + if [[ "${sm_mode}" == "false" ]]; then + gen_non_sm_ca_cert "${ca_cert_path}" + else + gen_sm_ca_cert "${ca_cert_path}" + fi + LOG_INFO "generate ca cert successfully, sm: ${sm_mode}, ca_cert_path: ${ca_cert_path}" +} + +generate_node_cert() { + local sm_mode="$1" + local ca_cert_path="${2}" + local node_cert_path="${3}" + + mkdir -p ${node_cert_path} + if [[ "${sm_mode}" == "false" ]]; then + gen_rsa_node_cert "${ca_cert_path}" "${node_cert_path}" "ssl" 2>&1 + else + gen_sm_node_cert "${ca_cert_path}" "${node_cert_path}" "ssl" 2>&1 + fi +} + + +deploy_nodes() +{ + echo "output_dir:${output_dir}" + dir_must_not_exists "${output_dir}" + mkdir -p "$output_dir" + dir_must_exists "${output_dir}" + + # check the binary + if [[ ! -f "$binary_path" ]]; then + LOG_FATAL "wedpr-component binary exec ${binary_path} not exist, Must copy binary file ${binary_name} to ${binary_path}" + fi + + local agency_index=0 + local agency_info="" + # generate the ca-cert + ca_dir="${output_dir}"/ca + cert_conf="${output_dir}/cert.cnf" + generate_ca_cert "${sm_mode}" "${ca_dir}" + # start_all.sh and stop_all.sh + # generate_all_node_scripts "${output_dir}" + cp "${binary_path}" "${output_dir}" + # generate cert for the node + ca_cert_dir="${output_dir}"/ca + mkdir -p ${ca_cert_dir} + # cp -r ${ca_dir}/* ${ca_cert_dir} + + # generate the node config + mkdir -p "${output_dir}" + # generate the node-cert + generate_node_cert "${sm_mode}" "${ca_dir}" "${output_dir}/conf" + # generate the node-script + generate_node_scripts "${output_dir}" + # generate the config.ini + local rpc_port=5894 + local agency_id="agency${count}" + local grpc_port=18100 + # the nodeid + private_key=$(generate_private_key "${output_dir}/conf") + node_id=$(cat "${output_dir}/conf/node.nodeid") + generate_config_ini "${output_dir}/config.ini" "${listen_ip}" "${rpc_port}" "${agency_info}" ${agency_id} "${listen_ip}" "${grpc_port}" "${node_id}" + generate_krb5_file_template "{output_dir}/conf/krb5.conf" + print_result +} + +parse_params() { + while getopts "o:e:sh" option; do + case $option in + o) + output_dir="$OPTARG" + ;; + e) + binary_path="$OPTARG" + file_must_exists "${binary_path}" + ;; + s) sm_mode="true" ;; + h) help ;; + *) help ;; + esac + done +} + +main() { + check_env + check_and_install_tassl + parse_params "$@" + deploy_nodes +} +main "$@" \ No newline at end of file diff --git a/cpp/tools/generate_psi.py b/cpp/tools/generate_psi.py new file mode 100644 index 00000000..06263db7 --- /dev/null +++ b/cpp/tools/generate_psi.py @@ -0,0 +1,75 @@ +# Copyright 2022 Ant Group Co., Ltd. +# +# 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. + + +from random import randint +from random import sample +import csv +import sys + + +def random_with_N_digits(n): + range_start = 10 ** (n - 1) + range_end = (10**n) - 1 + return randint(range_start, range_end) + + +row_list = [] +len1 = 10**2 +len2 = 10 +len3 = 10 +len4 = 10 + +if len(sys.argv) > 1: + len1 = int(sys.argv[1]) + len2 = int(len1 / 2) + +if len(sys.argv) > 2: + len3 = int(sys.argv[2]) + +len4 = int(len3 / 2) +print(len1, len2) + + +for i in range(len1): + data_list = [random_with_N_digits(18)] + row_list.append(data_list) + +row_list2 = sample(row_list, len2) +for i in range(len2, len1): + data_list = [random_with_N_digits(18)] + row_list2.append(data_list) + +row_list3 = sample(row_list, len4) +for i in range(len4, len3): + data_list = [random_with_N_digits(18)] + row_list3.append(data_list) + +print(len(row_list2)) +print(len(row_list3)) + +with open('psi_1.csv', 'w', newline='') as file: + writer = csv.writer(file) + writer.writerow(["id"]) + writer.writerows(row_list) + +with open('psi_2.csv', 'w', newline='') as file: + writer = csv.writer(file) + writer.writerow(["id"]) + writer.writerows(row_list2) + +with open('psi_3.csv', 'w', newline='') as file: + writer = csv.writer(file) + writer.writerow(["id"]) + writer.writerows(row_list3) diff --git a/cpp/tools/install_depends.sh b/cpp/tools/install_depends.sh new file mode 100644 index 00000000..28f3f682 --- /dev/null +++ b/cpp/tools/install_depends.sh @@ -0,0 +1,174 @@ +#!/bin/bash +os="" +LOG_WARN() { + local content=${1} + echo -e "\033[31m[ERROR] ${content}\033[0m" +} + +LOG_INFO() { + local content=${1} + echo -e "\033[32m[INFO] ${content}\033[0m" +} + +LOG_FATAL() { + local content=${1} + echo -e "\033[31m[FATAL] ${content}\033[0m" + exit 1 +} + +install_gsasl_depend() +{ + os_type="${1}" + LOG_INFO "check gsasl..." + gsasl=$(whereis libgsasl|grep "libgsasl.a") + if [[ ! -z "${gsasl}" ]];then + LOG_INFO "the libgasal.a has already exists!" + return + fi + + LOG_INFO "download and install libgsasl..." + wget --no-check-certificate https://ftp.gnu.org/gnu/gsasl/libgsasl-1.8.0.tar.gz && tar -xvf libgsasl-1.8.0.tar.gz + + # centos + if [[ "${os_type}" == "centos" ]];then + cd libgsasl-1.8.0 && ./configure --with-pic && make -j4 && make install + fi + # macos + if [[ "${os_type}" == "macos" ]];then + cd libgsasl-1.8.0 && ./configure --with-pic && make -j4 && make install + fi + # ubuntu + if [[ "${os_type}" == "ubuntu" ]];then + cd libgsasl-1.8.0 && ./configure --with-pic && make -j4 && make install + fi + cd .. && rm -rf libgsasl-1.8.0 && rm -rf libgsasl-1.8.0.tar.gz + df -lh + LOG_INFO "download and install libgsasl success..." +} + +install_nasm_depend() +{ + LOG_INFO "check nasm..." + nasm=$(nasm --version | awk -F' ' '{print $3}') + + echo "### current nasm: ${nasm}" + # require the nasm >= 2.15 + if [[ "${nasm}" == "2.15" ]] || [[ "${nasm}" > "2.15" ]];then + LOG_INFO "the nasm >= 2.15 has already exists!" + return + fi + LOG_INFO "download and install nasm 2.15..." + wget --no-check-certificate https://www.nasm.us/pub/nasm/releasebuilds/2.15/nasm-2.15.tar.gz && tar -xvf nasm-2.15.tar.gz + cd nasm-2.15 && ./configure && make -j4 && make install + cd .. && rm -rf nasm-2.15.tar.gz && rm -rf nasm-2.15 + LOG_INFO "download and install nasm success..." +} + +install_binutils_depend() +{ + LOG_INFO "download and install binutils 2.35..." + wget --no-check-certificate http://ftp.gnu.org/gnu/binutils/binutils-2.35.tar.gz && tar -zxf binutils-2.35.tar.gz + cd binutils-2.35 && ./configure && make -j4 && make install +} + +install_centos_depends() +{ + LOG_INFO "install depends for centos ..." + # install the basic package + sudo yum install -y lcov bison flex epel-release centos-release-scl flex bison patch devtoolset-11 rh-perl530-perl cmake3 zlib-devel ccache lcov python-devel python3-devel autoconf + LOG_INFO "install basic-package-depends for centos success..." + + #LOG_INFO "install gsasl ... " + #install_gsasl_depend "centos" + #LOG_INFO "install gsasl success!" + + LOG_INFO "install nasm ... " + install_nasm_depend + LOG_INFO "install nasm success!" + + LOG_INFO "install depends for centos success ..." +} + +install_ubuntu_depends() +{ + LOG_INFO "install depends for ubuntu ..." + # install the basic package + sudo apt install -y lcov bison flex g++ libssl-dev openssl cmake git build-essential autoconf texinfo flex patch bison libgmp-dev zlib1g-dev automake pkg-config libtool wget autoconf + LOG_INFO "install basic-package-depends for ubuntu success..." + + #LOG_INFO "install gsasl ... " + #install_gsasl_depend "ubuntu" + #LOG_INFO "install gsasl success!" + + LOG_INFO "install nasm ... " + install_nasm_depend + LOG_INFO "install nasm success!" + + LOG_INFO "install binutils ... " + install_binutils_depend + LOG_INFO "install binutils success!" + + LOG_INFO "install depends for ubuntu success ..." +} + +install_iconv_depend() +{ + LOG_INFO "download and install libiconv..." + wget --no-check-certificate https://mirrors.tuna.tsinghua.edu.cn/gnu/libiconv/libiconv-1.16.tar.gz && tar -xvf libiconv-1.16.tar.gz + + cd libiconv-1.16 && ./configure --with-pic && make -j4 && make install + cd .. && rm -rf libiconv-1.16* + df -lh + LOG_INFO "download and install libiconv success..." +} + +install_macos_depends() +{ + LOG_INFO "install depends for macos ..." + brew install autoconf nasm lcov automake + #install_gsasl_depend "macos" + #install_iconv_depend + LOG_INFO "install depends for macos success ..." +} + +help() { + echo $1 + cat < [Optional] the os to install depends, support 'centos', 'ubuntu' and 'macos' now, default is empty + -h Help + +e.g: + bash $0 -o centos + bash $0 -o ubuntu + bash $0 -o macos +EOF + exit 0 +} + +parse_params() { + while getopts "o:h" option; do + case $option in + o) os="${OPTARG}" + ;; + h) help ;; + *) help ;; + esac + done +} +main() { + parse_params "$@" + if [[ -z \${os} ]];then + help + fi + if [ "${os}" == "centos" ];then + install_centos_depends + fi + if [ "${os}" == "ubuntu" ];then + install_ubuntu_depends + fi + if [ "${os}" == "macos" ];then + install_macos_depends + fi +} +main "$@" diff --git a/cpp/tools/ppc-builder/build_ppc.py b/cpp/tools/ppc-builder/build_ppc.py new file mode 100644 index 00000000..21d98853 --- /dev/null +++ b/cpp/tools/ppc-builder/build_ppc.py @@ -0,0 +1,21 @@ +#!/usr/bin/python +# -*- coding: UTF-8 -*- +# Note: here can't be refactored by autopep +import sys +sys.path.append("src/") +from controller import commandline_helper +from common import utilities +import traceback + + +def main(): + try: + args = commandline_helper.parse_command() + commandline_helper.execute_command(args) + except Exception as error: + utilities.log_error("%s" % error) + traceback.print_exc() + + +if __name__ == "__main__": + main() diff --git a/cpp/tools/ppc-builder/conf/config-example.toml b/cpp/tools/ppc-builder/conf/config-example.toml new file mode 100644 index 00000000..867f113a --- /dev/null +++ b/cpp/tools/ppc-builder/conf/config-example.toml @@ -0,0 +1,205 @@ +[env] +binary_path = "bin/" +deploy_dir = "ppc1" + +[crypto] +# the gateway-service enable ssl or not, default enable ssl +gateway_disable_ssl = false +# the gateway-service enable sm-ssl or not, default disable sm-ssl +gateway_sm_ssl = false +# the rpc use sm-ssl or not +rpc_sm_ssl = false +# the rpc disable ssl or not +rpc_disable_ssl = true +# use sm-crypto or not +sm_crypto = false + +[[agency]] +name = "agency0" +#the time of the gateway holding and waiting to dispatcher the unsynced task, in minutes +holding_msg_minutes = 30 + + [agency.gateway] + deploy_ip=["127.0.0.1:2"] + # gateway listen ip + listen_ip="0.0.0.0" + # gateway listen start port + listen_port=40300 + # the thread count + thread_count = 4 + # the grpc config + # gateway grpc server listen ip + grpc_listen_ip="0.0.0.0" + # gateway grpc server listen start port + grpc_listen_port=40600 + # gateway connected peers, should be all of the gateway peers info + [[agency.gateway.peers]] + agency = "agency0" + endpoints = ["127.0.0.1:40300", "127.0.0.1:40301"] + [[agency.gateway.peers]] + agency = "agency1" + endpoints = ["127.0.0.1:40320", "127.0.0.1:40321"] + + # configuration for the ppc-node + [[agency.node]] + # disable the ra2018 psi or not, default enable ra2018 + disable_ra2018 = true + deploy_ip=["127.0.0.1:2"] + # node name, Notice: node_name in the same agency and group must be unique + node_name = "node0" + # node grpc server listen ip + grpc_listen_ip="0.0.0.0" + # node grpc server listen port + grpc_listen_port=40402 + # the components + components = "node" + # the rpc config for the node + [agency.node.rpc] + listen_ip = "0.0.0.0" + listen_port = 10200 + thread_count = 4 + # the ra2018 config for the node + [agency.node.ra2018psi] + # The database used to store cuckoo-filter + database = "ra2018_0" + # The capacity of the cuckoo filter in MB, the default is 1MB + cuckoofilter_capacity = 1 + # The length of each element of the cuckoo filter (bits), default 64bits + cuckoofilter_tagBits = 64 + # The number of buckets for the cuckoo filter, the default is 4 + cuckoofilter_buckets_num = 4 + # When the cuckoo filter replaces an element, the maximum number of element replacements allowed + cuckoofilter_max_kick_out_count = 20 + # The trash-bucket-size for the cuckoo-filter + trash_bucket_size = 10000 + # The cuckoo filter capacity that can be cached in memory in MB + cuckoofilter_cache_size = 256 + # Cache size in MB + psi_cache_size = 1024 + # When reading large files, the line size loaded into memory each time, default is 100w, -1 means load the max-size-of data + data_batch_size = 1000000 + # use hdfs to store the cuckoo-filter or not + use_hdfs = false + # the storage config + [agency.node.storage] + host = "127.0.0.1" + # the mysqlx_port + port = 33060 + user = "wedpr" + password = "" + database = "" + # the hdfs storage config + [agency.node.hdfs_storage] + user = "root" + name_node = "127.0.0.1" + name_node_port = 9000 + token = "" + # enable auth or not, default is false + enable_krb5_auth = false + # the hdfs kerberos auth principal, used when enable_krb5_auth + auth_principal = "root@NODE.DC1.CONSUL" + # the hdfs kerberos auth password, used when enable_krb5_auth + auth_password = "" + # the ccache path, used when enable_krb5_auth + ccache_path = "/tmp/krb5cc_ppc_node" + # the krb5 conf path + krb5_conf_path = "conf/krb5.conf" + # the gateway config + [agency.node.gateway] + gateway_grpc_target = ["127.0.0.1:40600", "127.0.0.1:40601"] + + +[[agency]] +name = "agency1" +#the time of the gateway holding and waiting to dispatcher the unsynced task, in minutes +holding_msg_minutes = 30 + + [agency.gateway] + deploy_ip=["127.0.0.1:2"] + # gateway listen ip + listen_ip="0.0.0.0" + # gateway listen start port + listen_port=40320 + # the thread count + thread_count = 4 + # the grpc config + # gateway grpc server listen ip + grpc_listen_ip="0.0.0.0" + # gateway grpc server listen start port + grpc_listen_port=40620 + # gateway connected peers, should be all of the gateway peers info + [[agency.gateway.peers]] + agency = "agency0" + endpoints = ["127.0.0.1:40300", "127.0.0.1:40301"] + [[agency.gateway.peers]] + agency = "agency1" + endpoints = ["127.0.0.1:40320", "127.0.0.1:40321"] + + # configuration for the ppc-node + [[agency.node]] + # disable the ra2018 psi or not, default enable ra2018 + disable_ra2018 = true + deploy_ip=["127.0.0.1:2"] + # node name, Notice: node_name in the same agency and group must be unique + node_name = "node0" + # node grpc server listen ip + grpc_listen_ip="0.0.0.0" + # node grpc server listen port + grpc_listen_port=40422 + # the componet + components = "node" + # the rpc config for the node + [agency.node.rpc] + listen_ip = "0.0.0.0" + listen_port = 10220 + thread_count = 4 + # the ra2018 config for the node + [agency.node.ra2018psi] + # The database used to store cuckoo-filter + database = "ra2018_1" + # The capacity of the cuckoo filter in MB, the default is 1MB + cuckoofilter_capacity = 1 + # The length of each element of the cuckoo filter (bits), default 64bits + cuckoofilter_tagBits = 64 + # The number of buckets for the cuckoo filter, the default is 4 + cuckoofilter_buckets_num = 4 + # When the cuckoo filter replaces an element, the maximum number of element replacements allowed + cuckoofilter_max_kick_out_count = 20 + # The trash-bucket-size for the cuckoo-filter + trash_bucket_size = 10000 + # The cuckoo filter capacity that can be cached in memory in MB + cuckoofilter_cache_size = 256 + # Cache size in MB + psi_cache_size = 1024 + # When reading large files, the line size loaded into memory each time, default is 100w, -1 means load the max-size-of data + data_batch_size = 1000000 + # use hdfs to store the cuckoo-filter or not + use_hdfs = false + # the storage config + [agency.node.storage] + host = "127.0.0.1" + # the mysqlx_port + port = 33060 + user = "wedpr" + password = "" + database = "" + # the hdfs storage config + [agency.node.hdfs_storage] + user = "root" + name_node = "127.0.0.1" + name_node_port = 9000 + token = "" + # enable auth or not, default is false + enable_krb5_auth = false + # the hdfs kerberos auth principal, used when enable_krb5_auth + auth_principal = "root@NODE.DC1.CONSUL" + # the hdfs kerberos auth password, used when enable_krb5_auth + auth_password = "" + # the ccache path, used when enable_krb5_auth + ccache_path = "/tmp/krb5cc_ppc_node" + # the krb5 conf path + krb5_conf_path = "conf/krb5.conf" + + # the gateway config + [agency.node.gateway] + gateway_grpc_target = ["127.0.0.1:40620", "127.0.0.1:40621"] diff --git a/cpp/tools/ppc-builder/requirements.txt b/cpp/tools/ppc-builder/requirements.txt new file mode 100644 index 00000000..3d7ce2f7 --- /dev/null +++ b/cpp/tools/ppc-builder/requirements.txt @@ -0,0 +1,3 @@ +configparser +toml +uuid diff --git a/cpp/tools/ppc-builder/src/common/utilities.py b/cpp/tools/ppc-builder/src/common/utilities.py new file mode 100644 index 00000000..5462a9db --- /dev/null +++ b/cpp/tools/ppc-builder/src/common/utilities.py @@ -0,0 +1,170 @@ +#!/usr/bin/python +# -*- coding: UTF-8 -*- +import sys +import re +import os +import subprocess +import logging +import configparser + +logging.basicConfig(format='%(message)s', + level=logging.INFO) + + +class ServiceInfo: + ssl_file_list = ["ca.crt", "ssl.key", "ssl.crt"] + sm_ssl_file_list = ["sm_ca.crt", "sm_ssl.key", + "sm_ssl.crt", "sm_enssl.key", "sm_enssl.crt"] + cert_generation_script_path = "src/scripts/gen_cert.sh" + node_service_type = "node" + gateway_service_type = "gateway" + supported_service_type = [node_service_type, gateway_service_type] + + +class ConfigInfo: + config_ini_file = "config.ini" + tpl_abs_path = "src/tpl/" + pwd_path = os.getcwd() + node_config_tpl_path = os.path.join( + pwd_path, tpl_abs_path, "config.ini.node") + gateway_config_tpl_path = os.path.join( + pwd_path, tpl_abs_path, "config.ini.gateway") + krb5_config_tpl_path = os.path.join( + pwd_path, tpl_abs_path, "krb5.conf") + + ppc_gateway_binary_name = "ppc-gateway-service" + ppc_node_binary_name = "ppc-pro-node" + + start_tpl_path = os.path.join( + pwd_path, tpl_abs_path, "start.sh") + stop_tpl_path = os.path.join( + pwd_path, tpl_abs_path, "stop.sh") + + start_all_tpl_path = os.path.join( + pwd_path, tpl_abs_path, "start_all.sh") + stop_all_tpl_path = os.path.join( + pwd_path, tpl_abs_path, "stop_all.sh") + + +class CommandInfo: + generate_config = "genconfig" + extend_config = "extend" + supported_command_list = [generate_config, extend_config] + + +def log_error(error_msg): + logging.error("\033[31m%s \033[0m" % error_msg) + + +def log_info(error_msg): + logging.info("\033[32m%s \033[0m" % error_msg) + + +def format_info(info): + return ("\033[32m%s \033[0m" % info) + + +def log_debug(error_msg): + logging.debug("%s" % error_msg) + + +def get_item_value(config, key, default_value, must_exist, desc): + if key in config: + return config[key] + if must_exist: + raise Exception("the value for %s.%s must be set" % (desc, key)) + return default_value + + +def get_value(config, section, key, default_value, must_exist): + if section in config and key in config[section]: + return config[section][key] + if must_exist: + raise Exception("the value for %s must be set" % key) + return default_value + + +def execute_command_and_getoutput(command): + status, output = subprocess.getstatusoutput(command) + if status != 0: + log_error( + "execute command %s failed, error message: %s" % (command, output)) + return (False, output) + return (True, output) + + +def execute_command(command): + (ret, result) = execute_command_and_getoutput(command) + return ret + + +def mkdir(path): + if not os.path.exists(path): + os.makedirs(path) + + +def removeDir(path): + if os.path.exists(path): + os.removedirs(path) + + +def mkfiledir(filepath): + parent_dir = os.path.abspath(os.path.join(filepath, "..")) + if os.path.exists(parent_dir) is False: + mkdir(parent_dir) + + +def convert_bool_to_str(value): + if value is True: + return "true" + return "false" + + +def print_split_info(): + log_info("=========================================================") + + +def print_badge(badge): + log_info("----------- %s -----------" % badge) + + +def file_must_exist(file_path): + if not os.path.exists(file_path): + log_error("%s does not exist, please check" % file_path) + sys.exit(-1) + + +def store_config(config_content, config_type, config_path, desc): + """ + store the generated genesis config content for given node + """ + if os.path.exists(config_path): + log_error("* store %s config for %s failed for the config %s already exists." % + (config_type, desc, config_path)) + return False + log_info("* store %s config for %s\n\t path: %s" % + (config_type, desc, config_path)) + + if os.path.exists(os.path.dirname(config_path)) is False: + mkdir(os.path.dirname(config_path)) + + with open(config_path, 'w') as configFile: + if isinstance(config_content, str): + configFile.write(config_content) + elif isinstance(config_content, bytes): + configFile.write(config_content) + else: + config_content.write(configFile) + log_info("* store %s config for %s success" % + (config_type, desc)) + return True + + +def load_config(file_path): + # load the config from tpl_config_path + config_content = configparser.ConfigParser( + comment_prefixes='/', allow_no_value=True) + # to distinguish uppercase/lowercase letters + config_content.optionxform = str + config_content.read(file_path) + return config_content diff --git a/cpp/tools/ppc-builder/src/config/binary_generator.py b/cpp/tools/ppc-builder/src/config/binary_generator.py new file mode 100644 index 00000000..d4bc175b --- /dev/null +++ b/cpp/tools/ppc-builder/src/config/binary_generator.py @@ -0,0 +1,26 @@ +#!/usr/bin/python +# -*- coding: UTF-8 -*- +import os +from common import utilities + + +class BinaryGenerator: + """ + generate the binary + """ + def generate_binary(binary_path, dst_path): + if os.path.exists(binary_path) is False: + utilities.log_error( + "The specified binary %s not exists!" % binary_path) + return False + # the binary has already been generated + if os.path.exists(dst_path) is True: + return True + utilities.mkfiledir(dst_path) + command = "cp %s %s" % (binary_path, dst_path) + (ret, output) = utilities.execute_command_and_getoutput(command) + if ret is False: + utilities.log_error("copy binary from %s to %s failed, error: %s") % ( + binary_path, dst_path, output) + return False + return True diff --git a/cpp/tools/ppc-builder/src/config/cert_generator.py b/cpp/tools/ppc-builder/src/config/cert_generator.py new file mode 100644 index 00000000..8521ee8b --- /dev/null +++ b/cpp/tools/ppc-builder/src/config/cert_generator.py @@ -0,0 +1,57 @@ +#!/usr/bin/python +# -*- coding: UTF-8 -*- +import os +from common import utilities + + +class CertGenerator: + """ + the cert generator + """ + def generate_ca_cert(sm_mode, ca_cert_path): + """ + generate the ca cert + """ + use_sm = "false" + if sm_mode is True: + use_sm = "true" + command = "bash %s generate_ca_cert %s %s" % ( + utilities.ServiceInfo.cert_generation_script_path, use_sm, ca_cert_path) + (ret, output) = utilities.execute_command_and_getoutput(command) + if ret is False: + utilities.log_error( + "* generate ca cert error, sm_mode: %d, ca cert path: %s, error: %s" % (sm_mode, ca_cert_path, output)) + return False + utilities.log_info( + "* generate ca cert success, sm_mode: %d, ca cert path: %s" % (sm_mode, ca_cert_path)) + return True + + def generate_node_cert(sm_mode, ca_cert_path, node_cert_path): + """ + generate the node cert + """ + use_sm = "false" + if sm_mode is True: + use_sm = "true" + command = "bash %s generate_node_cert %s %s %s" % ( + utilities.ServiceInfo.cert_generation_script_path, use_sm, ca_cert_path, node_cert_path) + (ret, output) = utilities.execute_command_and_getoutput(command) + if ret is False: + utilities.log_error("* generate node cert error, sm_mode: %d, ca cert path: %s, node cert path: %s" % + (sm_mode, ca_cert_path, node_cert_path)) + return False + utilities.log_info("* generate the node cert success, sm_mode: %d, ca cert path: %s, node cert path: %s" % + (sm_mode, ca_cert_path, node_cert_path)) + return True + + def generate_private_key(output_path): + command = "bash %s generate_private_key_for_psi_server %s" % ( + utilities.ServiceInfo.cert_generation_script_path, output_path) + (ret, output) = utilities.execute_command_and_getoutput(command) + if ret is False: + utilities.log_error( + "* generate private key error, output_path: %s" % output_path) + return (False, output) + utilities.log_info( + "* generate private_key success, path: %s, public_key: %s" % (output_path, output)) + return (True, output) diff --git a/cpp/tools/ppc-builder/src/config/ppc_deploy_config.py b/cpp/tools/ppc-builder/src/config/ppc_deploy_config.py new file mode 100644 index 00000000..d8c642e4 --- /dev/null +++ b/cpp/tools/ppc-builder/src/config/ppc_deploy_config.py @@ -0,0 +1,357 @@ +#!/usr/bin/python +# -*- coding: UTF-8 -*- + +from common import utilities + + +class PeerInfo: + def __init__(self, agency, endpoints): + self.agency = agency + self.endpoints = endpoints + + +class EnvConfig: + def __init__(self, config, section_name): + self.config = config + self.section_name = section_name + self.binary_path = utilities.get_value( + self.config, self.section_name, "binary_path", None, True) + self.deploy_dir = utilities.get_value( + self.config, self.section_name, "deploy_dir", None, True) + + +class GatewayConfig: + """ + the gateway config + """ + + def __init__(self, agency_name, holding_msg_minutes, config, config_section, must_exist): + self.config = config + self.config_section = config_section + self.holding_msg_minutes = holding_msg_minutes + self.agency_name = agency_name + + # the deploy_ip + self.deploy_ip = utilities.get_item_value( + self.config, "deploy_ip", None, must_exist, config_section) + # the listen_ip + self.listen_ip = utilities.get_item_value( + self.config, "listen_ip", "0.0.0.0", False, config_section) + # the listen_port + self.listen_port = utilities.get_item_value( + self.config, "listen_port", None, must_exist, config_section) + # the thread count + self.thread_count = utilities.get_item_value( + self.config, "thread_count", 4, False, config_section) + # the peers + self.peers = [] + peers = utilities.get_item_value( + self.config, "peers", None, must_exist, config_section) + for peer in peers: + agency = utilities.get_item_value( + peer, "agency", None, must_exist, "[[peers]]") + endpoints = utilities.get_item_value( + peer, "endpoints", None, must_exist, "[[peers]]") + self.peers.append(PeerInfo(agency, endpoints)) + + # the grpc_listen_ip + self.grpc_listen_ip = utilities.get_item_value( + self.config, "grpc_listen_ip", "0.0.0.0", False, config_section) + # the grpc_listen_port + self.grpc_listen_port = utilities.get_item_value( + self.config, "grpc_listen_port", None, must_exist, config_section) + + +class RpcConfig: + """ + the rpc config + """ + + def __init__(self, config, config_section, must_exist): + self.config = config + self.config_section = config_section + self.listen_ip = utilities.get_item_value( + self.config, "listen_ip", "0.0.0.0", False, config_section) + self.listen_port = utilities.get_item_value( + self.config, "listen_port", None, must_exist, config_section) + self.thread_count = utilities.get_item_value( + self.config, "thread_count", 4, False, config_section) + + +class StorageConfig: + """ + the sql storage config + """ + + def __init__(self, config, config_section, must_exist): + self.config = config + self.config_section = config_section + # the mysql configuration + self.host = utilities.get_item_value( + self.config, "host", None, must_exist, config_section) + self.port = utilities.get_item_value( + self.config, "port", None, must_exist, config_section) + self.user = utilities.get_item_value( + self.config, "user", None, must_exist, config_section) + self.password = utilities.get_item_value( + self.config, "password", None, must_exist, config_section) + self.database = utilities.get_item_value( + self.config, "database", None, must_exist, config_section) + + +class HDFSStorageConfig: + """ + the hdfs storage config + """ + + def __init__(self, config, config_section, must_exist): + self.config = config + self.config_section = config_section + # the hdfs configuration + self.user = utilities.get_item_value( + self.config, "user", None, must_exist, config_section) + self.name_node = utilities.get_item_value( + self.config, "name_node", None, must_exist, config_section) + self.name_node_port = utilities.get_item_value( + self.config, "name_node_port", None, must_exist, config_section) + self.token = utilities.get_item_value( + self.config, "token", "", False, config_section) + # enable auth or not + enable_krb5_auth = utilities.get_item_value( + self.config, "enable_krb5_auth", "", + False, config_section) + self.enable_krb5_auth_str = utilities.convert_bool_to_str( + enable_krb5_auth) + # auth principal + self.auth_principal = utilities.get_item_value( + self.config, "auth_principal", + "", enable_krb5_auth, config_section) + # auth password + self.auth_password = utilities.get_item_value( + self.config, "auth_password", + "", enable_krb5_auth, config_section) + # cacche path + self.ccache_path = utilities.get_item_value( + self.config, "ccache_path", + "", enable_krb5_auth, config_section) + # the krb5.conf + self.krb5_conf_path = utilities.get_item_value( + self.config, "krb5_conf_path", + "conf/krb5.conf", enable_krb5_auth, config_section) + + +class RA2018PSIConfig: + """ + the ra2018-psi config + """ + + def __init__(self, config, config_section, must_exist): + self.config = config + self.config_section = config_section + self.database = utilities.get_item_value( + self.config, "database", None, must_exist, config_section) + self.cuckoofilter_capacity = utilities.get_item_value( + self.config, "cuckoofilter_capacity", 1, False, config_section) + self.cuckoofilter_tagBits = utilities.get_item_value( + self.config, "cuckoofilter_tagBits", 32, False, config_section) + self.cuckoofilter_buckets_num = utilities.get_item_value( + self.config, "cuckoofilter_buckets_num", 4, False, config_section) + self.cuckoofilter_max_kick_out_count = utilities.get_item_value( + self.config, "cuckoofilter_max_kick_out_count", 20, False, config_section) + self.trash_bucket_size = utilities.get_item_value( + self.config, "trash_bucket_size", 10000, False, config_section) + self.cuckoofilter_cache_size = utilities.get_item_value( + self.config, "cuckoofilter_cache_size", 256, False, config_section) + self.psi_cache_size = utilities.get_item_value( + self.config, "psi_cache_size", 1024, False, config_section) + self.data_batch_size = utilities.get_item_value( + self.config, "data_batch_size", -1, False, config_section) + self.use_hdfs = utilities.get_item_value( + self.config, "use_hdfs", False, False, config_section) + + +class NodeGatewayConfig: + """ + the gateway config for the node + """ + + def __init__(self, agency_name, config, node_must_exists): + self.config = config + self.agency_name = agency_name + self.desc = "[agency.node]" + self.gateway_grpc_target_array = utilities.get_item_value( + self.config, "gateway_grpc_target", None, node_must_exists, self.desc) + self.gateway_grpc_target = "ipv4:" + self.gateway_grpc_target += ','.join( + map(str, self.gateway_grpc_target_array)) + + +class NodeConfig: + """ + the ppc-node config + """ + + def __init__(self, agency_name, holding_msg_minutes, config, must_exist): + self.config = config + self.section_name = "[[agency.node]]." + self.holding_msg_minutes = holding_msg_minutes + # set the agency_name + self.agency_name = agency_name + # disable ra2018 or not, default enable the ra2018 + self.disable_ra2018 = utilities.get_item_value( + self.config, "disable_ra2018", False, False, self.section_name) + # the components + self.components = utilities.get_item_value( + self.config, "components", None, False, self.section_name) + # the deploy_ip + self.deploy_ip = utilities.get_item_value( + self.config, "deploy_ip", None, must_exist, self.section_name) + # the node_name + self.node_name = utilities.get_item_value( + self.config, "node_name", None, must_exist, self.section_name) + # the grpc_listen_ip + self.grpc_listen_ip = utilities.get_item_value( + self.config, "grpc_listen_ip", "0.0.0.0", False, self.section_name) + # the grpc_listen_port + self.grpc_listen_port = utilities.get_item_value( + self.config, "grpc_listen_port", None, must_exist, self.section_name) + utilities.log_debug("load the node config success") + + # parse the rpc config + utilities.log_debug("load the rpc config") + rpc_config_section_name = "[[agency.node.rpc]]" + rpc_config_object = utilities.get_item_value( + self.config, "rpc", None, must_exist, rpc_config_section_name) + self.rpc_config = None + if rpc_config_object is not None: + self.rpc_config = RpcConfig( + rpc_config_object, rpc_config_section_name, must_exist) + utilities.log_debug("load the rpc config success") + + # parse the ra2018-psi config + utilities.log_debug("load the ra2018psi config") + ra2018psi_config_section = "[[agency.node.ra2018psi]]" + ra2018psi_config_object = utilities.get_item_value( + self.config, "ra2018psi", None, must_exist, ra2018psi_config_section) + self.ra2018psi_config = None + if ra2018psi_config_object is not None: + self.ra2018psi_config = RA2018PSIConfig( + ra2018psi_config_object, ra2018psi_config_section, must_exist) + utilities.log_debug("load the ra2018psi config success") + # parse the storage config + utilities.log_debug("load the sql storage config") + storage_config_section = "[[agency.node.storage]]" + storage_config_object = utilities.get_item_value( + self.config, "storage", None, must_exist, storage_config_section) + self.storage_config = None + if storage_config_object is not None: + self.storage_config = StorageConfig( + storage_config_object, storage_config_section, must_exist) + utilities.log_debug("load the sql storage success") + # parse the hdfs storage config + hdfs_storage_must_configured = False + if self.ra2018psi_config is not None: + hdfs_storage_must_configured = self.ra2018psi_config.use_hdfs + utilities.log_debug("load the hdfs storage config") + storage_config_section = "[[agency.node.hdfs_storage]]" + hdfs_storage_config_object = utilities.get_item_value( + self.config, "hdfs_storage", None, hdfs_storage_must_configured, storage_config_section) + self.hdfs_storage_config = None + if hdfs_storage_config_object is not None: + self.hdfs_storage_config = HDFSStorageConfig( + hdfs_storage_config_object, storage_config_section, hdfs_storage_must_configured) + utilities.log_debug("load the hdfs storage success") + # parse the gateway-inforamtion + utilities.log_debug("load the gateway config") + gateway_config_section = "[[agency.node.gateway]]" + gateway_config_object = utilities.get_item_value( + self.config, "gateway", None, must_exist, gateway_config_section) + self.gateway_config = None + if gateway_config_object is not None: + self.gateway_config = NodeGatewayConfig( + self.agency_name, gateway_config_object, must_exist) + utilities.log_debug("load the gateway success") + + +class AgencyConfig: + """ + the agency config + """ + + def __init__(self, config, gateway_must_exists, node_must_exists): + self.config = config + self.section_name = "[[agency]]" + # the agency-name + self.agency_name = utilities.get_item_value( + self.config, "name", None, True, self.section_name) + # the holding_msg_minutes + self.holding_msg_minutes = utilities.get_item_value( + self.config, "holding_msg_minutes", 30, False, self.section_name) + # parse the gateway config + utilities.log_debug("load the gateway config") + gateway_config_section_name = "[agency.gateway]" + gateway_config_object = utilities.get_item_value( + self.config, "gateway", None, gateway_must_exists, gateway_config_section_name) + self.gateway_config = None + if gateway_config_object is not None: + self.gateway_config = GatewayConfig(self.agency_name, self.holding_msg_minutes, gateway_config_object, + gateway_config_section_name, gateway_must_exists) + utilities.log_debug("load the gateway config success") + + # parse the node config + utilities.log_debug("load the node config") + node_config_section_name = "[[agency.node]]" + # Note: the node is not required to exist + node_config_list = utilities.get_item_value( + self.config, "node", None, False, node_config_section_name) + self.node_list = {} + # the case without node + if node_config_list is None: + return + # TODO: check the node-name + for node_object in node_config_list: + node_config = NodeConfig( + self.agency_name, self.holding_msg_minutes, node_object, node_must_exists) + self.node_list[node_config.node_name] = node_config + utilities.log_debug( + "load node config for %s success" % node_config.node_name) + utilities.log_debug("load the node config success") + + +class PPCDeployConfig: + """ + load all config from config.toml + """ + + def __init__(self, config, gateway_must_exists, node_must_exists): + self.config = config + # load the crypto config + utilities.log_debug("load the crypto config") + crypto_section = "crypto" + self.gateway_disable_ssl = utilities.get_value( + self.config, crypto_section, "gateway_disable_ssl", False, False) + self.gateway_sm_ssl = utilities.get_value( + self.config, crypto_section, "gateway_sm_ssl", False, False) + # the rpc disable ssl or not + self.rpc_disable_ssl = utilities.get_value( + self.config, crypto_section, "rpc_disable_ssl", False, False) + # the rpc use sm-ssl or not + self.rpc_sm_ssl = utilities.get_value( + self.config, crypto_section, "rpc_sm_ssl", False, False) + self.sm_crypto = utilities.get_value( + self.config, crypto_section, "sm_crypto", False, False) + utilities.log_debug("load the crypto config success") + self.env_config = EnvConfig(self.config, "env") + # load the agency config + # TODO: check duplicated case + utilities.log_debug("load the agency config") + self.agency_list = {} + agency_list_object = utilities.get_item_value( + self.config, "agency", None, False, "[[agency]]") + for agency_object in agency_list_object: + agency_config = AgencyConfig( + agency_object, gateway_must_exists, node_must_exists) + self.agency_list[agency_config.agency_name] = agency_config + utilities.log_debug( + "load the agency config for %s success" % agency_config.agency_name) + utilities.log_debug("load the agency config success") diff --git a/cpp/tools/ppc-builder/src/config/ppc_gateway_config_generator.py b/cpp/tools/ppc-builder/src/config/ppc_gateway_config_generator.py new file mode 100644 index 00000000..2c06abbb --- /dev/null +++ b/cpp/tools/ppc-builder/src/config/ppc_gateway_config_generator.py @@ -0,0 +1,167 @@ +#!/usr/bin/python +# -*- coding: UTF-8 -*- +import os +import json +from common import utilities +from config.binary_generator import BinaryGenerator +from config.cert_generator import CertGenerator +from config.shell_script_generator import ShellScriptGenerator + + +class PPCGatewayConfigGenerator: + """ + the ppc-gateway-config-generator + """ + + def __init__(self, config, output_dir): + self.config = config + self.output_dir = output_dir + self.binary_name = utilities.ConfigInfo.ppc_gateway_binary_name + self.service_type = utilities.ServiceInfo.gateway_service_type + + def generate_gateway_config(self): + utilities.print_badge("* generate gateway config, deploy_dir: %s" % + self.config.env_config.deploy_dir) + # generate the ca + ret = CertGenerator.generate_ca_cert( + self.config.gateway_sm_ssl, self.__generate_ca_cert_path__()) + if ret is False: + utilities.log_error( + "* generate ca-cert config for %s failed" % self.config.env_config.deploy_dir) + return False + connection_config = {} + connection_config["nodes"] = [] + connection_config_path_list = [] + for agency_config in self.config.agency_list.values(): + gateway_config = agency_config.gateway_config + ret = self.__generate_single_gateway_config__( + gateway_config, connection_config, connection_config_path_list) + if ret is False: + return False + self.__generate_connection_info__( + connection_config_path_list, connection_config) + utilities.print_badge( + "* generate gateway config success, deploy_dir: %s" % self.config.env_config.deploy_dir) + return True + + def __generate_single_gateway_config__(self, gateway_config, connection_config, connection_config_path_list): + # load the config from tpl_config_path + utilities.log_info("* generate config for ppc-gateway") + for ip_str in gateway_config.deploy_ip: + ip_array = ip_str.split(":") + ip = ip_array[0] + # generate the shell scripts for the given ip + ret = ShellScriptGenerator.generate_ip_shell_scripts( + self.__generate_ip_shell_scripts_output_path__(gateway_config.agency_name, ip), "start_all.sh", "stop_all.sh") + if ret is False: + return False + node_count = 1 + if len(ip_array) >= 2: + node_count = int(ip_array[1]) + for node_index in range(node_count): + node_name = "node" + str(node_index) + connection_config_path_list.append(os.path.join(self.__generate_node_path__( + gateway_config.agency_name, ip, node_name), "nodes.json")) + utilities.print_badge( + "* generate config for ppc-gateway %s.%s, deploy_ip: %s" % (gateway_config.agency_name, node_name, ip)) + config_content = utilities.load_config( + utilities.ConfigInfo.gateway_config_tpl_path) + # load the common config + self.__generate_common_config__(gateway_config, config_content) + # load the gateway config + listen_port = gateway_config.listen_port + node_index + connection_config["nodes"].append(ip + ":" + str(listen_port)) + grpc_listen_port = gateway_config.grpc_listen_port + node_index + self.__generate_gateway_config_content__( + gateway_config, config_content, listen_port, grpc_listen_port) + # generate the binary + binary_path = os.path.join( + self.config.env_config.binary_path, self.binary_name) + dst_binary_path = os.path.join( + self.__generate_ip_shell_scripts_output_path__( + gateway_config.agency_name, ip), + self.binary_name) + ret = BinaryGenerator.generate_binary( + binary_path, dst_binary_path) + if ret is False: + return False + # generate the ini config + ini_config_output_path = os.path.join( + self.__generate_node_path__(gateway_config.agency_name, ip, node_name), utilities.ConfigInfo.config_ini_file) + ret = utilities.store_config( + config_content, "ini", ini_config_output_path, "config.ini") + if ret is False: + utilities.log_error( + "* generate config for ppc-gateway, ip: %s failed" % (ip)) + return False + # generate the node config + ret = CertGenerator.generate_node_cert(self.config.gateway_sm_ssl, self.__generate_ca_cert_path__( + ), self.__generate_conf_output_path__(gateway_config.agency_name, ip, node_name)) + if ret is False: + utilities.log_error( + "* generate config for ppc-gateway failed for generate the node config failed") + return False + ret = ShellScriptGenerator.generate_node_shell_scripts(self.__generate_node_path__( + gateway_config.agency_name, ip, node_name), self.binary_name) + if ret is False: + return False + utilities.print_badge("* generate config for ppc-gateway%s success" % + (node_name)) + utilities.log_info("* generate config for ppc-gateway success") + return True + + def __generate_connection_info__(self, connection_config_path_list, connection_config): + connection_str = json.dumps(connection_config) + for path in connection_config_path_list: + ret = utilities.store_config( + connection_str, "json", path, "nodes.json") + if ret is False: + utilities.log_error( + "* generate nodes.json failed, path: %s" % path) + return False + return True + + def __generate_ca_cert_path__(self): + return os.path.join(self.output_dir, self.service_type, "ca") + + def __generate_node_path__(self, agency_name, ip, node_name): + return os.path.join(self.output_dir, agency_name, ip, self.service_type, node_name) + + def __generate_conf_output_path__(self, agency_name, ip, node_name): + node_path = self.__generate_node_path__(agency_name, ip, node_name) + return os.path.join(node_path, "conf") + + def __generate_ip_shell_scripts_output_path__(self, agency_name, ip): + return os.path.join(self.output_dir, agency_name, ip, self.service_type) + + def __generate_common_config__(self, config, config_content): + """ + generate the common config + """ + section = "agency" + # the agency + config_content[section]["id"] = config.agency_name + config_content["gateway"]["holding_msg_minutes"] = str( + config.holding_msg_minutes) + + def __generate_gateway_config_content__(self, config, config_content, listen_port, grpc_listen_port): + """ + generate the gateway config + """ + section = "gateway" + # the listen_ip + config_content[section]["listen_ip"] = config.listen_ip + # the listen port + config_content[section]["listen_port"] = str(listen_port) + # the thread count + config_content[section]["thread_count"] = str(config.thread_count) + # sm ssl + config_content[section]["sm_ssl"] = utilities.convert_bool_to_str( + self.config.gateway_sm_ssl) + # disable ssl + config_content[section]["disable_ssl"] = utilities.convert_bool_to_str( + self.config.gateway_disable_ssl) + section = "transport" + config_content[section]["listen_ip"] = config.grpc_listen_ip + # the listen port + config_content[section]["listen_port"] = str(grpc_listen_port) diff --git a/cpp/tools/ppc-builder/src/config/ppc_node_config_generator.py b/cpp/tools/ppc-builder/src/config/ppc_node_config_generator.py new file mode 100644 index 00000000..8a835ae1 --- /dev/null +++ b/cpp/tools/ppc-builder/src/config/ppc_node_config_generator.py @@ -0,0 +1,261 @@ +#!/usr/bin/python +# -*- coding: UTF-8 -*- +import os +import sys +from common import utilities +from config.binary_generator import BinaryGenerator +from config.cert_generator import CertGenerator +from config.shell_script_generator import ShellScriptGenerator + + +class PPCNodeConfigGenerator: + """ + the ppc-node-config-generator + """ + + def __init__(self, config, output_dir): + self.config = config + self.output_dir = output_dir + self.binary_name = utilities.ConfigInfo.ppc_node_binary_name + self.service_type = utilities.ServiceInfo.node_service_type + + def generate_node_config(self): + utilities.print_badge("* generate_node_config") + # generate the ca cert for rpc + ret = CertGenerator.generate_ca_cert( + self.config.rpc_sm_ssl, self.__generate_ca_cert_path__()) + if ret is False: + utilities.log_error( + "* generate_node_config failed for generate ca error") + return False + for agency_config in self.config.agency_list.values(): + for node_config in agency_config.node_list.values(): + for ip_str in node_config.deploy_ip: + if ret is False: + return False + ip_array = ip_str.split(":") + ip = ip_array[0] + # generate the shell scripts for the given ip + ret = ShellScriptGenerator.generate_ip_shell_scripts( + self.__generate_ip_output_path__(node_config.agency_name, ip), "start_all.sh", "stop_all.sh") + node_count = 1 + if len(ip_array) >= 2: + node_count = int(ip_array[1]) + for node_index in range(node_count): + node_name = "node" + str(node_index) + if self.__generate_single_node_config__(node_config, ip, node_name, node_config.agency_name, node_index) is False: + return False + utilities.print_badge("* generate_node_config success") + return True + + def __generate_single_node_config__(self, node_config, ip, node_name, agency_name, node_index): + utilities.print_badge("* generate node config for %s, ip: %s, agency: %s" % + (node_name, ip, agency_name)) + # copy the binary + binary_path = os.path.join( + self.config.env_config.binary_path, self.binary_name) + dst_binary_path = os.path.join( + self.__generate_ip_output_path__(agency_name, ip), self.binary_name) + ret = BinaryGenerator.generate_binary(binary_path, dst_binary_path) + if ret is False: + return False + # generate the node config + node_path = self.__generate_node_path__( + agency_name, ip, node_name) + + private_key_path = self.__generate_node_conf_path__( + agency_name, ip, node_name) + if self.__generate_single_node_inner_config__(utilities.ConfigInfo.node_config_tpl_path, + node_path, + private_key_path, node_config, ip, + node_index) is False: + utilities.log_error("* generate node config, ip: %s failed" % + (ip)) + return False + # generate the node cert(for rpc) + ret = CertGenerator.generate_node_cert(self.config.rpc_sm_ssl, self.__generate_ca_cert_path__( + ), self.__generate_node_conf_path__(agency_name, ip, node_name)) + if ret is False: + utilities.log_error("* generate node config, ip: %s failed for generate rpc cert failed" % + (ip)) + return False + ret = ShellScriptGenerator.generate_node_shell_scripts( + self.__generate_node_path__(agency_name, ip, node_name), self.binary_name) + if ret is False: + return False + utilities.print_badge("* generate node config %s, ip: %s.%s success" % + (node_name, agency_name, ip)) + return True + + def __generate_single_node_inner_config__(self, tpl_config_path, node_path, private_key_path, + node_config, ip, node_index): + config_content = utilities.load_config(tpl_config_path) + utilities.log_debug( + "__generate_single_node_inner_config__, load config.ini from %s" % tpl_config_path) + # generate the private key + (ret, node_id) = CertGenerator.generate_private_key(private_key_path) + if ret is False: + return False + # load the common config + self.__generate_common_config__( + config_content, node_config) + # load the rpc config + self.__generate_rpc_config__( + config_content, node_config.rpc_config, node_index) + # load the transport config + self.__generate_transport_config__(config_content, + node_config, node_id, ip, node_index) + # load the storage config + self.__generate_storage_config__( + config_content, node_config.storage_config) + # load the hdfs_storage_config + self.__generate_hdfs_storage_config__(node_path, utilities.ConfigInfo.krb5_config_tpl_path, + config_content, node_config.hdfs_storage_config) + # load the ra2018psi config + self.__generate_ra2018psi_config__( + config_content, node_config.ra2018psi_config) + # store the config + ini_config_output_path = os.path.join( + node_path, utilities.ConfigInfo.config_ini_file) + ret = utilities.store_config( + config_content, "ini", ini_config_output_path, "config.ini") + if ret is False: + return False + return True + + def __generate_ca_cert_path__(self): + return os.path.join(self.output_dir, self.service_type, "ca") + + def __generate_node_path__(self, agency_name, ip, node_name): + return os.path.join(self.output_dir, agency_name, ip, self.service_type, + node_name) + + def __generate_node_conf_path__(self, agency_name, ip, node_name): + node_path = self.__generate_node_path__(agency_name, ip, node_name) + return os.path.join(node_path, "conf") + + def __generate_ip_output_path__(self, agency_name, ip): + return os.path.join(self.output_dir, agency_name, ip, self.service_type) + + def __generate_common_config__(self, config_content, node_config): + """ + generate the common config + """ + # the agency config + config_content["agency"]["id"] = node_config.agency_name + # disable ra2018 or not + config_content["agency"]["disable_ra2018"] = utilities.convert_bool_to_str( + node_config.disable_ra2018) + # the crypto config + config_content["crypto"]["sm_crypto"] = utilities.convert_bool_to_str( + self.config.sm_crypto) + + def __generate_rpc_config__(self, config_content, rpc_config, node_index): + """ + generate the rpc config + """ + section_name = "rpc" + # listen_ip + config_content[section_name]["listen_ip"] = rpc_config.listen_ip + # listen_port + rpc_listen_port = rpc_config.listen_port + node_index + config_content[section_name]["listen_port"] = str(rpc_listen_port) + # sm_ssl + config_content[section_name]["sm_ssl"] = utilities.convert_bool_to_str( + self.config.rpc_sm_ssl) + # disable_ssl + config_content[section_name]["disable_ssl"] = utilities.convert_bool_to_str( + self.config.rpc_disable_ssl) + + def __generate_storage_config__(self, config_content, storage_config): + """ + generate the storage config + """ + if storage_config is None: + utilities.log_error("Must set the mysql-storage-config!") + sys.exit(-1) + + section_name = "storage" + config_content[section_name]["host"] = storage_config.host + config_content[section_name]["port"] = str(storage_config.port) + config_content[section_name]["user"] = storage_config.user + config_content[section_name]["password"] = storage_config.password + config_content[section_name]["database"] = storage_config.database + + def __generate_hdfs_storage_config__(self, node_path, krb5_tpl_file_path, config_content, hdfs_storage_config): + if hdfs_storage_config is None: + return + section_name = "hdfs_storage" + config_content[section_name]["user"] = hdfs_storage_config.user + config_content[section_name]["name_node"] = hdfs_storage_config.name_node + config_content[section_name]["name_node_port"] = str( + hdfs_storage_config.name_node_port) + config_content[section_name]["token"] = hdfs_storage_config.token + config_content[section_name]["enable_krb5_auth"] = hdfs_storage_config.enable_krb5_auth_str + config_content[section_name]["auth_principal"] = hdfs_storage_config.auth_principal + config_content[section_name]["auth_password"] = hdfs_storage_config.auth_password + config_content[section_name]["ccache_path"] = hdfs_storage_config.ccache_path + config_content[section_name]["krb5_conf_path"] = hdfs_storage_config.krb5_conf_path + # copy krb5.conf to krb5_conf_path specified path + dst_path = os.path.join(node_path, hdfs_storage_config.krb5_conf_path) + if hdfs_storage_config.krb5_conf_path.startswith("/"): + dst_path = hdfs_storage_config.krb5_conf_path + command = "cp %s %s" % (krb5_tpl_file_path, dst_path) + (ret, output) = utilities.execute_command_and_getoutput(command) + if ret is False: + utilities.log_error("copy krb5 configuration from %s to %s failed, error: %s") % ( + krb5_tpl_file_path, dst_path, output) + return False + return True + + def __generate_transport_config__(self, config_content, + node_config, node_id, + deploy_ip, node_index): + """_summary_ + + Args: + ; the endpoint information + listen_ip = 0.0.0.0 + listen_port = 18000 + host_ip = + ; the threadPoolSize + thread_count = 4 + ; the gatewayService endpoint information + gateway_target = + ; the components + components = + nodeid= + """ + section = "transport" + config_content[section]["listen_ip"] = node_config.grpc_listen_ip + config_content[section]["listen_port"] = str( + node_config.grpc_listen_port + node_index) + config_content[section]["host_ip"] = deploy_ip + config_content[section]["gateway_target"] = node_config.gateway_config.gateway_grpc_target + config_content[section]["components"] = node_config.components + config_content[section]["nodeid"] = node_id + + def __generate_ra2018psi_config__(self, config_content, ra2018psi_config): + """ + generate the ra2018psi config + """ + section_name = "ra2018psi" + config_content[section_name]["database"] = ra2018psi_config.database + config_content[section_name]["cuckoofilter_capacity"] = str( + ra2018psi_config.cuckoofilter_capacity) + config_content[section_name]["cuckoofilter_tagBits"] = str( + ra2018psi_config.cuckoofilter_tagBits) + config_content[section_name]["cuckoofilter_buckets_num"] = str( + ra2018psi_config.cuckoofilter_buckets_num) + config_content[section_name]["cuckoofilter_max_kick_out_count"] = str( + ra2018psi_config.cuckoofilter_max_kick_out_count) + config_content[section_name]["trash_bucket_size"] = str( + ra2018psi_config.trash_bucket_size) + config_content[section_name]["cuckoofilter_cache_size"] = str( + ra2018psi_config.cuckoofilter_cache_size) + config_content[section_name]["psi_cache_size"] = str( + ra2018psi_config.psi_cache_size) + config_content[section_name]["data_batch_size"] = str( + ra2018psi_config.data_batch_size) + config_content[section_name]["use_hdfs"] = utilities.convert_bool_to_str( + ra2018psi_config.use_hdfs) diff --git a/cpp/tools/ppc-builder/src/config/shell_script_generator.py b/cpp/tools/ppc-builder/src/config/shell_script_generator.py new file mode 100644 index 00000000..557e03ff --- /dev/null +++ b/cpp/tools/ppc-builder/src/config/shell_script_generator.py @@ -0,0 +1,75 @@ +#!/usr/bin/python +# -*- coding: UTF-8 -*- +from common import utilities +import os + + +class ShellScriptGenerator: + """ + generate the shell-scripts + """ + def generate_ip_shell_scripts(script_output_dir, start_shell_script_name, stop_shell_script_name): + start_all_path = os.path.join( + script_output_dir, start_shell_script_name) + utilities.mkdir(script_output_dir) + if os.path.exists(start_all_path) is False: + utilities.log_debug( + "* generate shell script, dst: %s" % start_all_path) + # start_all.sh + command = "cp %s %s" % ( + utilities.ConfigInfo.start_all_tpl_path, start_all_path) + (result, output) = utilities.execute_command_and_getoutput(command) + if result is False: + utilities.log_error( + "* generate %s failed, error: %s" % (start_all_path, output)) + return False + stop_all_path = os.path.join( + script_output_dir, stop_shell_script_name) + if os.path.exists(stop_all_path) is False: + # tars stop_all.sh + command = "cp %s %s" % ( + utilities.ConfigInfo.stop_all_tpl_path, stop_all_path) + (result, output) = utilities.execute_command_and_getoutput(command) + if result is False: + utilities.log_error( + "* generate %s failed, error: %s" % (stop_all_path, output)) + return False + utilities.log_debug( + "* generate_ip_shell_scripts success, output: %s" % script_output_dir) + return True + + def __update_binary__(file_path, output_path, binary_name): + command = "cp %s %s" % (file_path, output_path) + (ret, _) = utilities.execute_command_and_getoutput(command) + if ret is False: + return False + updated_config = "" + with open(output_path, 'r', encoding='UTF-8') as file: + updated_config = file.read() + updated_config = updated_config.replace( + "@BINARY_NAME@", binary_name) + with open(output_path, 'w', encoding='UTF-8') as file: + file.write(updated_config) + return True + + def generate_node_shell_scripts(script_output_dir, binary_name): + utilities.log_debug("* generate shell scripts for %s, dst: %s" % + (binary_name, script_output_dir)) + utilities.mkdir(script_output_dir) + # the start.sh + output_path = os.path.join(script_output_dir, "start.sh") + ret = ShellScriptGenerator.__update_binary__( + utilities.ConfigInfo.start_tpl_path, output_path, binary_name) + if ret is False: + utilities.log_error( + "generate_node_shell_scripts %s error" % output_path) + return False + # the stop.sh + output_path = os.path.join(script_output_dir, "stop.sh") + ret = ShellScriptGenerator.__update_binary__( + utilities.ConfigInfo.stop_tpl_path, output_path, binary_name) + if ret is False: + utilities.log_error( + "generate_node_shell_scripts %s error" % output_path) + return False + return True diff --git a/cpp/tools/ppc-builder/src/controller/commandline_helper.py b/cpp/tools/ppc-builder/src/controller/commandline_helper.py new file mode 100644 index 00000000..bc995877 --- /dev/null +++ b/cpp/tools/ppc-builder/src/controller/commandline_helper.py @@ -0,0 +1,88 @@ +#!/usr/bin/python +# -*- coding: UTF-8 -*- +from common import utilities +from config.ppc_gateway_config_generator import PPCGatewayConfigGenerator +from config.ppc_node_config_generator import PPCNodeConfigGenerator +from config.ppc_deploy_config import PPCDeployConfig +from argparse import RawTextHelpFormatter +import sys +import toml +import os +import argparse + + +def parse_command(): + help_info = "examples:\n * generate node config:\t python3 build_ppc.py -t node\n * generate gateway config:\t python3 build_ppc.py -t gateway\n * generate gateway config:\t python3 build_ppc.py -o genconfig -c config.toml -t gateway -d ppc-generated\n * generate node config:\t python3 build_ppc.py -o genconfig -c config.toml -t node -d ppc-generated" + parser = argparse.ArgumentParser( + prog=sys.argv[0], description=help_info, formatter_class=RawTextHelpFormatter, add_help=True) + + # the command option, now support genconfig/extend + help_info = "[Optional] specify the command: \n* supported command list: %s\n" % ( + ''.join(utilities.CommandInfo.supported_command_list)) + parser.add_argument("-o", '--operation', help=help_info, + required=False, default=utilities.CommandInfo.generate_config) + + # config option + help_info = "[Optional] the config file, default is config.toml\n" + parser.add_argument( + "-c", "--config", help=help_info, default="config.toml") + # the output option + help_info = "[Optional] the output path, default is pp-generated\n" + parser.add_argument( + "-d", "--output", help=help_info, default="ppc-generated") + + # the type option + supported_service_type_str = ', '.join( + utilities.ServiceInfo.supported_service_type) + help_info = "[Required] the service type:\n* now support: %s \n" % ( + supported_service_type_str) + parser.add_argument("-t", "--type", help=help_info, default="") + args = parser.parse_args() + return args + + +def generate_node_config(args, toml_config): + """ + generate the node config + """ + service_type = args.type + # check the type + if service_type not in utilities.ServiceInfo.supported_service_type: + utilities.log_error("The service type must be " + + ', '.join(utilities.ServiceInfo.supported_service_type)) + sys.exit(-1) + if service_type == utilities.ServiceInfo.node_service_type: + utilities.log_debug("generate config for the ppc-node") + config = PPCDeployConfig(toml_config, False, True) + node_generator = PPCNodeConfigGenerator(config, args.output) + ret = node_generator.generate_node_config() + if ret is False: + sys.exit(-1) + if service_type == utilities.ServiceInfo.gateway_service_type: + utilities.log_debug("generate config for the ppc-success") + config = PPCDeployConfig(toml_config, True, False) + gateway_generator = PPCGatewayConfigGenerator(config, args.output) + ret = gateway_generator.generate_gateway_config() + if ret is False: + sys.exit(-1) + + +def execute_command(args): + # check the config path + if os.path.exists(args.config) is False: + utilities.log_error("The config file %s not found!" % args.config) + sys.exit(-1) + # load the toml config + toml_config = toml.load(args.config) + # check the command + command = args.operation + if command not in utilities.CommandInfo.supported_command_list: + utilities.log_error("The command must be " + + ', '.join(utilities.CommandInfo.supported_command_list)) + sys.exit(-1) + if command == utilities.CommandInfo.generate_config: + generate_node_config(args, toml_config) + return + # TODO: implement expand + if command == utilities.CommandInfo.extend: + utilities.log_error("unimplemented command %s" % command) diff --git a/cpp/tools/ppc-builder/src/scripts/gen_cert.sh b/cpp/tools/ppc-builder/src/scripts/gen_cert.sh new file mode 100644 index 00000000..187fa66e --- /dev/null +++ b/cpp/tools/ppc-builder/src/scripts/gen_cert.sh @@ -0,0 +1,466 @@ + +cdn_link_header="https://osp-1257653870.cos.ap-guangzhou.myqcloud.com/FISCO-BCOS" +OPENSSL_CMD="${HOME}/.fisco/tassl-1.1.1b" + +cert_conf="cert.cnf" +sm_cert_conf='sm_cert.cnf' +sm2_params="sm_sm2.param" +days=36500 +rsa_key_length=2048 + +LOG_WARN() { + local content=${1} + echo -e "\033[31m[ERROR] ${content}\033[0m" +} + +LOG_INFO() { + local content=${1} + echo -e "\033[32m[INFO] ${content}\033[0m" +} + +LOG_FATAL() { + local content=${1} + echo -e "\033[31m[FATAL] ${content}\033[0m" + exit 1 +} + +dir_must_exists() { + if [ ! -d "$1" ]; then + LOG_FATAL "$1 DIR does not exist, please check!" + fi +} + +get_value() { + local var_name=${1} + var_name=var_${var_name//./} + local res=$(eval echo '$'"${var_name}") + echo ${res} +} + +set_value() { + local var_name=${1} + var_name=var_${var_name//./} + local var_value=${2} + eval "${var_name}=${var_value}" +} + +dir_must_not_exists() { + if [ -d "$1" ]; then + LOG_FATAL "$1 DIR already exist, please check!" + fi +} + +file_must_not_exists() { + if [ -f "$1" ]; then + LOG_FATAL "$1 file already exist, please check!" + fi +} + +file_must_exists() { + if [ ! -f "$1" ]; then + LOG_FATAL "$1 file does not exist, please check!" + fi +} + +check_env() { + if [ "$(uname)" == "Darwin" ];then + macOS="macOS" + fi + if [ "$(uname -m)" != "x86_64" ];then + x86_64_arch="false" + fi +} +check_name() { + local name="$1" + local value="$2" + [[ "$value" =~ ^[a-zA-Z0-9._-]+$ ]] || { + LOG_FATAL "$name name [$value] invalid, it should match regex: ^[a-zA-Z0-9._-]+\$" + } +} + +check_and_install_tassl(){ + if [ -f "${OPENSSL_CMD}" ];then + return + fi + # https://en.wikipedia.org/wiki/Uname#Examples + local x86_64_name="x86_64" + local arm_name="aarch64" + local tassl_mid_name="linux" + if [[ -n "${macOS}" ]];then + x86_64_name="x86_64" + arm_name="arm64" + tassl_mid_name="macOS" + fi + + local tassl_post_fix="x86_64" + local platform="$(uname -m)" + if [[ "${platform}" == "${arm_name}" ]];then + tassl_post_fix="aarch64" + elif [[ "${platform}" == "${x86_64_name}" ]];then + tassl_post_fix="x86_64" + else + LOG_FATAL "Unsupported platform ${platform} for ${tassl_mid_name}" + exit 1 + fi + local tassl_package_name="tassl-1.1.1b-${tassl_mid_name}-${tassl_post_fix}" + local tassl_tgz_name="${tassl_package_name}.tar.gz" + local tassl_link_prefix="${cdn_link_header}/FISCO-BCOS/tools/tassl-1.1.1b/${tassl_tgz_name}" + LOG_INFO "Downloading tassl binary from ${tassl_link_prefix}..." + wget --no-check-certificate "${tassl_link_prefix}" + tar zxvf ${tassl_tgz_name} && rm ${tassl_tgz_name} + chmod u+x ${tassl_package_name} + mkdir -p "${HOME}"/.fisco + mv ${tassl_package_name} "${HOME}"/.fisco/tassl-1.1.1b +} + +generate_sm_sm2_param() { + local output=$1 + cat << EOF > ${output} +-----BEGIN EC PARAMETERS----- +BggqgRzPVQGCLQ== +-----END EC PARAMETERS----- + +EOF +} + +generate_sm_cert_conf() { + local output=$1 + cat <"${output}" +oid_section = new_oids + +[ new_oids ] +tsa_policy1 = 1.2.3.4.1 +tsa_policy2 = 1.2.3.4.5.6 +tsa_policy3 = 1.2.3.4.5.7 + +#################################################################### +[ ca ] +default_ca = CA_default # The default ca section + +#################################################################### +[ CA_default ] + +dir = ./demoCA # Where everything is kept +certs = $dir/certs # Where the issued certs are kept +crl_dir = $dir/crl # Where the issued crl are kept +database = $dir/index.txt # database index file. +#unique_subject = no # Set to 'no' to allow creation of + # several ctificates with same subject. +new_certs_dir = $dir/newcerts # default place for new certs. + +certificate = $dir/cacert.pem # The CA certificate +serial = $dir/serial # The current serial number +crlnumber = $dir/crlnumber # the current crl number + # must be commented out to leave a V1 CRL +crl = $dir/crl.pem # The current CRL +private_key = $dir/private/cakey.pem # The private key +RANDFILE = $dir/private/.rand # private random number file + +x509_extensions = usr_cert # The extensions to add to the cert + +name_opt = ca_default # Subject Name options +cert_opt = ca_default # Certificate field options + +default_days = 36500 # how long to certify for +default_crl_days= 30 # how long before next CRL +default_md = default # use public key default MD +preserve = no # keep passed DN ordering + +policy = policy_match + +[ policy_match ] +countryName = match +stateOrProvinceName = match +organizationName = match +organizationalUnitName = optional +commonName = supplied +emailAddress = optional + +[ policy_anything ] +countryName = optional +stateOrProvinceName = optional +localityName = optional +organizationName = optional +organizationalUnitName = optional +commonName = supplied +emailAddress = optional + +#################################################################### +[ req ] +default_bits = 2048 +default_md = sm3 +default_keyfile = privkey.pem +distinguished_name = req_distinguished_name +x509_extensions = v3_ca # The extensions to add to the self signed cert + +string_mask = utf8only + +# req_extensions = v3_req # The extensions to add to a certificate request + +[ req_distinguished_name ] +countryName = CN +countryName_default = CN +stateOrProvinceName = State or Province Name (full name) +stateOrProvinceName_default =GuangDong +localityName = Locality Name (eg, city) +localityName_default = ShenZhen +organizationalUnitName = Organizational Unit Name (eg, section) +organizationalUnitName_default = fisco +commonName = Organizational commonName (eg, fisco) +commonName_default = fisco +commonName_max = 64 + +[ usr_cert ] +basicConstraints=CA:FALSE +nsComment = "OpenSSL Generated Certificate" + +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid,issuer + +[ v3_req ] + +# Extensions to add to a certificate request + +basicConstraints = CA:FALSE +keyUsage = nonRepudiation, digitalSignature + +[ v3enc_req ] + +# Extensions to add to a certificate request +basicConstraints = CA:FALSE +keyUsage = keyAgreement, keyEncipherment, dataEncipherment + +[ v3_agency_root ] +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid:always,issuer +basicConstraints = CA:true +keyUsage = cRLSign, keyCertSign + +[ v3_ca ] +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid:always,issuer +basicConstraints = CA:true +keyUsage = cRLSign, keyCertSign + +EOF +} + +generate_cert_conf() { + local output=$1 + cat <"${output}" +[ca] +default_ca=default_ca + +[default_ca] +default_days = 36500 +default_md = sha256 + +[req] +distinguished_name = req_distinguished_name +req_extensions = v3_req + +[req_distinguished_name] +countryName = CN +countryName_default = CN +stateOrProvinceName = State or Province Name (full name) +stateOrProvinceName_default =GuangDong +localityName = Locality Name (eg, city) +localityName_default = ShenZhen +organizationalUnitName = Organizational Unit Name (eg, section) +organizationalUnitName_default = WeDPR-PPC +commonName = Organizational commonName (eg, WeDPR-PPC) +commonName_default = WeDPR-PPC +commonName_max = 64 + +[ v3_req ] +basicConstraints = CA:FALSE +keyUsage = nonRepudiation, digitalSignature, keyEncipherment + +[ v4_req ] +basicConstraints = CA:FALSE + +EOF +} + +gen_non_sm_ca_cert() { + if [ ! -f "${cert_conf}" ]; then + generate_cert_conf "${cert_conf}" + fi + local ca_cert_dir="${1}" + file_must_not_exists "${ca_cert_dir}"/ca.key + file_must_not_exists "${ca_cert_dir}"/ca.crt + file_must_exists "${cert_conf}" + + mkdir -p "$ca_cert_dir" + dir_must_exists "$ca_cert_dir" + + ${OPENSSL_CMD} genrsa -out "${ca_cert_dir}"/ca.key "${rsa_key_length}" + ${OPENSSL_CMD} req -new -x509 -days "${days}" -subj "/CN=WeDPR-PPC/O=WeDPR-PPC/OU=chain" -key "${ca_cert_dir}"/ca.key -config "${cert_conf}" -out "${ca_cert_dir}"/ca.crt 2>/dev/null + if [ ! -f "${ca_cert_dir}/cert.cnf" ];then + mv "${cert_conf}" "${ca_cert_dir}" + fi + LOG_INFO "Generate ca cert successfully!" +} + +gen_sm_ca_cert() { + local ca_cert_dir="${1}" + name=$(basename "$ca_cert_dir") + check_name chain "$name" + + if [ ! -f "${sm_cert_conf}" ]; then + generate_sm_cert_conf ${sm_cert_conf} + fi + + generate_sm_sm2_param "${sm2_params}" + + mkdir -p "$ca_cert_dir" + dir_must_exists "$ca_cert_dir" + + "$OPENSSL_CMD" genpkey -paramfile "${sm2_params}" -out "$ca_cert_dir/sm_ca.key" 2>/dev/null + "$OPENSSL_CMD" req -config sm_cert.cnf -x509 -days "${days}" -subj "/CN=wedpr/O=wedpr/OU=ca" -key "$ca_cert_dir/sm_ca.key" -extensions v3_ca -out "$ca_cert_dir/sm_ca.crt" 2>/dev/null + if [ ! -f "${ca_cert_dir}/${sm_cert_conf}" ];then + cp "${sm_cert_conf}" "${ca_cert_dir}" + fi + if [ ! -f "${ca_cert_dir}/${sm2_params}" ];then + cp "${sm2_params}" "${ca_cert_dir}" + fi +} + + +gen_rsa_node_cert() { + local capath="${1}" + local ndpath="${2}" + local type="${3}" + + file_must_exists "$capath/ca.key" + file_must_exists "$capath/ca.crt" + # check_name node "$node" + + file_must_not_exists "$ndpath"/"${type}".key + file_must_not_exists "$ndpath"/"${type}".crt + + mkdir -p "${ndpath}" + dir_must_exists "${ndpath}" + + ${OPENSSL_CMD} genrsa -out "${ndpath}"/"${type}".key "${rsa_key_length}" 2>/dev/null + ${OPENSSL_CMD} req -new -sha256 -subj "/CN=WeDPR-PPC/O=WeDPR-PPC/OU=agency" -key "$ndpath"/"${type}".key -config "$capath"/cert.cnf -out "$ndpath"/"${type}".csr + ${OPENSSL_CMD} x509 -req -days "${days}" -sha256 -CA "${capath}"/ca.crt -CAkey "$capath"/ca.key -CAcreateserial \ + -in "$ndpath"/"${type}".csr -out "$ndpath"/"${type}".crt -extensions v4_req -extfile "$capath"/cert.cnf 2>/dev/null + + ${OPENSSL_CMD} pkcs8 -topk8 -in "$ndpath"/"${type}".key -out "$ndpath"/pkcs8_node.key -nocrypt + cp "$capath"/ca.crt "$capath"/cert.cnf "$ndpath"/ + + rm -f "$ndpath"/"$type".csr + rm -f "$ndpath"/"$type".key + + mv "$ndpath"/pkcs8_node.key "$ndpath"/"$type".key + + LOG_INFO "Generate ${ndpath} cert successful!" +} + +gen_sm_node_cert_with_ext() { + local capath="$1" + local certpath="$2" + local type="$3" + local extensions="$4" + + file_must_exists "$capath/sm_ca.key" + file_must_exists "$capath/sm_ca.crt" + + file_must_not_exists "$ndpath/sm_${type}.crt" + file_must_not_exists "$ndpath/sm_${type}.key" + + "$OPENSSL_CMD" genpkey -paramfile "$capath/${sm2_params}" -out "$certpath/sm_${type}.key" 2> /dev/null + "$OPENSSL_CMD" req -new -subj "/CN=WeDPR-PPC/O=WeDPR-PPC/OU=${type}" -key "$certpath/sm_${type}.key" -config "$capath/sm_cert.cnf" -out "$certpath/sm_${type}.csr" 2> /dev/null + + "$OPENSSL_CMD" x509 -sm3 -req -CA "$capath/sm_ca.crt" -CAkey "$capath/sm_ca.key" -days "${days}" -CAcreateserial -in "$certpath/sm_${type}.csr" -out "$certpath/sm_${type}.crt" -extfile "$capath/sm_cert.cnf" -extensions "$extensions" 2> /dev/null + + rm -f "$certpath/sm_${type}.csr" +} + +gen_sm_node_cert() { + local capath="${1}" + local ndpath="${2}" + local type="${3}" + + file_must_exists "$capath/sm_ca.key" + file_must_exists "$capath/sm_ca.crt" + + mkdir -p "$ndpath" + dir_must_exists "$ndpath" + local node=$(basename "$ndpath") + check_name node "$node" + + gen_sm_node_cert_with_ext "$capath" "$ndpath" "${type}" v3_req + gen_sm_node_cert_with_ext "$capath" "$ndpath" "en${type}" v3enc_req + #nodeid is pubkey + $OPENSSL_CMD ec -in "$ndpath/sm_${type}.key" -text -noout 2> /dev/null | sed -n '7,11p' | sed 's/://g' | tr "\n" " " | sed 's/ //g' | awk '{print substr($0,3);}' | cat > "${ndpath}/sm_${type}.nodeid" + cp "$capath/sm_ca.crt" "$ndpath" +} + +generate_ca_cert() { + local sm_mode="$1" + local ca_cert_path="$2" + LOG_INFO "generate ca cert, sm: ${sm_mode}, ca_cert_path: ${ca_cert_path}" + mkdir -p "${ca_cert_path}" + if [[ "${sm_mode}" == "false" ]]; then + gen_non_sm_ca_cert "${ca_cert_path}" + else + gen_sm_ca_cert "${ca_cert_path}" + fi + LOG_INFO "generate ca cert successfully, sm: ${sm_mode}, ca_cert_path: ${ca_cert_path}" +} + +generate_node_cert() { + local sm_mode="$1" + local ca_cert_path="${2}" + local node_cert_path="${3}" + + mkdir -p ${node_cert_path} + if [[ "${sm_mode}" == "false" ]]; then + gen_rsa_node_cert "${ca_cert_path}" "${node_cert_path}" "ssl" 2>&1 + else + gen_sm_node_cert "${ca_cert_path}" "${node_cert_path}" "ssl" 2>&1 + fi +} + +# we use sm_param to generate the private key +generate_private_key_for_psi_server() { + local output_path="${1}" + if [ ! -d "${output_path}" ]; then + mkdir -p ${output_path} + fi + if [ ! -f ${sm2_params} ]; then + generate_sm_sm2_param ${sm2_params} + fi + ${OPENSSL_CMD} genpkey -paramfile ${sm2_params} -out ${output_path}/node.pem 2>/dev/null + $OPENSSL_CMD ec -in "$output_path/node.pem" -text -noout 2> /dev/null | sed -n '3,5p' | sed 's/://g' | tr "\n" " " | sed 's/ //g' | cat > "$output_path/node.privateKey" + ${OPENSSL_CMD} ec -text -noout -in "${output_path}/node.pem" 2>/dev/null | sed -n '7,11p' | tr -d ": \n" | awk '{print substr($0,3);}' | cat >"$output_path"/node.nodeid + public_key=$(cat $output_path/node.nodeid) + echo ${public_key} +} + +check_env() { + if [ "$(uname)" == "Darwin" ];then + macOS="macOS" + fi + if [ "$(uname -m)" != "x86_64" ];then + x86_64_arch="false" + fi +} + +main() { + check_env + check_and_install_tassl + command="${1}" + if [ "${command}" == "generate_node_cert" ];then + generate_node_cert "${2}" "${3}" "${4}" + fi + if [ "${command}" == "generate_ca_cert" ];then + generate_ca_cert "${2}" "${3}" + fi + if [ "${command}" == "generate_private_key_for_psi_server" ];then + generate_private_key_for_psi_server "${2}" + fi +} +main "$@" \ No newline at end of file diff --git a/cpp/tools/ppc-builder/src/tpl/config.ini.gateway b/cpp/tools/ppc-builder/src/tpl/config.ini.gateway new file mode 100644 index 00000000..10afa936 --- /dev/null +++ b/cpp/tools/ppc-builder/src/tpl/config.ini.gateway @@ -0,0 +1,53 @@ +[agency] + ; the agency-id of self-party + id = agency0 + +[cert] + ; directory the certificates located in + cert_path=./conf + +[gateway] + listen_ip=0.0.0.0 + listen_port=40300 + ;the dir that contains the connected endpoint information, e.g.nodes.json + ;nodes_path="./" + ; the file that configure the connected endpoint information + ; nodes_file=nodes.json + ; thread_count = 4 + ; ssl or sm ssl + sm_ssl=false + ; the max allowed message size in MBytes, default is 100MBytes + max_allow_msg_size = 100 + ;ssl connection switch, if disable the ssl connection, default: false + ;disable_ssl = true + ;the time of the gateway holding and waiting to dispatcher the unsynced task, in minutes + holding_msg_minutes = 30 + ;reconnect_time = 10000 + ; the unreachable distance + ;unreachable_distance=10 + +[transport] + ; the endpoint information + listen_ip = 0.0.0.0 + listen_port = 19000 + +[log] + enable=true + log_path=./log + ; info debug trace + level=debug + ; MB + max_log_file_size=200 + ; LineID, TimeStamp, ProcessID, ThreadName, ThreadID and Message + ;format=%Severity%|ppcs-gateway|system-id|%TimeStamp%|%ThreadName%-%ThreadID%|%Message% + format=%Severity%|%TimeStamp%|%Message% + enable_rotate_by_hour=true + log_name_pattern=ppcs-gateway.log + ; Y,m,d,H,M,S are supported, N is the sequence number log_%Y%m%d.%H%M%S.%N.log + rotate_name_pattern=log_%Y%m%d.%H%M.log + ; if archive_path is empty, the archive function will be disabled + ; archive_path=./log/ + compress_archive_file=true + ; ; 0: no limit, in MB + ; max_archive_size=0 + ; min_free_space=0 \ No newline at end of file diff --git a/cpp/tools/ppc-builder/src/tpl/config.ini.node b/cpp/tools/ppc-builder/src/tpl/config.ini.node new file mode 100644 index 00000000..5bbb29b3 --- /dev/null +++ b/cpp/tools/ppc-builder/src/tpl/config.ini.node @@ -0,0 +1,124 @@ +[agency] + ; the agency-id of self-party + id = agency0 + ; the private key path for the psi-server + private_key_path = conf/node.pem + ; disable the ra2018 or not, default enable ra2018 + disable_ra2018 = true + ; the path that allows programs to access + ; data_location = data + ; task_timeout_minutes = 180 + ; thread_count = 8 + ; GB, reject task if available memory is less than min_needed_memory + ; min_needed_memory = 1 + +[crypto] + sm_crypto = false + +[rpc] + listen_ip=0.0.0.0 + listen_port=10200 + ; token = ppcs_psi_apikey + thread_count=4 + ; ssl or sm ssl + sm_ssl=false + ; ssl connection switch, if disable the ssl connection, default: true + disable_ssl = true + ; disable_db = true + +[cert] + ; directory the certificates located in + cert_path=./conf + +[transport] + ; the endpoint information + listen_ip = 0.0.0.0 + listen_port = 18000 + host_ip = + ; the threadPoolSize + thread_count = 4 + ; the gatewayService endpoint information + gateway_target = + ; the components + components = + nodeid= + +[storage] + host = 127.0.0.1 + ; the mysqlx_port + port = 3306 + user = app + password = + database = + +[hdfs_storage] + ; the hdfs configuration + user = root + name_node = 127.0.0.1 + name_node_port = 9000 + token = + ; enable replace-datanode-on-failure or not + replace-datanode-on-failure = false + ; the connection-timeout, in ms, default is 1000ms + connection-timeout = 1000 + ; enable auth or not, default is false + ; enable_krb5_auth = false + ; the hdfs kerberos auth principal, used when enable_krb5_auth + ; auth_principal = root@NODE.DC1.CONSUL + ; the hdfs kerberos auth password, used when enable_krb5_auth + ; auth_password = + ; the ccache path, used when enable_krb5_auth + ; ccache_path = /tmp/krb5cc_ppc_node + ; the krb5.conf path + ; krb5_conf_path = conf/krb5.conf + +[ra2018psi] + ; The database used to store cuckoo-filter + database=ra2018_0 + ; The capacity of the cuckoo filter in MB, the default is 256MB + cuckoofilter_capacity = 1 + ; The length of each element of the cuckoo filter (bits), default 64bits + cuckoofilter_tagBits = 64 + ; The number of buckets for the cuckoo filter, the default is 4 + cuckoofilter_buckets_num = 4 + ; When the cuckoo filter replaces an element, the maximum number of element replacements allowed + cuckoofilter_max_kick_out_count = 20 + ; The trash-bucket-size for the cuckoo-filter + trash_bucket_size = 10000 + ; The cuckoo filter capacity that can be cached in memory in MB + cuckoofilter_cache_size = 256 + ; Cache size in MB + psi_cache_size = 1024 + ; When reading large files, the line size loaded into memory each time, default is 100w, -1 means load the max-size-of data + ; data_batch_size = 1000000 + ; use hdfs to store the cuckoo-filter or not + use_hdfs = false + +[ecdh-psi] + ; When reading large files, the line size loaded into memory each time, default is 100w, -1 means load the max-size-of data + ; data_batch_size = 1000000 + +[cm2020-psi] + ; Number of tasks that can be executed concurrently + parallelism = 3 + +[log] + enable=true + log_path=./log + ; info debug trace + level=debug + ; MB + max_log_file_size=200 + ; LineID, TimeStamp, ProcessID, ThreadName, ThreadID and Message + ;format=%Severity%|ppcs-psi4ef|system-id|%TimeStamp%|%ThreadName%-%ThreadID%|%Message% + format=%Severity%|%TimeStamp%|%Message% + enable_rotate_by_hour=true + log_name_pattern=ppcs-psi4ef.log + ; Y,m,d,H,M,S are supported, N is the sequence number log_%Y%m%d.%H%M%S.%N.log + rotate_name_pattern=log_%Y%m%d.%H%M.log + ; if archive_path is empty, the archive function will be disabled + ; archive_path=./log/ + compress_archive_file=true + ; 0: no limit, in MB + ; max_archive_files=10 + ; min_free_space=0 \ No newline at end of file diff --git a/cpp/tools/ppc-builder/src/tpl/krb5.conf b/cpp/tools/ppc-builder/src/tpl/krb5.conf new file mode 100644 index 00000000..6e612c20 --- /dev/null +++ b/cpp/tools/ppc-builder/src/tpl/krb5.conf @@ -0,0 +1,17 @@ +[libdefaults] + default_realm = NODE.DC1.CONSUL + dns_lookup_realm = false + dns_lookup_kdc = false + ticket_lifetime = 24h + renew_lifetime = 7d + forwardable = true + +[realms] + NODE.DC1.CONSUL = { + kdc = + admin_server = + } + +[domain_realm] + .node.dc1.consul = NODE.DC1.CONSUL + node.dc1.consul = NODE.DC1.CONSUL diff --git a/cpp/tools/ppc-builder/src/tpl/start.sh b/cpp/tools/ppc-builder/src/tpl/start.sh new file mode 100755 index 00000000..83921a4c --- /dev/null +++ b/cpp/tools/ppc-builder/src/tpl/start.sh @@ -0,0 +1,39 @@ +#!/bin/bash +SHELL_FOLDER=$(cd $(dirname $0);pwd) + +LOG_ERROR() { + content=${1} + echo -e "\033[31m[ERROR] ${content}\033[0m" +} + +LOG_INFO() { + content=${1} + echo -e "\033[32m[INFO] ${content}\033[0m" +} + +binary=${SHELL_FOLDER}/../@BINARY_NAME@ +cd ${SHELL_FOLDER} +node=$(basename ${SHELL_FOLDER}) +node_pid=$(ps aux|grep ${binary}|grep -v grep|awk '{print $2}') +if [ ! -z ${node_pid} ];then + echo " ${node} is running, pid is $node_pid." + exit 0 +else + nohup ${binary} -c config.ini >>nohup.out 2>&1 & + sleep 1.5 +fi +try_times=4 +i=0 +while [ $i -lt ${try_times} ] +do + node_pid=$(ps aux|grep ${binary}|grep -v grep|awk '{print $2}') + success_flag=$(tail -n20 nohup.out | grep running) + if [[ ! -z ${node_pid} && ! -z "${success_flag}" ]];then + echo -e "\033[32m ${node} start successfully pid=${node_pid}\033[0m" + exit 0 + fi + sleep 0.5 + ((i=i+1)) +done +echo -e "\033[31m Exceed waiting time. Please try again to start ${node} \033[0m" +tail -n20 nohup.out diff --git a/cpp/tools/ppc-builder/src/tpl/start_all.sh b/cpp/tools/ppc-builder/src/tpl/start_all.sh new file mode 100644 index 00000000..b0e20f1b --- /dev/null +++ b/cpp/tools/ppc-builder/src/tpl/start_all.sh @@ -0,0 +1,13 @@ +#!/bin/bash +dirpath="$(cd "$(dirname "$0")" && pwd)" +cd "${dirpath}" + +dirs=($(ls -l ${dirpath} | awk '/^d/ {print $NF}')) +for dir in ${dirs[*]} +do + if [[ -f "${dirpath}/${dir}/config.ini" && -f "${dirpath}/${dir}/start.sh" ]];then + echo "try to start ${dir}" + bash ${dirpath}/${dir}/start.sh & + fi +done +wait diff --git a/cpp/tools/ppc-builder/src/tpl/stop.sh b/cpp/tools/ppc-builder/src/tpl/stop.sh new file mode 100755 index 00000000..ae40e5ba --- /dev/null +++ b/cpp/tools/ppc-builder/src/tpl/stop.sh @@ -0,0 +1,35 @@ +#!/bin/bash +SHELL_FOLDER=$(cd $(dirname $0);pwd) + +LOG_ERROR() { + content=${1} + echo -e "\033[31m[ERROR] ${content}\033[0m" +} + +LOG_INFO() { + content=${1} + echo -e "\033[32m[INFO] ${content}\033[0m" +} + +binary=${SHELL_FOLDER}/../@BINARY_NAME@ +node=$(basename ${SHELL_FOLDER}) +node_pid=$(ps aux|grep ${binary}|grep -v grep|awk '{print $2}') +try_times=10 +i=0 +if [ -z ${node_pid} ];then + echo " ${node} isn't running." + exit 0 +fi +[ ! -z ${node_pid} ] && kill ${node_pid} > /dev/null +while [ $i -lt ${try_times} ] +do + sleep 1 + node_pid=$(ps aux|grep ${binary}|grep -v grep|awk '{print $2}') + if [ -z ${node_pid} ];then + echo -e "\033[32m stop ${node} success.\033[0m" + exit 0 + fi + ((i=i+1)) +done +echo " Exceed maximum number of retries. Please try again to stop ${node}" +exit 1 diff --git a/cpp/tools/ppc-builder/src/tpl/stop_all.sh b/cpp/tools/ppc-builder/src/tpl/stop_all.sh new file mode 100644 index 00000000..63cc7f48 --- /dev/null +++ b/cpp/tools/ppc-builder/src/tpl/stop_all.sh @@ -0,0 +1,13 @@ +#!/bin/bash +dirpath="$(cd "$(dirname "$0")" && pwd)" +cd "${dirpath}" + +dirs=($(ls -l ${dirpath} | awk '/^d/ {print $NF}')) +for dir in ${dirs[*]} +do + if [[ -f "${dirpath}/${dir}/config.ini" && -f "${dirpath}/${dir}/stop.sh" ]];then + echo "try to stop ${dir}" + bash ${dirpath}/${dir}/stop.sh + fi +done +wait diff --git a/cpp/vcpkg b/cpp/vcpkg new file mode 160000 index 00000000..51b14cd4 --- /dev/null +++ b/cpp/vcpkg @@ -0,0 +1 @@ +Subproject commit 51b14cd4e1230dd51c11ffeff6f7d53c61cc5297 diff --git a/cpp/vcpkg-configuration.json b/cpp/vcpkg-configuration.json new file mode 100644 index 00000000..e62c646e --- /dev/null +++ b/cpp/vcpkg-configuration.json @@ -0,0 +1,19 @@ +{ + "registries": [ + { + "kind": "git", + "repository": "https://github.com/FISCO-BCOS/registry", + "baseline": "d45a1d99c6b01713252bcb734c03f2c1ac0e44b8", + "packages": [ + "openssl", + "bcos-utilities", + "bcos-boostssl", + "tarscpp", + "libhdfs3", + "tbb", + "gsasl", + "krb5" + ] + } + ] +} diff --git a/cpp/vcpkg.json b/cpp/vcpkg.json new file mode 100644 index 00000000..a1f68255 --- /dev/null +++ b/cpp/vcpkg.json @@ -0,0 +1,164 @@ +{ + "name": "wedpr-component", + "version-string": "3.0.0", + "homepage": "https://github.com/WeBankBlockchain/WeDPR-Component", + "description": "wedpr component", + "dependencies": [ + { + "name": "vcpkg-cmake", + "host": true + }, + { + "name": "vcpkg-cmake-config", + "host": true + }, + { + "name": "bcos-utilities", + "version>=": "1.0.0" + }, + "zlib" + ], + "builtin-baseline": "51b14cd4e1230dd51c11ffeff6f7d53c61cc5297", + "overrides": [ + { + "name": "seal", + "version": "4.0.0" + }, + { + "name": "kuku", + "version": "2.1#3" + }, + { + "name": "libhdfs3", + "version": "2024-11-29#0" + }, + { + "name": "tbb", + "version": "2021.8.0" + }, + { + "name": "tarscpp", + "version": "3.0.3-1#1" + }, + { + "name": "libsodium", + "version": "1.0.18#9" + }, + { + "name": "grpc", + "version": "1.51.1#1" + }, + { + "name": "jsoncpp", + "version": "1.9.5" + }, + { + "name":"gsasl", + "version": "2.2.1-no-gssapi#0" + }, + { + "name": "libxml2", + "version": "2.11.5#1" + } + ], + "features": { + "sse-libhdfs3": { + "description": "Enable SSE4.2 for libhdfs3", + "dependencies":[ + { + "name": "libhdfs3", + "version>=": "2024-04-27#1", + "features": ["sse"] + } + ] + }, + "default-libhdfs3": { + "description": "Disable SSE4.2 for libhdfs3", + "dependencies":[ + { + "name": "libhdfs3", + "version>=": "2024-04-27#1", + "features": [] + } + ] + }, + "cpufeatures":{ + "description": "Enable cpu features", + "dependencies": [ + { + "name": "cpu-features", + "version>=": "0.9.0" + } + ] + }, + "all": { + "description": "all dependencies", + "dependencies": [ + { + "name": "bcos-boostssl", + "version>=": "3.2.3" + }, + { + "name": "seal", + "version>=": "4.0.0", + "features": ["no-throw-tran"] + }, + { + "name": "kuku", + "version>=": "2.1" + }, + { + "name": "redis-plus-plus", + "version>=": "1.3.6" + }, + { + "name": "mysql-connector-cpp", + "version>=": "8.0.32" + }, + { + "name": "grpc", + "features": ["codegen"], + "version>=": "1.51.1" + }, + { + "name": "bcos-boostssl", + "version>=": "3.2.3" + }, + { + "name": "libxml2", + "version>=": "2.11.5#1", + "features": ["lzma", "zlib"] + }, + "tarscpp", + "tbb", + "gsasl" + ] + }, + "sdk": { + "description": "sdk dependencies", + "dependencies": [ + { + "name": "openssl", + "version>=": "1.1.1-tassl" + }, + "libsodium", + { + "name": "libsodium", + "version>=": "1.0.18" + } + ] + }, + "toolkit": { + "description": "tooklit dependencies", + "dependencies": [ + { + "name": "grpc", + "version>=": "1.51.1" + }, + "tarscpp", + "jsoncpp", + "tbb" + ] + } + } +} diff --git a/cpp/wedpr-computing/ppc-cem/CMakeLists.txt b/cpp/wedpr-computing/ppc-cem/CMakeLists.txt new file mode 100644 index 00000000..c846ec95 --- /dev/null +++ b/cpp/wedpr-computing/ppc-cem/CMakeLists.txt @@ -0,0 +1,8 @@ +project(ppc-cem VERSION ${VERSION}) +add_subdirectory(src) + +if (TESTS) + enable_testing() + set(CTEST_OUTPUT_ON_FAILURE TRUE) + add_subdirectory(tests) +endif() diff --git a/cpp/wedpr-computing/ppc-cem/src/CEMService.cpp b/cpp/wedpr-computing/ppc-cem/src/CEMService.cpp new file mode 100644 index 00000000..9e2734c5 --- /dev/null +++ b/cpp/wedpr-computing/ppc-cem/src/CEMService.cpp @@ -0,0 +1,371 @@ +/* + * Copyright (C) 2022 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 CEMService.cpp + * @author: caryliao + * @date 2022-11-04 + */ + +#include "CEMService.h" +#include "ppc-framework/io/DataResourceLoader.h" +#include "ppc-io/src/DataResourceLoaderImpl.h" +#include "ppc-io/src/FileLineReader.h" +#include "ppc-io/src/FileLineWriter.h" +#include "ppc-storage/src/FileStorageFactoryImpl.h" +#include "wedpr_ffi_c_equality.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace ppc; +using namespace ppc::cem; +using namespace bcos; +using namespace ppc::io; +using namespace ppc::protocol; +using namespace ppc::tools; +using namespace ppc::storage; + +void CEMService::doCipherTextEqualityMatch(const Json::Value::Members& fieldNames, + const std::vector& fieldValues, LineReader::Ptr lineReader, + Json::Value& matchCount) +{ + auto fieldNameLine = (lineReader->next(1))->get(0); + std::vector fileFieldNames; + // obtain the fieldName + boost::split(fileFieldNames, fieldNameLine, boost::is_any_of(",")); + std::vector matchFieldColumnIndexs; + // obtain the field that need to be matched, put it into matchFieldColumnIndexs + for (size_t i = 0; i < fileFieldNames.size(); i++) + { + for (auto fieldName : fieldNames) + { + auto fileFieldName = fileFieldNames.at(i); + boost::algorithm::trim(fieldName); + boost::algorithm::trim(fileFieldName); + if (fieldName == fileFieldName) + { + matchFieldColumnIndexs.emplace_back(i); + } + } + } + uint64_t lineSize = 0; + for (auto fieldName : fieldNames) + { + matchCount[fieldName] = 0; + } + // record the match-result + std::vector> matchCountResult(matchFieldColumnIndexs.size()); + int64_t readPerBatchLines = m_cemConfig.readPerBatchLines; + while (true) + { + // batch read dataset line + auto dataBatch = lineReader->next(readPerBatchLines); + if (!dataBatch) + { + break; + } + lineSize += dataBatch->size(); + // paraller for handle ciphtertext match in dataset + tbb::parallel_for( + tbb::blocked_range(0U, dataBatch->size()), [&](auto const& range) { + for (auto i = range.begin(); i < range.end(); i++) + { + auto fileLine = dataBatch->get(i); + // erase windows \r character + fileLine.erase( + std::remove(fileLine.begin(), fileLine.end(), '\r'), fileLine.end()); + std::vector fileFieldValues; + boost::split(fileFieldValues, fileLine, boost::is_any_of(",")); + tbb::parallel_for(tbb::blocked_range(0U, matchFieldColumnIndexs.size()), + [&](auto const& range) { + for (auto j = range.begin(); j < range.end(); j++) + { + // auto startT = utcSteadyTime(); + auto decodedRequestValue = fromHexString(fieldValues.at(j)); + auto decodedFileValue = + fromHexString(fileFieldValues.at(matchFieldColumnIndexs.at(j))); + CInputBuffer inputBuffer1{ + (const char*)decodedRequestValue->data(), CIPHERTEXT_LEN}; + CInputBuffer inputBuffer2{ + (const char*)decodedFileValue->data(), CIPHERTEXT_LEN}; + auto matchResult = wedpr_pairing_bls128_equality_test( + &inputBuffer1, &inputBuffer2); + // CEM_LOG(INFO) << LOG_DESC("match once ok") + // << LOG_KV("timecost(ms)", utcSteadyTime() - startT); + if (matchResult == WEDPR_SUCCESS) + { + (matchCountResult[j]).fetch_add(1, std::memory_order_relaxed); + } + } + }); + } + }); + } + // assign the result + for (uint64_t i = 0; i < matchFieldColumnIndexs.size(); i++) + { + auto fieldName = fileFieldNames.at(matchFieldColumnIndexs.at(i)); + boost::algorithm::trim(fieldName); + matchCount[fieldName] = matchCountResult[i].load(); + } + CEM_LOG(INFO) << LOG_DESC("match dataset file ok") << LOG_KV("file lines", lineSize); +} + +void CEMService::makeCiphertextEqualityMatch( + Json::Value const& request, Json::Value& response, DataResourceType _type) +{ + auto startT = utcSteadyTime(); + tbb::parallel_for(tbb::blocked_range(0U, request.size()), [&](auto const& range) { + for (auto i = range.begin(); i < range.end(); i++) + { + auto datasetId = request[(Json::ArrayIndex)i]["dataset_id"].asString(); + auto matchField = request[(Json::ArrayIndex)i]["match_field"]; + Json::Value result; + result["dataset_id"] = datasetId; + auto fieldNames = matchField.getMemberNames(); + std::vector fieldValues; + for (auto fieldName : fieldNames) + { + const std::string fieldValue = matchField[fieldName].asString(); + fieldValues.emplace_back(fieldValue); + } + Json::Value matchCount; + auto linereader = initialize_lineReader(datasetId, _type); + doCipherTextEqualityMatch(fieldNames, fieldValues, linereader, matchCount); + result["match_count"] = matchCount; + response[(Json::ArrayIndex)i] = result; + } + }); + CEM_LOG(INFO) << LOG_DESC("ciphertext equality match request handle ok") + << LOG_KV("timecost(ms)", utcSteadyTime() - startT); +} + +void CEMService::makeCiphertextEqualityMatchRpc(Json::Value const& request, RespFunc func) +{ + Json::Value response(Json::arrayValue); + response.resize((Json::ArrayIndex)request.size()); + makeCiphertextEqualityMatch(request, response, DataResourceType::HDFS); + func(nullptr, std::move(response)); +} + +void CEMService::doEncryptDataset(LineReader::Ptr lineReader, LineWriter::Ptr lineWriter) +{ + try + { + auto fieldNameLine = (lineReader->next(1))->get(0); + auto dataBatchFieldName = std::make_shared(); + // erase windows \r character + fieldNameLine.erase( + std::remove(fieldNameLine.begin(), fieldNameLine.end(), '\r'), fieldNameLine.end()); + dataBatchFieldName->append(fieldNameLine); + lineWriter->writeLine(dataBatchFieldName, DataSchema::String, "\n"); + uint64_t lineSize = 0; + int64_t readPerBatchLines = m_cemConfig.readPerBatchLines; + while (true) + { + // batch read dataset line + auto dataBatch = lineReader->next(readPerBatchLines); + if (!dataBatch) + { + break; + } + lineSize += dataBatch->size(); + auto ciphertextFileLines = std::make_shared(); + ciphertextFileLines->resize(dataBatch->size()); + // parallel for handle encrypt dataset + tbb::parallel_for(tbb::blocked_range(0U, dataBatch->size()), [&](auto const& + range) { + for (auto i = range.begin(); i < range.end(); i++) + { + auto fileLine = dataBatch->get(i); + // erase windows \r character + fileLine.erase( + std::remove(fileLine.begin(), fileLine.end(), '\r'), fileLine.end()); + std::vector fileFieldValues; + boost::split(fileFieldValues, fileLine, boost::is_any_of(",")); + std::ostringstream ciphertextFileLine; + for (uint64_t i = 0; i < fileFieldValues.size(); i++) + { + // id in index 0, need not be encrypted + auto fieldValue = fileFieldValues.at(i); + boost::algorithm::trim(fieldValue); + if (i == 0) + { + ciphertextFileLine << fieldValue; + } + else + { + // auto startT = utcSteadyTime(); + const char* plaintext = fieldValue.data(); + CInputBuffer inputBuffer{plaintext, fieldValue.size()}; + auto ciphertext = std::make_shared(); + ciphertext->resize(CIPHERTEXT_LEN); + COutputBuffer outputBuffer{(char*)ciphertext->data(), CIPHERTEXT_LEN}; + auto encryptResult = + wedpr_pairing_bls128_encrypt_message(&inputBuffer, &outputBuffer); + // << LOG_KV("timecost(ms)", utcSteadyTime() - startT); + if (encryptResult == WEDPR_SUCCESS) + { + auto ciphertextHexStr = *toHexString(*ciphertext); + ciphertextFileLine << "," << ciphertextHexStr; + } + else + { + BOOST_THROW_EXCEPTION( + OpenDatasetFileFailException() + << errinfo_comment("encrypt dataset file fail")); + } + } + } + ciphertextFileLines->set(i, ciphertextFileLine.str()); + } + }); + lineWriter->writeLine(ciphertextFileLines, DataSchema::String, "\n"); + } + lineWriter->close(); + CEM_LOG(INFO) << LOG_DESC("encrypt dataset file ok") << LOG_KV("file lines", lineSize); + } + catch (const char*& e) + { + CEM_LOG(INFO) << LOG_KV("doEncryptDataset", e); + } +} + +void CEMService::encryptDataset(Json::Value const& request, Json::Value& response) +{ + // parallel for handle dataset + auto startT = utcSteadyTime(); + tbb::parallel_for(tbb::blocked_range(0U, request.size()), [&](auto const& range) { + for (auto i = range.begin(); i < range.end(); i++) + { + const std::string datasetId = request[(Json::ArrayIndex)i].asString(); + auto linereader = initialize_lineReader(datasetId, DataResourceType::HDFS); + auto linewriter = initialize_lineWriter(datasetId, DataResourceType::HDFS); + doEncryptDataset(linereader, linewriter); + renameSource(datasetId, DataResourceType::HDFS); + response[(Json::ArrayIndex)i] = datasetId + m_cemConfig.ciphertextSuffix; + } + }); + CEM_LOG(INFO) << LOG_DESC("encrypt dataset request handle ok") + << LOG_KV("timecost(ms)", utcSteadyTime() - startT); +} + +void CEMService::encryptDatasetRpc(Json::Value const& request, RespFunc func) +{ + Json::Value response; + encryptDataset(request, response); + func(nullptr, std::move(response)); +} + +LineReader::Ptr CEMService::initialize_lineReader( + const std::string& _datasetId, DataResourceType _type) +{ + std::string file_to = m_cemConfig.datasetFilePath + "/" + _datasetId; + auto factory = std::make_shared(); + auto dataResourceLoader = std::make_shared( + nullptr, nullptr, nullptr, nullptr, factory, nullptr); + const auto dataResource = std::make_shared(); + dataResource->setResourceID(_datasetId); + const auto dataResourceDesc = std::make_shared(); + dataResourceDesc->setType((int)_type); + if ((int)_type == (int)DataResourceType::HDFS) + { + file_to = m_cemConfig.datasetHDFSPath + "/" + _datasetId; + dataResourceDesc->setFileStorageConnectOption(m_storageConfig.fileStorageConnectionOpt); + } + else if ((int)_type == (int)DataResourceType::FILE) + { + file_to = m_cemConfig.datasetFilePath + "/" + _datasetId; + } + dataResourceDesc->setPath(file_to); + dataResource->setDesc(dataResourceDesc); + return dataResourceLoader->loadReader(dataResource->desc()); +} + +LineWriter::Ptr CEMService::initialize_lineWriter( + const std::string& _datasetId, DataResourceType _type) +{ + std::string file_to = + m_cemConfig.datasetFilePath + "/" + _datasetId + m_cemConfig.ciphertextSuffix; + auto factory = std::make_shared(); + auto dataResourceLoader = std::make_shared( + nullptr, nullptr, nullptr, nullptr, factory, nullptr); + const auto dataResource = std::make_shared(); + dataResource->setResourceID(_datasetId); + const auto dataResourceDesc = std::make_shared(); + dataResourceDesc->setType((int)_type); + if ((int)_type == (int)DataResourceType::HDFS) + { + file_to = m_cemConfig.datasetHDFSPath + "/" + _datasetId + m_cemConfig.ciphertextSuffix; + dataResourceDesc->setFileStorageConnectOption(m_storageConfig.fileStorageConnectionOpt); + } + else if ((int)_type == (int)DataResourceType::FILE) + { + file_to = m_cemConfig.datasetFilePath + "/" + _datasetId + m_cemConfig.ciphertextSuffix; + } + dataResourceDesc->setPath(file_to); + dataResource->setOutputDesc(dataResourceDesc); + return dataResourceLoader->loadWriter(dataResource->outputDesc()); +} + +void CEMService::renameSource(const std::string& _datasetId, DataResourceType _type) +{ + if ((int)_type == (int)DataResourceType::HDFS) + { + std::string from_file = + m_cemConfig.datasetHDFSPath + "/" + _datasetId + m_cemConfig.ciphertextSuffix; + std::string to_file = m_cemConfig.datasetHDFSPath + "/" + _datasetId; + auto factory = std::make_shared(); + auto dataResourceLoader = std::make_shared( + nullptr, nullptr, nullptr, nullptr, factory, nullptr); + const auto dataResource = std::make_shared(); + dataResource->setResourceID(_datasetId); + const auto dataResourceDesc = std::make_shared(); + dataResourceDesc->setType((int)_type); + dataResourceDesc->setFileStorageConnectOption(m_storageConfig.fileStorageConnectionOpt); + dataResourceDesc->setPath(from_file); + dataResource->setOutputDesc(dataResourceDesc); + dataResourceLoader->renameResource(dataResource->outputDesc(), to_file); + } + else if ((int)_type == (int)DataResourceType::FILE) + { + std::string from_file = + m_cemConfig.datasetFilePath + "/" + _datasetId + m_cemConfig.ciphertextSuffix; + std::string to_file = m_cemConfig.datasetFilePath + "/" + _datasetId; + if (boost::filesystem::exists(from_file)) + { + boost::filesystem::remove(from_file); + } + boost::filesystem::rename(from_file, to_file); + } +} + + +void CEMService::setCEMConfig(CEMConfig const& cemConfig) +{ + m_cemConfig = cemConfig; +} + +void CEMService::setStorageConfig(StorageConfig const& storageConfig) +{ + m_storageConfig = storageConfig; +} \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-cem/src/CEMService.h b/cpp/wedpr-computing/ppc-cem/src/CEMService.h new file mode 100644 index 00000000..52be9c1d --- /dev/null +++ b/cpp/wedpr-computing/ppc-cem/src/CEMService.h @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2022 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 CEMService.h + * @author: caryliao + * @date 2022-11-04 + */ +#pragma once +#include "Common.h" +#include "ppc-framework/rpc/RpcInterface.h" +#include "ppc-io/src/FileLineReader.h" +#include "ppc-io/src/FileLineWriter.h" +#include "ppc-tools/src/config/CEMConfig.h" +#include "ppc-tools/src/config/StorageConfig.h" +#include +#include +namespace ppc::cem +{ +class CEMService +{ +public: + using Ptr = std::shared_ptr; + CEMService() = default; + virtual ~CEMService() = default; + + void makeCiphertextEqualityMatchRpc(Json::Value const& request, ppc::rpc::RespFunc func); + void makeCiphertextEqualityMatch( + Json::Value const& request, Json::Value& response, ppc::protocol::DataResourceType _type); + void encryptDatasetRpc(Json::Value const& request, ppc::rpc::RespFunc func); + void encryptDataset(Json::Value const& request, Json::Value& response); + + void setCEMConfig(ppc::tools::CEMConfig const& cemConfig); + void setStorageConfig(ppc::tools::StorageConfig const& storageConfig); + void doCipherTextEqualityMatch(const Json::Value::Members& fieldNames, + const std::vector& fieldValues, ppc::io::LineReader::Ptr lineReader, + Json::Value& matchCount); + void doEncryptDataset(ppc::io::LineReader::Ptr lineReader, ppc::io::LineWriter::Ptr lineWriter); + ppc::io::LineReader::Ptr initialize_lineReader( + const std::string& _datasetId, ppc::protocol::DataResourceType _type); + ppc::io::LineWriter::Ptr initialize_lineWriter( + const std::string& _datasetId, ppc::protocol::DataResourceType _type); + void renameSource(const std::string& _datasetId, ppc::protocol::DataResourceType _type); + +private: + ppc::tools::CEMConfig m_cemConfig; + ppc::tools::StorageConfig m_storageConfig; +}; +} // namespace ppc::cem \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-cem/src/CMakeLists.txt b/cpp/wedpr-computing/ppc-cem/src/CMakeLists.txt new file mode 100644 index 00000000..ccb4451b --- /dev/null +++ b/cpp/wedpr-computing/ppc-cem/src/CMakeLists.txt @@ -0,0 +1,6 @@ +file(GLOB_RECURSE SOURCES "*.cpp" "*.h") + +set(FFI_CEM_LIBRARY ${CMAKE_SOURCE_DIR}/deps/lib/libffi_c_equality.a) + +add_library(${CEM_TARGET} ${SOURCES}) +target_link_libraries(${CEM_TARGET} PUBLIC ${FFI_CEM_LIBRARY} ${IO_TARGET} TBB::tbb) diff --git a/cpp/wedpr-computing/ppc-cem/src/Common.h b/cpp/wedpr-computing/ppc-cem/src/Common.h new file mode 100644 index 00000000..c1f9bc59 --- /dev/null +++ b/cpp/wedpr-computing/ppc-cem/src/Common.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2022 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 Common.h + * @author: caryliao + * @date 2022-11-03 + */ +#pragma once +#include "ppc-framework/Common.h" +#include + +#define CEM_LOG(LEVEL) BCOS_LOG(LEVEL) << LOG_BADGE("CM") + +namespace ppc::cem +{ +const size_t CIPHERTEXT_LEN = 144; +DERIVE_PPC_EXCEPTION(OpenDatasetFileFailException); +DERIVE_PPC_EXCEPTION(CipherMatchFailException); +} // namespace ppc::cem \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-cem/src/WedprUtilities.h b/cpp/wedpr-computing/ppc-cem/src/WedprUtilities.h new file mode 100644 index 00000000..856d4769 --- /dev/null +++ b/cpp/wedpr-computing/ppc-cem/src/WedprUtilities.h @@ -0,0 +1,28 @@ +#ifndef _WEDPR_UTILITIES_H_ +#define _WEDPR_UTILITIES_H_ + +#include +#include +#include +#include +#include + +extern "C" { + +struct CInputBuffer +{ + const char* data; + uintptr_t len; +}; + +struct COutputBuffer +{ + char* data; + uintptr_t len; +}; + +const int8_t WEDPR_ERROR = -1; +const int8_t WEDPR_SUCCESS = 0; +} // extern "C" + +#endif diff --git a/cpp/wedpr-computing/ppc-cem/src/wedpr_ffi_c_equality.h b/cpp/wedpr-computing/ppc-cem/src/wedpr_ffi_c_equality.h new file mode 100644 index 00000000..8bbd8fdf --- /dev/null +++ b/cpp/wedpr-computing/ppc-cem/src/wedpr_ffi_c_equality.h @@ -0,0 +1,25 @@ +#ifndef _WEDPR_CRYPTO_H_ +#define _WEDPR_CRYPTO_H_ + +#include +#include +#include +#include + +#include "WedprUtilities.h" + +extern "C" { +/** + * C interface for 'encrypt_message'. + */ +int8_t wedpr_pairing_bls128_encrypt_message( + const CInputBuffer* raw_plaintext, COutputBuffer* output_ciphertext); + +/** + * C interface for 'equality_test'. + */ +int8_t wedpr_pairing_bls128_equality_test( + const CInputBuffer* raw_cipher1, const CInputBuffer* raw_cipher2); +} + +#endif diff --git a/cpp/wedpr-computing/ppc-cem/tests/CMakeLists.txt b/cpp/wedpr-computing/ppc-cem/tests/CMakeLists.txt new file mode 100644 index 00000000..ae572c6c --- /dev/null +++ b/cpp/wedpr-computing/ppc-cem/tests/CMakeLists.txt @@ -0,0 +1,11 @@ +file(GLOB_RECURSE SOURCES "*.cpp" "*.h") + +# cmake settings +set(TEST_BINARY_NAME test-ppc-cem) + +add_executable(${TEST_BINARY_NAME} ${SOURCES}) +target_include_directories(${TEST_BINARY_NAME} PRIVATE .) + +# target_link_libraries(${TEST_BINARY_NAME} ${CEM_TARGET} ${BCOS_UTILITIES_TARGET} jsoncpp_static ${BOOST_UNIT_TEST}) +target_link_libraries(${TEST_BINARY_NAME} ${CEM_TARGET} ${RPC_TARGET} ${BOOST_UNIT_TEST}) +add_test(NAME test-cem WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} COMMAND ${TEST_BINARY_NAME}) diff --git a/cpp/wedpr-computing/ppc-cem/tests/TestCEMService.cpp b/cpp/wedpr-computing/ppc-cem/tests/TestCEMService.cpp new file mode 100644 index 00000000..5214af38 --- /dev/null +++ b/cpp/wedpr-computing/ppc-cem/tests/TestCEMService.cpp @@ -0,0 +1,136 @@ +/* + * Copyright (C) 2022 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 applicabl 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 TestCEMService.cpp + * @author: caryliao + * @date 2022-11-19 + */ +#include "ppc-cem/src/CEMService.h" +#include "ppc-cem/src/Common.h" +#include +#include + +using namespace ppc::cem; +using namespace bcos; +using namespace bcos::test; + +namespace ppc::test +{ +BOOST_FIXTURE_TEST_SUITE(cMServiceTest, TestPromptFixture) + +BOOST_AUTO_TEST_CASE(testCEMService) +{ + auto cemService = std::make_shared(); + std::string configPath{"../../../../wedpr-computing/ppc-cem/tests/data/config.ini"}; + boost::property_tree::ptree pt; + boost::property_tree::read_ini(configPath, pt); + // load the cm config + auto ppcConfig = std::make_shared(); + ppcConfig->loadCEMConfig(pt); + auto cemConfig = ppcConfig->cemConfig(); + auto storageConfig = ppcConfig->storageConfig(); + cemService->setCEMConfig(cemConfig); + cemService->setStorageConfig(storageConfig); + + // d1 encrypted + std::string all_datasets[3] = {"d1", "d2", "d3"}; + for (int i = 0; i < 3; i++) + { + std::string datasetId = all_datasets[i]; + std::string encrypted_file = + cemConfig.datasetFilePath + "/" + datasetId + cemConfig.ciphertextSuffix; + if (boost::filesystem::exists(encrypted_file)) + { + boost::filesystem::remove(encrypted_file); + } + auto linereader = + cemService->initialize_lineReader(datasetId, ppc::protocol::DataResourceType::FILE); + auto linewriter = + cemService->initialize_lineWriter(datasetId, ppc::protocol::DataResourceType::FILE); + cemService->doEncryptDataset(linereader, linewriter); + } + + // d1 matched + Json::Value request2(Json::arrayValue); + + Json::Value param1; + param1["dataset_id"] = "d1-encrypted"; + Json::Value matchField1; + matchField1["x1"] = + "b53d3973005bd84da8367d4d247946b00ed269454d8799608631262862b3ee2a912fa42e1e71af77236ad851ea" + "e44f0c91a674f59469a47c0d8cac7385009d22f012f44f3477ad254a91f3ef07b7a2fc2c78012b2538a9052ce0" + "53dd884ffe2914f7027ae7d545b050426f12f8f225a058a4c609773d0ae7cc73e103954790b7d52a398a88e42e" + "dd8a006cf1325828b9"; + matchField1["x2"] = + "8357af78f88dfbe857bc4eb6801b83714d3f3127bdd4e68bbc17444fe8783686dd36ab44f9b80fb6c173ef0fb1" + "8c22e093216884966cd61c3723c987d91471c76a449d18070358862ebdc50c5d326035c1c188b5642baba5f3f6" + "37a7b5aec5fc054fe607cd0fad22e75468c47dd30a74af05f42a84ba73adf7f277fe94a8f4cd42b23563bbbe42" + "a1e493f44a65f1c52c"; + param1["match_field"] = matchField1; + + Json::Value param2; + param2["dataset_id"] = "d2-encrypted"; + Json::Value matchField2; + matchField2["x1"] = + "971a80d65f1983e14a5bd33347237adadd8e8586ac766d1e06e68bde9957032e009cab0c3501cb3d620aefab4c" + "063fc9b43d2bedd7b0ddc9c5b24d53fa2e35cd41b689350e417df8cb24ce9e585501c04c9535bd2525d02f5397" + "c60ed353358916b585666d0f124df64269151c1f218df4becc79b237124ddda84b64bfa0230b5b012a9a87d28c" + "629d635b0ae84467ab"; + matchField2["x2"] = + "a8374c5e1ca1ef7944ac904491b94d0dafc3c8bb81feaf4f7bff24d9083f8cb459a3181aa454556558ba80ffb9" + "7d91cdaaa17e4e27a75d3835ab69963429aee031b54aa5ecdadbea45566452da568b51aed0b188d1d0ac86ed5e" + "5f665239094e156c1eec61d1d3aa66d98eb004ef3cb870a79cb1fe9ac7c698dcf360d85bfd066b9fd1c9642dd9" + "6960c9bd41027e368b"; + param2["match_field"] = matchField2; + + Json::Value param3; + param3["dataset_id"] = "d3-encrypted"; + Json::Value matchField3; + matchField3["x1"] = + "acf497223d82cf3347d19f00ba4e5e1139c1897e05667186d9c766fa482a4aacaf66b6aecd335bc437e637f8d9" + "b4327f8ed030aec4e047d32cde0b00421a3f31c1857dac3bdfb99700fea524fe3873bfb66809a7ea48f3df251e" + "41dbe27685f10fd525dd18b4e3eabb5e89bba75593439cc73ff19b5afd9f45a2a89407353b0d2b5af875f270dd" + "3d865776216ce194b2"; + matchField3["x2"] = + "a5e604a12f2f06848b626e16cd13d8f74cf866c3963074715b8251ff77fe1c797e40c12785ac872432d814e8df" + "7cd6ad8383c2605111479ddb47941ae27e5e3eb29d1bfd2f2f92b6a7f3c312ddefacf12fc016776d96fbd9998d" + "99399359b11d10641c1d724af6a42659ce0f254a2258af388e8a89c7e7b420a5daa9efb304cdae0ec1c328c6f8" + "5ff3c9fdcbbe29cce8"; + param3["match_field"] = matchField3; + + request2.append(param1); + request2.append(param2); + request2.append(param3); + + Json::Value response2(Json::arrayValue); + response2.resize((Json::ArrayIndex)request2.size()); + cemService->makeCiphertextEqualityMatch( + request2, response2, ppc::protocol::DataResourceType::FILE); + BOOST_CHECK(response2.size() == 3); + uint64_t matchResult = 50; + BOOST_CHECK(response2[(Json::ArrayIndex)0]["dataset_id"].asString() == "d1-encrypted"); + BOOST_CHECK(response2[(Json::ArrayIndex)0]["match_count"]["x1"].asUInt64() == matchResult); + BOOST_CHECK(response2[(Json::ArrayIndex)0]["match_count"]["x2"].asUInt64() == matchResult); + + BOOST_CHECK(response2[(Json::ArrayIndex)1]["dataset_id"].asString() == "d2-encrypted"); + BOOST_CHECK(response2[(Json::ArrayIndex)1]["match_count"]["x1"].asUInt64() == matchResult); + BOOST_CHECK(response2[(Json::ArrayIndex)1]["match_count"]["x2"].asUInt64() == matchResult); + + BOOST_CHECK(response2[(Json::ArrayIndex)2]["dataset_id"].asString() == "d3-encrypted"); + BOOST_CHECK(response2[(Json::ArrayIndex)2]["match_count"]["x1"].asUInt64() == matchResult); + BOOST_CHECK(response2[(Json::ArrayIndex)2]["match_count"]["x2"].asUInt64() == matchResult); +} +BOOST_AUTO_TEST_SUITE_END() +} // namespace ppc::test diff --git a/cpp/wedpr-computing/ppc-cem/tests/data/config.ini b/cpp/wedpr-computing/ppc-cem/tests/data/config.ini new file mode 100644 index 00000000..c9562ec0 --- /dev/null +++ b/cpp/wedpr-computing/ppc-cem/tests/data/config.ini @@ -0,0 +1,70 @@ +[agency] + ; the agency-id of self-party + id = agency + ; the agency info + +[cem] + use_mysql = false + dataset_hdfs_path = /user/ppc/admin + dataset_file_path = ../../../../wedpr-computing/ppc-cem/tests/data + ciphertext_suffix = -encrypted + read_per_batch_lines = 100000 + +[crypto] + sm_crypto = false + +[rpc] + listen_ip=0.0.0.0 + listen_port=5002 + thread_count=4 + ; ssl or sm ssl + sm_ssl=false + ; ssl connection switch, if disable the ssl connection, default: false + ;disable_ssl = true + +; [storage] +; host = 127.0.0.1 +; ; the mysqlx_port +; port = 3306 +; user = root +; password = 12345678 +; database = ppc15 + +[hdfs_storage] + ; the hdfs configuration + user = ppc + name_node = 127.0.0.1 + name_node_port = 9900 + token = + ; enable replace-datanode-on-failure or not + replace-datanode-on-failure = false + ; the connection-timeout, in ms, default is 1000ms + connection-timeout = 2000 + +[cert] + ; directory the certificates located in + cert_path=./conf + +[log] + enable=true + ; print the log to std::cout or not, default print to the log files + enable_console_output = false + log_path=./log + ; info debug trace + level=info + ; MB + max_log_file_size=200 + ; LineID, TimeStamp, ProcessID, ThreadName, ThreadID and Message + #format=%Severity%|ppcs-psi4ef|system-id|%TimeStamp%|%ThreadName%-%ThreadID%|%Message% + #enable_rotate_by_hour=true + #log_name_pattern=ppcs-psi4ef.log + ; Y,m,d,H,M,S are supported, N is the sequence number log_%Y%m%d.%H%M%S.%N.log + #rotate_name_pattern=log_%Y%m%d.%H%M.log + ; if archive_path is empty, the archive function will be disabled + ; archive_path=./log/ + #compress_archive_file=true + ; ; 0: no limit, in MB + ; max_archive_files=10 + ; ; 0: no limit, in MB + ; max_archive_size=0 + ; min_free_space=0 diff --git a/cpp/wedpr-computing/ppc-cem/tests/data/d1 b/cpp/wedpr-computing/ppc-cem/tests/data/d1 new file mode 100644 index 00000000..ff848899 --- /dev/null +++ b/cpp/wedpr-computing/ppc-cem/tests/data/d1 @@ -0,0 +1,101 @@ +id,x1,x2 +1,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +2,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +3,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +4,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +5,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +6,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +7,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +8,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +9,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +10,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +11,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +12,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +13,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +14,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +15,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +16,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +17,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +18,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +19,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +20,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +21,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +22,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +23,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +24,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +25,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +26,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +27,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +28,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +29,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +30,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +31,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +32,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +33,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +34,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +35,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +36,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +37,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +38,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +39,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +40,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +41,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +42,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +43,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +44,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +45,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +46,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +47,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +48,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +49,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +50,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +51,c127b40c158f404aa432656b013bad12,424637e2531f4ddfad8f43d8d3d45f3e +52,f35367150f904fa3ab3442e77355e43a,600d3627245341d580fe078b19450d6d +53,29627c5f37e94779a8ec95322e5afbe1,63533be072f8427ea9ba6d0369163862 +54,a41df047bf2f4e919033441f61d1b7fd,e2382ff5ba01431d9f48e085419ec4ef +55,65db7c7b020d4b0d9229a2ad0ea4c7c5,e775c8b1f7154d119ec8ddbea66cd4bc +56,e749e17a71a2447fac63bca47b6846a7,0045251d24b9466695d5d0c38929ea90 +57,14c697e5bce841878ebf89bf08a9ba14,04317b907cdc4043b8200db5110831c1 +58,38047064e02a4ca4af076ae26aa679f7,9bb62566a45c4d229a4fd795f8777a75 +59,5fb6f18de87043a497f0677537c189bc,2724e3acf012450e8355d84b8b3ece86 +60,b44e260738b343629faaa7d9f549bbcb,94b80d51709d4c5faaee2d78a762bbc4 +61,808af13908c14cd89092219dc37b29cf,1085ef4476aa4635b7d3e78ea67f83c3 +62,af18d05a4e2548468d61ccad12a0340e,2024c88fcc03414a81b64da8409dc8af +63,ba426827999c462b9df669d7e932144c,2b2d0515df814e4f94c1110d3b584ba4 +64,525584d2c08f439eb7bee2db6b91ac37,8188e4aee9354bb2b9fc8536f34b1c24 +65,f1d40891ad90463cb530bcd4fce3b733,1c6bb273297846dbbb920e5409c6e5ff +66,f9f22de01edd4644b6c55ef7a993b184,55adc457cd124274a27ebb830ad3dc66 +67,e4ff7eaa9dd04f149049aa12bf21e68a,0c3fb3b958b14243a3edcd1bc9a51283 +68,71d984a3e0ad42698f3186cfbfdcbd87,0a520b68a33c499b9809ae269a55c394 +69,96d145bc82ff4e2a84551c20ef6f1cc5,affad8d9f1284a5dbdf97ca825288654 +70,fcece0ef256c47fdaa5678e20df0f4a1,623b626acc0b494d90f64879575c51e3 +71,87800bc6aeb5461b869afaba3d7430b3,0825eac882c0486b8316723e722e29cf +72,dd943a94e743432592c68e38352e83c8,3aeb080d0f234cc198b3165baab8d8f5 +73,8f7f6922e81246a680f931c44ecc0d1a,42f4992a390a440a9aa1b440a02e78f5 +74,42d3d9010a7548faa386e83ae61f4802,f4d3dbad28004d759be6229bc2bbff9a +75,01dc4d7631f94ba987e435c87d632684,44bde70d206b4450bde0991d405ab0fa +76,ccea7c284fce4d3988d8948f79b2fef6,04fecfe64b874cc8b2cad3e2bc205317 +77,272d7020324f4fa9a36a31b64ef798fb,c803c1ef9eab459387bb0be0fe6e1e93 +78,c92ee2e67c22477482eb6a9b3492283a,07cf6bbaea12454ba9f8693486df6282 +79,afba2c31d5fb4e658fa16b269bd48179,c55973e7e2f04e96976e99218bf2a8d5 +80,7066d9b40a994cce8b5eb555a3a265c8,6bb406d7c2de40ff828bc6e2a4e97ee9 +81,ce88a3d29e574780a649399794d793bf,b5ac277d1e7242089a30a48d78033ac2 +82,2514054bd2fd42f79ecdbb4b4fac3301,af552fac31434e3b94bdb2dd7087c6e7 +83,1466f1d054284e78b1844dd343bdc095,970e1fd372ee4dacbc5d911a0f556efe +84,21d7c25b139845ea84b8a04dc45a1fc9,d28447da4e5843adadb9845fab94a278 +85,3e451bbe00b34590b0d627d0d17d4aab,8aa5643bab1342ffa4229bef214807d1 +86,d2e635d343a440478e8ae39d5f07c87d,adf9ab5d926c4d48ac33fa301f2e5cd4 +87,2ec3545d3ce84b4290481b4b3d5c9fd2,6c0a1f2b9d124cd1a2e27a419ecfce58 +88,42d37153df1c4e7f9eacf0628f07d22a,695082c3bd6a48a69e74c7435a642b1b +89,403c2018e9b64e7caba38b12ecdb8358,470671bd2e7640c8851426c9ebe4c924 +90,ccb7cefb3efd4a49a6e5e400caf239da,2d73f2af749d4c04990f6464d8d1350d +91,a39164ae87d84d8a8faecdfecfa537f3,1d82ac0af6e1484dbc16b1fe2fde368f +92,908045cc3301407ca0c8818e01eebf5f,92dc6cd19357410e96b60d96238e4f03 +93,ac388e933ba6482fbb5e3505d1a1e18a,4711abe2a1774467901f76dcd4d590b8 +94,5978cdb261304e13ab299f7c4a8bf3ff,d9ea4748b79842888038c71e72061abd +95,7808218f4ea74e57acbb0a913b967d29,d7fc8e21ae6f4d6c8dc0ffdf4e376aab +96,c0cd4c990efc43c18e46c246a1e3382e,8e1a87e86a5d48e593935786aa0cbc38 +97,5c0aaf7f191c4720a343f6d8b8c4704c,2ad4bd183efa49e984302df6cba20956 +98,15d996bfe59a4cc8ab4899e6cce426e2,fd4d20fb799c41a9afdf64b206e08a4e +99,d4a93966765b4a42b1697c8d14881211,36727725990f49a6bd4d92b1ec6424d2 +100,ebf75e2646914039803a59fd2b2e8fd9,e0ae4ddcf5d9424cb949b03882606219 diff --git a/cpp/wedpr-computing/ppc-cem/tests/data/d2 b/cpp/wedpr-computing/ppc-cem/tests/data/d2 new file mode 100644 index 00000000..ff848899 --- /dev/null +++ b/cpp/wedpr-computing/ppc-cem/tests/data/d2 @@ -0,0 +1,101 @@ +id,x1,x2 +1,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +2,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +3,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +4,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +5,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +6,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +7,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +8,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +9,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +10,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +11,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +12,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +13,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +14,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +15,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +16,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +17,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +18,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +19,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +20,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +21,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +22,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +23,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +24,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +25,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +26,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +27,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +28,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +29,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +30,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +31,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +32,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +33,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +34,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +35,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +36,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +37,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +38,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +39,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +40,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +41,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +42,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +43,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +44,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +45,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +46,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +47,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +48,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +49,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +50,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +51,c127b40c158f404aa432656b013bad12,424637e2531f4ddfad8f43d8d3d45f3e +52,f35367150f904fa3ab3442e77355e43a,600d3627245341d580fe078b19450d6d +53,29627c5f37e94779a8ec95322e5afbe1,63533be072f8427ea9ba6d0369163862 +54,a41df047bf2f4e919033441f61d1b7fd,e2382ff5ba01431d9f48e085419ec4ef +55,65db7c7b020d4b0d9229a2ad0ea4c7c5,e775c8b1f7154d119ec8ddbea66cd4bc +56,e749e17a71a2447fac63bca47b6846a7,0045251d24b9466695d5d0c38929ea90 +57,14c697e5bce841878ebf89bf08a9ba14,04317b907cdc4043b8200db5110831c1 +58,38047064e02a4ca4af076ae26aa679f7,9bb62566a45c4d229a4fd795f8777a75 +59,5fb6f18de87043a497f0677537c189bc,2724e3acf012450e8355d84b8b3ece86 +60,b44e260738b343629faaa7d9f549bbcb,94b80d51709d4c5faaee2d78a762bbc4 +61,808af13908c14cd89092219dc37b29cf,1085ef4476aa4635b7d3e78ea67f83c3 +62,af18d05a4e2548468d61ccad12a0340e,2024c88fcc03414a81b64da8409dc8af +63,ba426827999c462b9df669d7e932144c,2b2d0515df814e4f94c1110d3b584ba4 +64,525584d2c08f439eb7bee2db6b91ac37,8188e4aee9354bb2b9fc8536f34b1c24 +65,f1d40891ad90463cb530bcd4fce3b733,1c6bb273297846dbbb920e5409c6e5ff +66,f9f22de01edd4644b6c55ef7a993b184,55adc457cd124274a27ebb830ad3dc66 +67,e4ff7eaa9dd04f149049aa12bf21e68a,0c3fb3b958b14243a3edcd1bc9a51283 +68,71d984a3e0ad42698f3186cfbfdcbd87,0a520b68a33c499b9809ae269a55c394 +69,96d145bc82ff4e2a84551c20ef6f1cc5,affad8d9f1284a5dbdf97ca825288654 +70,fcece0ef256c47fdaa5678e20df0f4a1,623b626acc0b494d90f64879575c51e3 +71,87800bc6aeb5461b869afaba3d7430b3,0825eac882c0486b8316723e722e29cf +72,dd943a94e743432592c68e38352e83c8,3aeb080d0f234cc198b3165baab8d8f5 +73,8f7f6922e81246a680f931c44ecc0d1a,42f4992a390a440a9aa1b440a02e78f5 +74,42d3d9010a7548faa386e83ae61f4802,f4d3dbad28004d759be6229bc2bbff9a +75,01dc4d7631f94ba987e435c87d632684,44bde70d206b4450bde0991d405ab0fa +76,ccea7c284fce4d3988d8948f79b2fef6,04fecfe64b874cc8b2cad3e2bc205317 +77,272d7020324f4fa9a36a31b64ef798fb,c803c1ef9eab459387bb0be0fe6e1e93 +78,c92ee2e67c22477482eb6a9b3492283a,07cf6bbaea12454ba9f8693486df6282 +79,afba2c31d5fb4e658fa16b269bd48179,c55973e7e2f04e96976e99218bf2a8d5 +80,7066d9b40a994cce8b5eb555a3a265c8,6bb406d7c2de40ff828bc6e2a4e97ee9 +81,ce88a3d29e574780a649399794d793bf,b5ac277d1e7242089a30a48d78033ac2 +82,2514054bd2fd42f79ecdbb4b4fac3301,af552fac31434e3b94bdb2dd7087c6e7 +83,1466f1d054284e78b1844dd343bdc095,970e1fd372ee4dacbc5d911a0f556efe +84,21d7c25b139845ea84b8a04dc45a1fc9,d28447da4e5843adadb9845fab94a278 +85,3e451bbe00b34590b0d627d0d17d4aab,8aa5643bab1342ffa4229bef214807d1 +86,d2e635d343a440478e8ae39d5f07c87d,adf9ab5d926c4d48ac33fa301f2e5cd4 +87,2ec3545d3ce84b4290481b4b3d5c9fd2,6c0a1f2b9d124cd1a2e27a419ecfce58 +88,42d37153df1c4e7f9eacf0628f07d22a,695082c3bd6a48a69e74c7435a642b1b +89,403c2018e9b64e7caba38b12ecdb8358,470671bd2e7640c8851426c9ebe4c924 +90,ccb7cefb3efd4a49a6e5e400caf239da,2d73f2af749d4c04990f6464d8d1350d +91,a39164ae87d84d8a8faecdfecfa537f3,1d82ac0af6e1484dbc16b1fe2fde368f +92,908045cc3301407ca0c8818e01eebf5f,92dc6cd19357410e96b60d96238e4f03 +93,ac388e933ba6482fbb5e3505d1a1e18a,4711abe2a1774467901f76dcd4d590b8 +94,5978cdb261304e13ab299f7c4a8bf3ff,d9ea4748b79842888038c71e72061abd +95,7808218f4ea74e57acbb0a913b967d29,d7fc8e21ae6f4d6c8dc0ffdf4e376aab +96,c0cd4c990efc43c18e46c246a1e3382e,8e1a87e86a5d48e593935786aa0cbc38 +97,5c0aaf7f191c4720a343f6d8b8c4704c,2ad4bd183efa49e984302df6cba20956 +98,15d996bfe59a4cc8ab4899e6cce426e2,fd4d20fb799c41a9afdf64b206e08a4e +99,d4a93966765b4a42b1697c8d14881211,36727725990f49a6bd4d92b1ec6424d2 +100,ebf75e2646914039803a59fd2b2e8fd9,e0ae4ddcf5d9424cb949b03882606219 diff --git a/cpp/wedpr-computing/ppc-cem/tests/data/d3 b/cpp/wedpr-computing/ppc-cem/tests/data/d3 new file mode 100644 index 00000000..ff848899 --- /dev/null +++ b/cpp/wedpr-computing/ppc-cem/tests/data/d3 @@ -0,0 +1,101 @@ +id,x1,x2 +1,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +2,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +3,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +4,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +5,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +6,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +7,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +8,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +9,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +10,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +11,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +12,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +13,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +14,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +15,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +16,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +17,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +18,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +19,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +20,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +21,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +22,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +23,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +24,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +25,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +26,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +27,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +28,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +29,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +30,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +31,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +32,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +33,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +34,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +35,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +36,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +37,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +38,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +39,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +40,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +41,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +42,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +43,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +44,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +45,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +46,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +47,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +48,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +49,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +50,b01fd1269fc544b4b54ad067a5a96cc8,68ef58e92d6a4e62b8725f80f161cc04 +51,c127b40c158f404aa432656b013bad12,424637e2531f4ddfad8f43d8d3d45f3e +52,f35367150f904fa3ab3442e77355e43a,600d3627245341d580fe078b19450d6d +53,29627c5f37e94779a8ec95322e5afbe1,63533be072f8427ea9ba6d0369163862 +54,a41df047bf2f4e919033441f61d1b7fd,e2382ff5ba01431d9f48e085419ec4ef +55,65db7c7b020d4b0d9229a2ad0ea4c7c5,e775c8b1f7154d119ec8ddbea66cd4bc +56,e749e17a71a2447fac63bca47b6846a7,0045251d24b9466695d5d0c38929ea90 +57,14c697e5bce841878ebf89bf08a9ba14,04317b907cdc4043b8200db5110831c1 +58,38047064e02a4ca4af076ae26aa679f7,9bb62566a45c4d229a4fd795f8777a75 +59,5fb6f18de87043a497f0677537c189bc,2724e3acf012450e8355d84b8b3ece86 +60,b44e260738b343629faaa7d9f549bbcb,94b80d51709d4c5faaee2d78a762bbc4 +61,808af13908c14cd89092219dc37b29cf,1085ef4476aa4635b7d3e78ea67f83c3 +62,af18d05a4e2548468d61ccad12a0340e,2024c88fcc03414a81b64da8409dc8af +63,ba426827999c462b9df669d7e932144c,2b2d0515df814e4f94c1110d3b584ba4 +64,525584d2c08f439eb7bee2db6b91ac37,8188e4aee9354bb2b9fc8536f34b1c24 +65,f1d40891ad90463cb530bcd4fce3b733,1c6bb273297846dbbb920e5409c6e5ff +66,f9f22de01edd4644b6c55ef7a993b184,55adc457cd124274a27ebb830ad3dc66 +67,e4ff7eaa9dd04f149049aa12bf21e68a,0c3fb3b958b14243a3edcd1bc9a51283 +68,71d984a3e0ad42698f3186cfbfdcbd87,0a520b68a33c499b9809ae269a55c394 +69,96d145bc82ff4e2a84551c20ef6f1cc5,affad8d9f1284a5dbdf97ca825288654 +70,fcece0ef256c47fdaa5678e20df0f4a1,623b626acc0b494d90f64879575c51e3 +71,87800bc6aeb5461b869afaba3d7430b3,0825eac882c0486b8316723e722e29cf +72,dd943a94e743432592c68e38352e83c8,3aeb080d0f234cc198b3165baab8d8f5 +73,8f7f6922e81246a680f931c44ecc0d1a,42f4992a390a440a9aa1b440a02e78f5 +74,42d3d9010a7548faa386e83ae61f4802,f4d3dbad28004d759be6229bc2bbff9a +75,01dc4d7631f94ba987e435c87d632684,44bde70d206b4450bde0991d405ab0fa +76,ccea7c284fce4d3988d8948f79b2fef6,04fecfe64b874cc8b2cad3e2bc205317 +77,272d7020324f4fa9a36a31b64ef798fb,c803c1ef9eab459387bb0be0fe6e1e93 +78,c92ee2e67c22477482eb6a9b3492283a,07cf6bbaea12454ba9f8693486df6282 +79,afba2c31d5fb4e658fa16b269bd48179,c55973e7e2f04e96976e99218bf2a8d5 +80,7066d9b40a994cce8b5eb555a3a265c8,6bb406d7c2de40ff828bc6e2a4e97ee9 +81,ce88a3d29e574780a649399794d793bf,b5ac277d1e7242089a30a48d78033ac2 +82,2514054bd2fd42f79ecdbb4b4fac3301,af552fac31434e3b94bdb2dd7087c6e7 +83,1466f1d054284e78b1844dd343bdc095,970e1fd372ee4dacbc5d911a0f556efe +84,21d7c25b139845ea84b8a04dc45a1fc9,d28447da4e5843adadb9845fab94a278 +85,3e451bbe00b34590b0d627d0d17d4aab,8aa5643bab1342ffa4229bef214807d1 +86,d2e635d343a440478e8ae39d5f07c87d,adf9ab5d926c4d48ac33fa301f2e5cd4 +87,2ec3545d3ce84b4290481b4b3d5c9fd2,6c0a1f2b9d124cd1a2e27a419ecfce58 +88,42d37153df1c4e7f9eacf0628f07d22a,695082c3bd6a48a69e74c7435a642b1b +89,403c2018e9b64e7caba38b12ecdb8358,470671bd2e7640c8851426c9ebe4c924 +90,ccb7cefb3efd4a49a6e5e400caf239da,2d73f2af749d4c04990f6464d8d1350d +91,a39164ae87d84d8a8faecdfecfa537f3,1d82ac0af6e1484dbc16b1fe2fde368f +92,908045cc3301407ca0c8818e01eebf5f,92dc6cd19357410e96b60d96238e4f03 +93,ac388e933ba6482fbb5e3505d1a1e18a,4711abe2a1774467901f76dcd4d590b8 +94,5978cdb261304e13ab299f7c4a8bf3ff,d9ea4748b79842888038c71e72061abd +95,7808218f4ea74e57acbb0a913b967d29,d7fc8e21ae6f4d6c8dc0ffdf4e376aab +96,c0cd4c990efc43c18e46c246a1e3382e,8e1a87e86a5d48e593935786aa0cbc38 +97,5c0aaf7f191c4720a343f6d8b8c4704c,2ad4bd183efa49e984302df6cba20956 +98,15d996bfe59a4cc8ab4899e6cce426e2,fd4d20fb799c41a9afdf64b206e08a4e +99,d4a93966765b4a42b1697c8d14881211,36727725990f49a6bd4d92b1ec6424d2 +100,ebf75e2646914039803a59fd2b2e8fd9,e0ae4ddcf5d9424cb949b03882606219 diff --git a/cpp/wedpr-computing/ppc-cem/tests/main.cpp b/cpp/wedpr-computing/ppc-cem/tests/main.cpp new file mode 100644 index 00000000..2c06f9b5 --- /dev/null +++ b/cpp/wedpr-computing/ppc-cem/tests/main.cpp @@ -0,0 +1,2 @@ +#define BOOST_TEST_MAIN +#include \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-mpc/CMakeLists.txt b/cpp/wedpr-computing/ppc-mpc/CMakeLists.txt new file mode 100644 index 00000000..be4f918f --- /dev/null +++ b/cpp/wedpr-computing/ppc-mpc/CMakeLists.txt @@ -0,0 +1,8 @@ +add_subdirectory(src) + +#if (TESTS) +# enable_testing() +# set(CTEST_OUTPUT_ON_FAILURE TRUE) +# add_subdirectory(tests) +#endif() + diff --git a/cpp/wedpr-computing/ppc-mpc/src/CMakeLists.txt b/cpp/wedpr-computing/ppc-mpc/src/CMakeLists.txt new file mode 100644 index 00000000..a880eea0 --- /dev/null +++ b/cpp/wedpr-computing/ppc-mpc/src/CMakeLists.txt @@ -0,0 +1,4 @@ +file(GLOB_RECURSE SOURCES "*.cpp" "*.h") + +add_library(${MPC_TARGET} ${SOURCES}) +target_link_libraries(${MPC_TARGET} PUBLIC ${IO_TARGET} ${TOOLS_TARGET} jsoncpp_static) diff --git a/cpp/wedpr-computing/ppc-mpc/src/Common.h b/cpp/wedpr-computing/ppc-mpc/src/Common.h new file mode 100644 index 00000000..43ff4df8 --- /dev/null +++ b/cpp/wedpr-computing/ppc-mpc/src/Common.h @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2022 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 Common.h + * @author: caryliao + * @date 2023-03-24 + */ +#pragma once +#include "ppc-framework/Common.h" +#include + +#define MPC_LOG(LEVEL) BCOS_LOG(LEVEL) << LOG_BADGE("MPC") + +namespace ppc::mpc +{ +DERIVE_PPC_EXCEPTION(MpcCompilerNotExistException); +DERIVE_PPC_EXCEPTION(RunMpcFailException); +DERIVE_PPC_EXCEPTION(OpenPipeFailException); + +struct JobInfo +{ + std::string jobId; + bool mpcNodeUseGateway; + std::string receiverNodeIp; + int mpcNodeDirectPort; + int participantCount; + int selfIndex; + bool isMalicious; + int bitLength; + std::string mpcFilePath; + std::string inputFilePath; + std::string outputFilePath; + std::string gatewayEngineEndpoint; +}; + +// job status +struct JobStatus +{ + std::string jobId; + std::string status; + std::string message; + int64_t startTimeMs; + int64_t timeCostMs; +}; + +const std::string MPC_JOB_RUNNNING = "RUNNING"; +const std::string MPC_JOB_COMPLETED = "COMPLETED"; +const std::string MPC_JOB_FAILED = "FAILED"; +const std::string MPC_JOB_KILLED = "KILLED"; + +const int MPC_SUCCESS = 0; +const int MPC_DUPLICATED = 1; +const int MPC_FAILED = -1; + +const std::string PATH_SEPARATOR = "/"; +const std::string MPC_RELATIVE_PATH = "/Programs/Source/"; +const std::string MPC_ALGORITHM_FILE_SUFFIX = ".mpc"; +const std::string MPC_ALGORITHM_COMPILER = "compile.py"; +const std::string MPC_PREPARE_FILE = "mpc_prepare.csv"; +const std::string MPC_RESULT_FILE = "mpc_result.csv"; + +enum MpcBinaryType +{ + Hemi, + Replicated, + Shamir, + Mascot +}; +const std::string MPC_BINARY_NAME[] = { + "hemi-party.x", "replicated-ring-party.x", "shamir-party.x", "mascot-party.x"}; + +} // namespace ppc::mpc diff --git a/cpp/wedpr-computing/ppc-mpc/src/MPCService.cpp b/cpp/wedpr-computing/ppc-mpc/src/MPCService.cpp new file mode 100644 index 00000000..0a064e0c --- /dev/null +++ b/cpp/wedpr-computing/ppc-mpc/src/MPCService.cpp @@ -0,0 +1,699 @@ +/* + * Copyright (C) 2022 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 MPCService.cpp + * @author: caryliao + * @date 2023-03-28 + */ + +#include "MPCService.h" +#include "Common.h" +#include "ppc-framework/io/DataResourceLoader.h" +#include "ppc-io/src/DataResourceLoaderImpl.h" +#include "ppc-io/src/FileLineReader.h" +#include "ppc-io/src/FileLineWriter.h" +#include "ppc-io/src/FileSystemDeleter.h" +#include "ppc-storage/src/FileStorageFactoryImpl.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace ppc; +using namespace ppc::mpc; +using namespace bcos; +using namespace ppc::io; +using namespace ppc::protocol; +using namespace ppc::tools; +using namespace ppc::storage; +using namespace ppc::rpc; + +bool MPCService::addJobIfNotRunning(const JobInfo& jobInfo) +{ + std::lock_guard l(x_job2Status); + auto it = m_job2Status.find(jobInfo.jobId); + if (it != m_job2Status.end()) + { + MPC_LOG(INFO) << LOG_DESC("[MPCService][addJob]") + << "job already exists" + << LOG_KV("jobId", jobInfo.jobId) + << LOG_KV("status", it->second.status) + << LOG_KV("message", it->second.message); + + if (it->second.status == MPC_JOB_RUNNNING) + { + // job is running + return false; + } + + m_job2Status.erase(it); + } + + JobStatus jobStatus; + jobStatus.jobId = jobInfo.jobId; + jobStatus.status = MPC_JOB_RUNNNING; + jobStatus.message = "job is running"; + jobStatus.startTimeMs = utcSteadyTime(); + jobStatus.timeCostMs = 0; + + m_job2Status[jobInfo.jobId] = jobStatus; + m_runningJobs.insert(jobInfo.jobId); + + MPC_LOG(INFO) << LOG_DESC("[MPCService][addJob]") + << "job added successfully" + << LOG_KV("jobId", jobInfo.jobId) + << LOG_KV("runningJobsCount", m_runningJobs.size()) + ; + return true; +} + +bool MPCService::queryJobStatus(const std::string &jobId, JobStatus &jobStatus) +{ + std::lock_guard l(x_job2Status); + auto it = m_job2Status.find(jobId); + if (it == m_job2Status.end()) + { + MPC_LOG(DEBUG) << LOG_DESC("[MPCService][queryJobStatus]") + << "job does not exist" + << LOG_KV("jobId", jobId); + return false; + } + + jobStatus = it->second; + + MPC_LOG(INFO) << LOG_DESC("[MPCService][queryJobStatus]") + << "find job" + << LOG_KV("jobId", jobId) + << LOG_KV("status", jobStatus.status) + << LOG_KV("message", jobStatus.message) + << LOG_KV("timeCostMs", jobStatus.timeCostMs); + return true; +} + +void MPCService::onFinish(const std::string &jobId, const std::string &msg) +{ + std::lock_guard l(x_job2Status); + m_runningJobs.erase(jobId); + auto it = m_job2Status.find(jobId); + if (it == m_job2Status.end()) + { + MPC_LOG(ERROR) << LOG_DESC("[MPCService][onFinish]") + << "job does not exist" + << LOG_KV("jobId", jobId); + return; + } + + JobStatus &jobStatus = it->second; + jobStatus.status = MPC_JOB_COMPLETED; + jobStatus.message = msg; + jobStatus.timeCostMs = utcSteadyTime() - jobStatus.startTimeMs; + + MPC_LOG(INFO) << LOG_DESC("[MPCService][onFinish]") + << "job finished" + << LOG_KV("jobId", jobId) + << LOG_KV("timeCostMs", jobStatus.timeCostMs) + ; +} + +void MPCService::onFailed(const std::string &jobId, const std::string &msg) +{ + std::lock_guard l(x_job2Status); + m_runningJobs.erase(jobId); + auto it = m_job2Status.find(jobId); + if (it == m_job2Status.end()) + { + MPC_LOG(ERROR) << LOG_DESC("[MPCService][onFailed]") + << "job does not exist" + << LOG_KV("jobId", jobId); + return; + } + + JobStatus &jobStatus = it->second; + jobStatus.status = MPC_JOB_FAILED; + jobStatus.message = msg; + jobStatus.timeCostMs = utcSteadyTime() - jobStatus.startTimeMs; + + MPC_LOG(INFO) << LOG_DESC("[MPCService][onFailed]") + << LOG_KV("jobId", jobId) + << LOG_KV("msg", msg) + << LOG_KV("timeCostMs", jobStatus.timeCostMs); +} + + +void MPCService::onKill(const std::string &jobId, const std::string &msg) +{ + std::lock_guard l(x_job2Status); + m_runningJobs.erase(jobId); + auto it = m_job2Status.find(jobId); + if (it == m_job2Status.end()) + { + MPC_LOG(ERROR) << LOG_DESC("[MPCService][onKill]") + << "job does not exist" + << LOG_KV("jobId", jobId); + return; + } + + JobStatus &jobStatus = it->second; + jobStatus.status = MPC_JOB_KILLED; + jobStatus.message = msg; + jobStatus.timeCostMs = utcSteadyTime() - jobStatus.startTimeMs; + + MPC_LOG(INFO) << LOG_DESC("[MPCService][onKill]") + << "job is killed" + << LOG_KV("jobId", jobId) + << LOG_KV("timeCostMs", jobStatus.timeCostMs) + ; +} + +void MPCService::doRun(const JobInfo& jobInfo) +{ + auto startT = utcSteadyTime(); + + std::string mpcFileHdfsPath = jobInfo.mpcFilePath; + std::string mpcRootPath = m_mpcConfig.mpcRootPathNoGateway; + if (jobInfo.mpcNodeUseGateway) + { + mpcRootPath = m_mpcConfig.mpcRootPath; + } + std::string localPathPrefix = + m_mpcConfig.jobPath + PATH_SEPARATOR + jobInfo.jobId + PATH_SEPARATOR; + std::string mpcFileLocalPath = + mpcRootPath + MPC_RELATIVE_PATH + jobInfo.jobId + MPC_ALGORITHM_FILE_SUFFIX; + + FileSystemDeleter fileSystemDeleter({localPathPrefix, mpcFileLocalPath}); + + // 0 get jobInfo and make command + std::string jobId = jobInfo.jobId; + int participantCount = jobInfo.participantCount; + int selfIndex = jobInfo.selfIndex; + + std::string mpcCmd; + makeCommand(mpcCmd, jobInfo); + + // 1 download mpc algorithm file + auto mpcFileReader = + initialize_lineReader(jobInfo, mpcFileHdfsPath, DataResourceType::HDFS); + auto mpcFileWriter = + initialize_lineWriter(jobInfo, mpcFileLocalPath, DataResourceType::FILE); + readAndSaveFile(mpcFileHdfsPath, mpcFileLocalPath, mpcFileReader, mpcFileWriter); + + // 2 download mpc prepare file + std::string mpcPrepareFileHdfsPath = jobInfo.inputFilePath; + + std::string mpcPrepareFileLocalPath = localPathPrefix + MPC_PREPARE_FILE + "-P" + std::to_string(selfIndex) + "-0"; + auto datasetFileReader = + initialize_lineReader(jobInfo, mpcPrepareFileHdfsPath, DataResourceType::HDFS); + auto datasetFileWriter = + initialize_lineWriter(jobInfo, mpcPrepareFileLocalPath, DataResourceType::FILE); + readAndSaveFile(mpcPrepareFileHdfsPath, mpcPrepareFileLocalPath, datasetFileReader, datasetFileWriter); + + // 3 run mpc job + int outExitStatus = MPC_SUCCESS; + std::string outResult; + execCommand(mpcCmd, outExitStatus, outResult); + + // 4 upload result file + std::string resultFileHdfsPath = jobInfo.outputFilePath; + std::string resultFileLocalPath = localPathPrefix + MPC_RESULT_FILE; + writeStringToFile(outResult, resultFileLocalPath); + + auto resultFileReader = + initialize_lineReader(jobInfo, resultFileLocalPath, DataResourceType::FILE); + auto resultFileWriter = + initialize_lineWriter(jobInfo, resultFileHdfsPath, DataResourceType::HDFS); + readAndSaveFile(resultFileLocalPath, resultFileHdfsPath, resultFileReader, resultFileWriter); + + if (outExitStatus != MPC_SUCCESS) + { + MPC_LOG(ERROR) << LOG_DESC("[MPCService][doRun]") + << "run mpc job failed" + << LOG_KV("jobId", jobId) + << LOG_KV("outExitStatus", outExitStatus) + << LOG_KV("outResult", outResult); + BOOST_THROW_EXCEPTION(RunMpcFailException() << errinfo_comment(outResult)); + } + + MPC_LOG(INFO) << LOG_DESC("[MPCService][doRun]") << LOG_KV("jobId", jobId) + << LOG_DESC("run mpc job successfully"); + + MPC_LOG(INFO) << LOG_DESC("do run mpc") << LOG_KV("jodId", jobInfo.jobId)<< LOG_KV("timecost(ms)", utcSteadyTime() - startT); +} + +void MPCService::queryMpcRpc(Json::Value const& request, RespFunc func) +{ + auto jobId = request["jobId"].asString(); + + JobStatus jobStatus; + auto result = queryJobStatus(jobId, jobStatus); + + Json::Value response; + if (result) + { + response["code"] = MPC_SUCCESS; + response["status"] = jobStatus.status; + response["message"] = jobStatus.message; + response["timeCostMs"] = jobStatus.timeCostMs; + } + else + { + response["code"] = MPC_FAILED; + response["status"] = ""; + response["message"] = "job does not exist"; + response["timeCostMs"] = -1; + } + + func(nullptr, std::move(response)); +} + +void MPCService::runMpcRpcByJobInfo(const JobInfo& jobInfo) +{ + try + { + doRun(jobInfo); + onFinish(jobInfo.jobId, "run mpc job successfully"); + } + catch (const std::exception& e) + { + onFailed(jobInfo.jobId, boost::diagnostic_information(e)); + } +} + +void MPCService::runMpcRpc(Json::Value const& request, RespFunc func) +{ + Json::Value response; + + try + { + auto jobInfo = paramsToJobInfo(request); + auto r = addJobIfNotRunning(jobInfo); + if (r) + { + doRun(jobInfo); + onFinish(jobInfo.jobId, "run mpc job successfully"); + + response["code"] = MPC_SUCCESS; + response["message"] = "success"; + } + else + { + response["code"] = MPC_DUPLICATED; + response["message"] = "duplicated submit job"; + } + } + catch (const std::exception& e) + { + const std::string diagnostic_information = std::string(boost::diagnostic_information(e)); + + MPC_LOG(ERROR) << LOG_DESC("[MPCService][runMpcRpc]") << LOG_DESC("run mpc submit job failed") + << LOG_DESC(diagnostic_information) + << LOG_KV("request", request.toStyledString()); + + response["code"] = MPC_FAILED; + response["message"] = diagnostic_information; + } + + func(nullptr, std::move(response)); +} + +void MPCService::asyncRunMpcRpc(Json::Value const& request, RespFunc func) +{ + Json::Value response; + + try + { + auto jobInfo = paramsToJobInfo(request); + auto r = addJobIfNotRunning(jobInfo); + + if (r) + { + response["code"] = MPC_SUCCESS; + response["message"] = "success"; + + MPC_LOG(INFO) << LOG_DESC("[MPCService][asyncRunMpcRpc]") << LOG_DESC("async run mpc submit job successfully") + << LOG_KV("request", request.toStyledString()) + << LOG_KV("response", response.toStyledString()); + + // async run mpc job + m_threadPool->enqueue([self = weak_from_this(), jobInfo]() { + auto service = self.lock(); + if (!service) + { + MPC_LOG(ERROR) << LOG_DESC("[MPCService][asyncRunMpcRpc]") << LOG_DESC("async run mpc service is null"); + return; + } + service->runMpcRpcByJobInfo(jobInfo); + }); + } + else + { + response["code"] = MPC_DUPLICATED; + response["message"] = "duplicated submit job"; + + MPC_LOG(INFO) << LOG_DESC("[MPCService][asyncRunMpcRpc]") << LOG_DESC("async run mpc duplicated submit job") + << LOG_KV("request", request.toStyledString()) + << LOG_KV("response", response.toStyledString()); + } + } + catch (const std::exception& e) + { + const std::string diagnostic_information = std::string(boost::diagnostic_information(e)); + + MPC_LOG(ERROR) << LOG_DESC("[MPCService][asyncRunMpcRpc]") << LOG_DESC("async run mpc submit job failed") + << LOG_DESC(diagnostic_information) + << LOG_KV("request", request.toStyledString()); + + response["code"] = MPC_FAILED; + response["message"] = diagnostic_information; + } + + func(nullptr, std::move(response)); +} + +void MPCService::doKill(Json::Value const& request, Json::Value& response) +{ + auto startT = utcSteadyTime(); + try + { + auto jobId = request["jobId"].asString(); + MPC_LOG(INFO) << LOG_DESC("[MPCService][doKill]") << LOG_KV("jobId", jobId); + + std::string killCmd = "ps -ef |grep mpc | grep " + jobId + + " | grep -v grep | awk '{print $2}' | xargs kill -9"; + MPC_LOG(INFO) << LOG_DESC("[MPCService][doKill]") << LOG_KV("jobId", jobId) << LOG_KV("killCmd", killCmd); + + int outExitStatus = 0; + std::string outResult; + execCommand(killCmd, outExitStatus, outResult); + std::string message = ""; + if (outExitStatus == 0) + { + message = "Kill mpc job successfully"; + onKill(jobId, message); + MPC_LOG(INFO) << LOG_DESC("[MPCService][doKill]") << LOG_KV("jobId", jobId) << LOG_DESC(message); + response["code"] = MPC_SUCCESS; + response["message"] = "success"; + } + else + { + message = "Kill mpc job failed"; + MPC_LOG(INFO) << LOG_DESC("[MPCService][doKill]") << LOG_KV("jobId", jobId) << LOG_DESC(message) + << LOG_KV("outExitStatus", outExitStatus) + << LOG_KV("outResult", outResult); + response["code"] = MPC_FAILED; + response["message"] = message; + } + } + catch (const std::exception& e) + { + const std::string diagnostic_information = std::string(boost::diagnostic_information(e)); + MPC_LOG(INFO) << LOG_DESC("[MPCService][doKill]") << LOG_DESC("kill mpc job failed:") + << LOG_DESC(diagnostic_information); + response["code"] = MPC_FAILED; + response["message"] = diagnostic_information; + } + MPC_LOG(INFO) << LOG_DESC("kill mpc job") + << LOG_KV("request", response.toStyledString()) + << LOG_KV("timecost(ms)", utcSteadyTime() - startT); +} + +void MPCService::killMpcRpc(Json::Value const& request, RespFunc func) +{ + Json::Value response; + doKill(request, response); + func(nullptr, std::move(response)); +} + +void MPCService::writeStringToFile(const std::string& content, const std::string& filePath) +{ + std::ostringstream buffer; + buffer << content; + + std::ofstream file(filePath, std::ios::out | std::ios::trunc); + file << buffer.str(); +} + +void MPCService::readAndSaveFile(const std::string &readerFilePath, const std::string &writerFilePath, LineReader::Ptr lineReader, LineWriter::Ptr lineWriter) +{ + uint64_t lineSize = 0; + int64_t readPerBatchLines = m_mpcConfig.readPerBatchLines; + while (true) + { + // batch read dataset line + auto dataBatch = lineReader->next(readPerBatchLines); + if (!dataBatch) + { + break; + } + lineSize += dataBatch->size(); + lineWriter->writeLine(dataBatch, DataSchema::String, "\n"); + } + lineWriter->close(); + MPC_LOG(INFO) << LOG_DESC("save file ok") + << LOG_KV("readerFilePath", readerFilePath) + << LOG_KV("writerFilePath", writerFilePath) + << LOG_KV("file lines", lineSize); +} + +LineReader::Ptr MPCService::initialize_lineReader( + const JobInfo& jobInfo, const std::string& readerFilePath, DataResourceType type) +{ + auto factory = std::make_shared(); + auto dataResourceLoader = std::make_shared( + nullptr, nullptr, nullptr, nullptr, factory, nullptr); + const auto dataResource = std::make_shared(); + dataResource->setResourceID(jobInfo.jobId); + const auto dataResourceDesc = std::make_shared(); + dataResourceDesc->setType((int)type); + if ((int)type == (int)DataResourceType::HDFS) + { + dataResourceDesc->setFileStorageConnectOption(m_storageConfig.fileStorageConnectionOpt); + } + dataResourceDesc->setPath(readerFilePath); + dataResource->setDesc(dataResourceDesc); + return dataResourceLoader->loadReader(dataResource->desc()); +} + +LineWriter::Ptr MPCService::initialize_lineWriter( + const JobInfo& jobInfo, const std::string& writerFilePath, DataResourceType type) +{ + auto factory = std::make_shared(); + auto dataResourceLoader = std::make_shared( + nullptr, nullptr, nullptr, nullptr, factory, nullptr); + const auto dataResource = std::make_shared(); + dataResource->setResourceID(jobInfo.jobId); + const auto dataResourceDesc = std::make_shared(); + dataResourceDesc->setType((int)type); + + if ((int)type == (int)DataResourceType::HDFS) + { + dataResourceDesc->setFileStorageConnectOption(m_storageConfig.fileStorageConnectionOpt); + } + dataResourceDesc->setPath(writerFilePath); + dataResource->setOutputDesc(dataResourceDesc); + return dataResourceLoader->loadWriter(dataResource->outputDesc()); +} + + +void MPCService::setMPCConfig(MPCConfig const& mpcConfig) +{ + m_mpcConfig = mpcConfig; +} + +void MPCService::setStorageConfig(StorageConfig const& storageConfig) +{ + m_storageConfig = storageConfig; +} + +JobInfo MPCService::paramsToJobInfo(const Json::Value& params) +{ + try + { + JobInfo jobInfo; + jobInfo.jobId = params["jobId"].asString(); + jobInfo.mpcNodeUseGateway = params["mpcNodeUseGateway"].asBool(); + jobInfo.receiverNodeIp = params["receiverNodeIp"].asString(); + jobInfo.mpcNodeDirectPort = params["mpcNodeDirectPort"].asInt(); + jobInfo.participantCount = params["participantCount"].asInt(); + jobInfo.selfIndex = params["selfIndex"].asInt(); + jobInfo.isMalicious = params["isMalicious"].asBool(); + jobInfo.bitLength = params["bitLength"].asInt(); + jobInfo.mpcFilePath = params["mpcFilePath"].asString(); + jobInfo.inputFilePath = params["inputFilePath"].asString(); + jobInfo.outputFilePath = params["outputFilePath"].asString(); + jobInfo.gatewayEngineEndpoint = params["gatewayEngineEndpoint"].asString(); + return jobInfo; + } + catch (const std::exception& e) + { + BOOST_THROW_EXCEPTION( + InvalidParam() << errinfo_comment( + "invalid params:" + std::string(boost::diagnostic_information(e)))); + } +} + +void MPCService::makeCommand(std::string& cmd, const JobInfo& jobInfo) +{ + std::string jobId = jobInfo.jobId; + std::string mpcRootPath = m_mpcConfig.mpcRootPath; + if (jobInfo.mpcNodeUseGateway) + { + MPC_LOG(INFO) << LOG_DESC("[MPCService][makeCommand] use gateway to connect node") + << LOG_KV("jobId", jobId); + } + else + { + mpcRootPath = m_mpcConfig.mpcRootPathNoGateway; + MPC_LOG(INFO) << LOG_DESC("[MPCService][makeCommand] direct connect node") + << LOG_KV("jobId", jobId); + } + int r = chdir(mpcRootPath.c_str()); + if (r == 0) + { + MPC_LOG(INFO) << LOG_DESC("[MPCService][makeCommand] change dir ok") + << LOG_KV("jobId", jobId); + } + else + { + MPC_LOG(ERROR) << LOG_DESC("[MPCService][makeCommand] change dir fail") + << LOG_KV("mpcRootPath", mpcRootPath) + << LOG_KV("ret", r) + << LOG_KV("jobId", jobId); + } + std::string compileFilePath = mpcRootPath + PATH_SEPARATOR + MPC_ALGORITHM_COMPILER; + int participantCount = jobInfo.participantCount; + int selfIndex = jobInfo.selfIndex; + bool isMalicious = jobInfo.isMalicious; + std::string mpcBinFileName; + std::string compileOption; + getMpcProtocol(participantCount, isMalicious, mpcBinFileName, compileOption); + + if (!boost::filesystem::exists(compileFilePath)) + { + MPC_LOG(ERROR) << LOG_DESC("[MPCService] compile file not exist") + << LOG_KV("compileFilePath", compileFilePath) + << LOG_KV("jobId", jobId); + + BOOST_THROW_EXCEPTION(MpcCompilerNotExistException() + << errinfo_comment("compile file not exist:" + compileFilePath)); + } + if (jobInfo.mpcNodeUseGateway) + { + cmd = "export LD_LIBRARY_PATH=$PPC_MPC_LIB && python "; + } + else + { + cmd = "export LD_LIBRARY_PATH=$PPC_MPC_NO_GATEWAY_LIB && python "; + } + std::string compileCmd = compileFilePath + " " + compileOption + +" " + + std::to_string(jobInfo.bitLength) + " " + jobInfo.jobId; + cmd += compileCmd + " && "; + cmd += mpcRootPath + PATH_SEPARATOR + mpcBinFileName + " "; + cmd += std::to_string(jobInfo.selfIndex) + " "; + cmd += jobInfo.jobId + " "; + if (jobInfo.mpcNodeUseGateway) + { + cmd += "-gateway " + jobInfo.gatewayEngineEndpoint + " "; + cmd += "-ID " + jobInfo.jobId.substr(jobInfo.jobId.length() - 8, 8) + " "; + } + else + { + cmd += "-h " + jobInfo.receiverNodeIp + " "; + cmd += "-pn " + std::to_string(jobInfo.mpcNodeDirectPort) + " "; + } + if (jobInfo.mpcNodeUseGateway && !jobInfo.isMalicious && jobInfo.participantCount >= 3) + { + cmd += "-u "; + } + std::string inputFilePath = + m_mpcConfig.jobPath + PATH_SEPARATOR + jobInfo.jobId + PATH_SEPARATOR + MPC_PREPARE_FILE; + cmd += "-IF " + inputFilePath + " "; + if (mpcBinFileName != MPC_BINARY_NAME[MpcBinaryType::Replicated]) + { + cmd += "-N " + std::to_string(jobInfo.participantCount) + " "; + } + MPC_LOG(INFO) << LOG_DESC("[MPCService][makeCommand]") << LOG_KV("jobId", jobId) << LOG_KV("mpcCmd", cmd); +} + +void MPCService::getMpcProtocol(const int participantCount, const bool isMalicious, + std::string& mpcBinFileName, std::string& compileOption) +{ + if (participantCount <= 1) + { + BOOST_THROW_EXCEPTION( + InvalidParam() << errinfo_comment("getMpcProtocol: participantCount need at least 2")); + } + if (isMalicious == true) + { + mpcBinFileName = MPC_BINARY_NAME[MpcBinaryType::Mascot]; + compileOption = "-F"; + } + else + { + if (participantCount == 2) + { + mpcBinFileName = MPC_BINARY_NAME[MpcBinaryType::Hemi]; + compileOption = "-F"; + } + else if (participantCount == 3) + { + mpcBinFileName = MPC_BINARY_NAME[MpcBinaryType::Replicated]; + compileOption = "-R"; + } + else + { + mpcBinFileName = MPC_BINARY_NAME[MpcBinaryType::Shamir]; + compileOption = "-F"; + } + } +} + +void MPCService::execCommand(const std::string cmd, int& outExitStatus, std::string& outResult) +{ + try + { + auto pPipe = popen((cmd + " 2>&1").c_str(), "r"); + if (pPipe == nullptr) + { + BOOST_THROW_EXCEPTION(OpenPipeFailException() << errinfo_comment("open pipe fail")); + } + std::array buffer; + while (not std::feof(pPipe)) + { + auto bytes = std::fread(buffer.data(), 1, buffer.size(), pPipe); + outResult.append(buffer.data(), bytes); + } + auto rc = pclose(pPipe); + if (WIFEXITED(rc)) + { + outExitStatus = WEXITSTATUS(rc); + } + MPC_LOG(INFO) << LOG_DESC("[MPCService][execCommand]") + << LOG_KV("outExitStatus", outExitStatus); + } + catch (const std::exception& e) + { + MPC_LOG(WARNING) << LOG_DESC("[MPCService] execCommand failed") << LOG_KV("cmd", cmd); + BOOST_THROW_EXCEPTION( + RunMpcFailException() << errinfo_comment( + "invalid params:" + std::string(boost::diagnostic_information(e)))); + } +} diff --git a/cpp/wedpr-computing/ppc-mpc/src/MPCService.h b/cpp/wedpr-computing/ppc-mpc/src/MPCService.h new file mode 100644 index 00000000..a91b0cfa --- /dev/null +++ b/cpp/wedpr-computing/ppc-mpc/src/MPCService.h @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2022 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 MPCService.h + * @author: caryliao + * @date 2023-03-24 + */ +#pragma once +#include "Common.h" +#include "ppc-framework/rpc/RpcInterface.h" +#include "ppc-io/src/FileLineReader.h" +#include "ppc-io/src/FileLineWriter.h" +#include "ppc-tools/src/config/MPCConfig.h" +#include "ppc-tools/src/config/StorageConfig.h" +#include +#include +#include +#include +#include +#include +#include + +namespace ppc::mpc +{ +class MPCService: public std::enable_shared_from_this +{ +public: + using Ptr = std::shared_ptr; + MPCService() = default; + virtual ~MPCService() + { + if (m_threadPool) + { + m_threadPool->stop(); + } + } + + void runMpcRpc(Json::Value const& request, ppc::rpc::RespFunc func); + void killMpcRpc(Json::Value const& request, ppc::rpc::RespFunc func); + void asyncRunMpcRpc(Json::Value const& request, ppc::rpc::RespFunc func); + void queryMpcRpc(Json::Value const& request, ppc::rpc::RespFunc func); + + void runMpcRpcByJobInfo(const JobInfo& jobInfo); + + void setMPCConfig(ppc::tools::MPCConfig const& mpcConfig); + void setStorageConfig(ppc::tools::StorageConfig const& storageConfig); + + JobInfo paramsToJobInfo(const Json::Value& params); + void makeCommand(std::string& cmd, const JobInfo& jobInfo); + void getMpcProtocol(const int participantCount, const bool isMalicious, + std::string& mpcBinFileName, std::string& compileOption); + + void doRun(const JobInfo& jobInfo); + void doKill(Json::Value const& request, Json::Value& response); + + void onFinish(const std::string &jobId, const std::string &msg); + void onFailed(const std::string &jobId, const std::string &msg); + void onKill(const std::string &jobId, const std::string &msg); + + void execCommand(const std::string cmd, int& outExitStatus, std::string& outResult); + + void writeStringToFile(const std::string& content, const std::string& filePath); + void readAndSaveFile(const std::string &readerFilePath, const std::string &writerFilePath,ppc::io::LineReader::Ptr lineReader, ppc::io::LineWriter::Ptr lineWriter); + ppc::io::LineReader::Ptr initialize_lineReader(const JobInfo& jobInfo, + const std::string& readerFilePath, ppc::protocol::DataResourceType type); + ppc::io::LineWriter::Ptr initialize_lineWriter(const JobInfo& jobInfo, + const std::string& writerFilePath, ppc::protocol::DataResourceType type); + + void setThreadPool(std::shared_ptr threadPool) + { + m_threadPool = threadPool; + } + + bool addJobIfNotRunning(const JobInfo& jobInfo); + + bool queryJobStatus(const std::string &jobId, JobStatus &jobStatus); + +private: + std::mutex x_job2Status; + std::unordered_map m_job2Status; + std::unordered_set m_runningJobs; + ppc::tools::MPCConfig m_mpcConfig; + ppc::tools::StorageConfig m_storageConfig; + + std::shared_ptr m_threadPool; +}; +} // namespace ppc::mpc diff --git a/cpp/wedpr-computing/ppc-mpc/tests/CMakeLists.txt b/cpp/wedpr-computing/ppc-mpc/tests/CMakeLists.txt new file mode 100644 index 00000000..ef2135ec --- /dev/null +++ b/cpp/wedpr-computing/ppc-mpc/tests/CMakeLists.txt @@ -0,0 +1,9 @@ +file(GLOB_RECURSE SOURCES "*.cpp" "*.h") + +# cmake settings +set(TEST_BINARY_NAME test-ppc-mpc) + +add_executable(${TEST_BINARY_NAME} ${SOURCES}) +target_include_directories(${TEST_BINARY_NAME} PRIVATE .) +target_link_libraries(${TEST_BINARY_NAME} ${MPC_TARGET} ${RPC_TARGET} ${BOOST_UNIT_TEST} TBB::tbb) +add_test(NAME test-mpc WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} COMMAND ${TEST_BINARY_NAME}) \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-mpc/tests/TestMPCService.cpp b/cpp/wedpr-computing/ppc-mpc/tests/TestMPCService.cpp new file mode 100644 index 00000000..5b523bbc --- /dev/null +++ b/cpp/wedpr-computing/ppc-mpc/tests/TestMPCService.cpp @@ -0,0 +1,124 @@ +/* + * Copyright (C) 2022 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 applicabl 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 TestmpcService->cpp + * @author: caryliao + * @date 2023-03-28 + */ +#include "ppc-mpc/src/Common.h" +#include "ppc-mpc/src/MPCService.h" +#include +#include + +using namespace ppc::mpc; +using namespace bcos; +using namespace bcos::test; +using namespace ppc::io; + +namespace ppc::test +{ +BOOST_FIXTURE_TEST_SUITE(MPCServiceTest, TestPromptFixture) + +BOOST_AUTO_TEST_CASE(testMPCService) +{ + auto mpcService = std::make_shared(); + std::string configPath{"../../../../wedpr-computing/ppc-mpc/tests/data/config.ini"}; + boost::property_tree::ptree pt; + boost::property_tree::read_ini(configPath, pt); + // load the mpc config + auto ppcConfig = std::make_shared(); + ppcConfig->loadMPCConfig(pt); + auto mpcConfig = ppcConfig->mpcConfig(); + auto storageConfig = ppcConfig->storageConfig(); + mpcService->setMPCConfig(mpcConfig); + mpcService->setStorageConfig(storageConfig); + + // test mpc config + BOOST_CHECK(mpcConfig.datasetHDFSPath == "/user/ppc/"); + BOOST_CHECK(mpcConfig.jobPath == "/data/app/ppc/mpc-job/"); + BOOST_CHECK(mpcConfig.mpcRootPath == "/ppc/scripts/ppc-mpc/"); + BOOST_CHECK(mpcConfig.mpcRootPathNoGateway == "/ppc/scripts/ppc-mpc-no-gateway/"); + BOOST_CHECK(mpcConfig.readPerBatchLines == 100000); + + // test getMpcProtocol + std::string mpcBinFileName, compileOption; + BOOST_CHECK_THROW( + mpcService->getMpcProtocol(1, false, mpcBinFileName, compileOption), InvalidParam); + + mpcService->getMpcProtocol(2, true, mpcBinFileName, compileOption); + BOOST_CHECK_EQUAL(mpcBinFileName, MPC_BINARY_NAME[MpcBinaryType::Mascot]); + BOOST_CHECK_EQUAL(compileOption, "-F"); + + mpcService->getMpcProtocol(2, false, mpcBinFileName, compileOption); + BOOST_CHECK_EQUAL(mpcBinFileName, MPC_BINARY_NAME[MpcBinaryType::Hemi]); + BOOST_CHECK_EQUAL(compileOption, "-F"); + + mpcService->getMpcProtocol(3, false, mpcBinFileName, compileOption); + BOOST_CHECK_EQUAL(mpcBinFileName, MPC_BINARY_NAME[MpcBinaryType::Replicated]); + BOOST_CHECK_EQUAL(compileOption, "-R"); + + mpcService->getMpcProtocol(4, false, mpcBinFileName, compileOption); + BOOST_CHECK_EQUAL(mpcBinFileName, MPC_BINARY_NAME[MpcBinaryType::Shamir]); + BOOST_CHECK_EQUAL(compileOption, "-F"); + + // test makeCommand + std::string cmd; + JobInfo jobInfo; + jobInfo.jobId = "j-123456789"; + jobInfo.mpcNodeUseGateway = true; + jobInfo.receiverNodeIp = ""; + jobInfo.mpcNodeDirectPort = 5899; + jobInfo.participantCount = 2; + jobInfo.selfIndex = 0; + jobInfo.isMalicious = false; + jobInfo.bitLength = 128; + jobInfo.inputFilePath = "mpc_prepare.csv"; + jobInfo.outputFilePath = "mpc_output.txt"; + jobInfo.gatewayEngineEndpoint = "127.0.0.1:6789"; + + mpcService->makeCommand(cmd, jobInfo); + BOOST_CHECK_EQUAL(cmd, + "/ppc/scripts/ppc-mpc//compile.py -F 128 j-123456789 && /ppc/scripts/ppc-mpc//hemi-party.x " + "0 j-123456789 -gateway 127.0.0.1:6789 -ID 23456789 -IF " + "/data/app/ppc/mpc-job//j-123456789/mpc_prepare.csv -N 2 "); + + + jobInfo.participantCount = 3; + mpcService->makeCommand(cmd, jobInfo); + BOOST_CHECK_EQUAL(cmd, + "/ppc/scripts/ppc-mpc//compile.py -R 128 j-123456789 && " + "/ppc/scripts/ppc-mpc//replicated-ring-party.x " + "0 j-123456789 -gateway 127.0.0.1:6789 -ID 23456789 -u -IF " + "/data/app/ppc/mpc-job//j-123456789/mpc_prepare.csv "); + + jobInfo.participantCount = 4; + mpcService->makeCommand(cmd, jobInfo); + BOOST_CHECK_EQUAL(cmd, + "/ppc/scripts/ppc-mpc//compile.py -F 128 j-123456789 && " + "/ppc/scripts/ppc-mpc//shamir-party.x 0 j-123456789 -gateway 127.0.0.1:6789 -ID 23456789 " + "-u -IF /data/app/ppc/mpc-job//j-123456789/mpc_prepare.csv -N 4 "); + + jobInfo.participantCount = 4; + jobInfo.isMalicious = true; + jobInfo.mpcNodeUseGateway = false; + jobInfo.receiverNodeIp = "192.168.1.2"; + mpcService->makeCommand(cmd, jobInfo); + BOOST_CHECK_EQUAL(cmd, + "/ppc/scripts/ppc-mpc-no-gateway//compile.py -F 128 j-123456789 && " + "/ppc/scripts/ppc-mpc-no-gateway//mascot-party.x 0 j-123456789 -h 192.168.1.2 -pn 5899 " + "-IF /data/app/ppc/mpc-job//j-123456789/mpc_prepare.csv -N 4 "); +} +BOOST_AUTO_TEST_SUITE_END() +} // namespace ppc::test diff --git a/cpp/wedpr-computing/ppc-mpc/tests/data/config.ini b/cpp/wedpr-computing/ppc-mpc/tests/data/config.ini new file mode 100644 index 00000000..a4a9fb9c --- /dev/null +++ b/cpp/wedpr-computing/ppc-mpc/tests/data/config.ini @@ -0,0 +1,56 @@ +[agency] + ; the agency-id of self-party + id = agency + ; the agency info + +[mpc] + dataset_hdfs_path = /user/ppc/ + job_path = /data/app/ppc/mpc-job/ + mpc_root_path = /ppc/scripts/ppc-mpc/ + mpc_root_path_no_gateway = /ppc/scripts/ppc-mpc-no-gateway/ + read_per_batch_lines = 100000 + +[crypto] + sm_crypto = false + +[rpc] + listen_ip=0.0.0.0 + listen_port=5002 + thread_count=4 + ; ssl or sm ssl + sm_ssl=false + ; ssl connection switch, if disable the ssl connection, default: false + ;disable_ssl = true + +; [storage] +; host = 127.0.0.1 +; ; the mysqlx_port +; port = 3306 +; user = root +; password = 12345678 +; database = ppc15 + +[hdfs_storage] + ; the hdfs configuration + user = ppc + name_node = 127.0.0.1 + name_node_port = 9900 + token = + ; enable replace-datanode-on-failure or not + replace-datanode-on-failure = false + ; the connection-timeout, in ms, default is 1000ms + connection-timeout = 2000 + +[cert] + ; directory the certificates located in + cert_path=./conf + +[log] + enable=true + ; print the log to std::cout or not, default print to the log files + enable_console_output = false + log_path=./log + ; info debug trace + level=info + ; MB + max_log_file_size=200 diff --git a/cpp/wedpr-computing/ppc-mpc/tests/main.cpp b/cpp/wedpr-computing/ppc-mpc/tests/main.cpp new file mode 100644 index 00000000..2c06f9b5 --- /dev/null +++ b/cpp/wedpr-computing/ppc-mpc/tests/main.cpp @@ -0,0 +1,2 @@ +#define BOOST_TEST_MAIN +#include \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-pir/CMakeLists.txt b/cpp/wedpr-computing/ppc-pir/CMakeLists.txt new file mode 100644 index 00000000..0633d26f --- /dev/null +++ b/cpp/wedpr-computing/ppc-pir/CMakeLists.txt @@ -0,0 +1,7 @@ +add_subdirectory(src) + +if (TESTS) + enable_testing() + set(CTEST_OUTPUT_ON_FAILURE TRUE) + add_subdirectory(tests) +endif() diff --git a/cpp/wedpr-computing/ppc-pir/src/BaseOT.cpp b/cpp/wedpr-computing/ppc-pir/src/BaseOT.cpp new file mode 100644 index 00000000..98530d80 --- /dev/null +++ b/cpp/wedpr-computing/ppc-pir/src/BaseOT.cpp @@ -0,0 +1,288 @@ +/** + * Copyright (C) 2021 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 BaseOT.cpp + * @author: asherli + * @date 2023-03-13 + */ + +#include "BaseOT.h" +#include "Common.h" +#include "ppc-crypto-core/src/sym-crypto/OpenSSLAES.h" +#include "ppc-framework/crypto/SymCrypto.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +using namespace ppc::crypto; +using namespace ppc::protocol; +using namespace ppc::pir; +using namespace bcos; + +BaseOT::BaseOT(EccCrypto::Ptr _ecc, Hash::Ptr _hash) + : m_ecc(std::move(_ecc)), m_hash(std::move(_hash)) +{ + m_acculator = std::make_shared(OpenSSLAES::AESType::AES128); +} + +std::string genRandom(const int len) +{ + static const char alphanum[] = + "0123456789" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz"; + std::string tmp_s; + tmp_s.reserve(len); + + for (int i = 0; i < len; ++i) + { + tmp_s += alphanum[rand() % (sizeof(alphanum) - 1)]; + } + + return tmp_s; +} + + +bool isPrefix(bcos::bytes prefixBytes, bcos::bytes targetBytes) +{ + int len1 = prefixBytes.size(); + int len2 = targetBytes.size(); + + // If prefix is larger than target, then prefix can't be a prefix anymore. + if (len1 > len2) + { + return false; + } + + // Check if the first len1 bytes of "targetBytes" are equals to "prefixBytes". + for (int i = 0; i < len1; i++) + { + if (prefixBytes[i] != targetBytes[i]) + { + return false; + } + } + + return true; +} + + +SenderMessage BaseOT::senderGenerateCipher( + const bcos::bytes _choicesMessage, const uint32_t obfuscatedOrder) + +{ + PIR_LOG(INFO) << LOG_DESC("senderGenerateCipher"); + + bcos::bytes scalarBlidingA = m_ecc->generateRandomScalar(); + bcos::bytes scalarBlidingB = m_ecc->generateRandomScalar(); + bcos::bytes pointX = m_ecc->mulGenerator(scalarBlidingA); + bcos::bytes pointY = m_ecc->mulGenerator(scalarBlidingB); + bcos::bytes scalarC = m_ecc->scalarMul(scalarBlidingA, scalarBlidingB); + // PIR_LOG(INFO) << LOG_DESC("scalarBlidingA") << LOG_KV("scalarBlidingA", + // toHex(scalarBlidingA)); bcos::bytes scalarC_B = m_ecc->scalarSub(scalarC, scalarBlidingB); + // PIR_LOG(INFO) << LOG_DESC("scalarC_B") << LOG_KV("scalarC_B", toHex(scalarC_B)); + + + bcos::bytes pointZ = m_ecc->mulGenerator(scalarC); + // std::vector z0List; + // std::vector sendObfuscatedHash; + uint32_t reviewLength = 0; + if (_choicesMessage.size() < obfuscatedOrder) + { + reviewLength = _choicesMessage.size(); + } + else + { + reviewLength = obfuscatedOrder; + } + // 取vector的前k个字符 + bcos::bytes sendObfuscatedHash( + _choicesMessage.begin(), _choicesMessage.begin() + obfuscatedOrder); + bcos::bytes scalarId = m_ecc->hashToScalar(_choicesMessage); + PIR_LOG(INFO) << LOG_DESC("scalarId") << LOG_KV("scalarId", toHex(scalarId)); + + bcos::bytes scalarCSub = m_ecc->scalarSub(scalarC, scalarId); + bcos::bytes z0 = m_ecc->mulGenerator(scalarCSub); + + + SenderMessage senderMessage; + senderMessage.pointX = pointX; + senderMessage.pointY = pointY; + senderMessage.scalarBlidingA = scalarBlidingA; + senderMessage.scalarBlidingB = scalarBlidingB; + senderMessage.pointZ = z0; + senderMessage.sendObfuscatedHash = sendObfuscatedHash; + return senderMessage; +} + +ReceiverMessage BaseOT::receiverGenerateMessage(const bcos::bytes pointX, const bcos::bytes pointY, + const std::vector> messageKeypair, const bcos::bytes pointZ) +{ + PIR_LOG(INFO) << LOG_DESC("receiverGenerateMessage") + << LOG_KV("messageKeypair size", messageKeypair.size()); + PIR_LOG(INFO) << LOG_DESC("receiverGenerateMessage") << LOG_KV("pointX", toHex(pointX)) + << LOG_KV("pointY", toHex(pointY)) << LOG_KV("pointZ", toHex(pointZ)); + // std::vector encryptMessagePair(messageKeypair.size()); + // std::vector pointWList(messageKeypair.size()); + // std::vector encryptCipher(messageKeypair.size()); + std::vector encryptMessagePair; + std::vector pointWList; + std::vector encryptCipher; + for (uint32_t i = 0; i < messageKeypair.size(); ++i) + { + // PIR_LOG(TRACE) << LOG_DESC("round") << LOG_KV("i", i); + bcos::bytes scalarBlidingR = m_ecc->generateRandomScalar(); + bcos::bytes scalarBlidingS = m_ecc->generateRandomScalar(); + bcos::bytes pointWLeft = m_ecc->ecMultiply(pointX, scalarBlidingS); + bcos::bytes pointWRight = m_ecc->mulGenerator(scalarBlidingR); + bcos::bytes pointW = m_ecc->ecAdd(pointWLeft, pointWRight); + bcos::bytes pointKeyRight = m_ecc->ecMultiply(pointY, scalarBlidingR); + // std::cout << "pointW" << toHex(pointW) << std::endl; + pointWList.push_back(pointW); + bcos::bytes scalarId = m_ecc->hashToScalar(messageKeypair[i].first); + // PIR_LOG(INFO) << LOG_DESC("scalarId") << LOG_KV("scalarId", toHex(scalarId)); + + // std::cout << "iter->first" << std::string(messageKeypair[i].first.begin(), + // messageKeypair[i].first.end()) << std::endl; + + // point是33个字节uint_8 + bcos::bytes pointZRight = m_ecc->mulGenerator(scalarId); + // PIR_LOG(INFO) << LOG_DESC("pointZRight") << LOG_KV("pointZRight.size()", + // pointZRight.size()); + + // TODO: use random aes key 128bit + bcos::bytes message = messageKeypair[i].second; + // std::vector encryptMessageList; + bcos::bytes defaultPrefix(pir::DEFAULT_PREFIX.begin(), pir::DEFAULT_PREFIX.end()); + bcos::bytes randomKey = m_ecc->generateRandomScalar(); + + + // 截取defaultPrefix和randomKey的前16个字节拼接成一个新的bcos::bytes类型 + bcos::bytes newBytes; + bcos::bytes aesKey; + aesKey.insert(aesKey.end(), randomKey.begin(), randomKey.begin() + 16); + newBytes.insert(newBytes.end(), defaultPrefix.begin(), defaultPrefix.begin() + 16); + newBytes.insert(newBytes.end(), randomKey.begin(), randomKey.begin() + 16); + bcos::bytes encryptedData = m_acculator->encrypt( + SymCrypto::OperationMode::CBC, bcos::ref(aesKey), bcos::ref(m_iv), bcos::ref(message)); + encryptCipher.push_back(encryptedData); + // PIR_LOG(INFO) << LOG_DESC("aesKey") << LOG_KV("aesKey", toHex(aesKey)); + + bcos::bytes pointZi = m_ecc->ecAdd(pointZ, pointZRight); + bcos::bytes pointKeyLeft = m_ecc->ecMultiply(pointZi, scalarBlidingS); + bcos::bytes pointKey = m_ecc->ecAdd(pointKeyLeft, pointKeyRight); + // PIR_LOG(INFO) << LOG_DESC("pointKey") << LOG_KV("pointKey", toHex(pointKey)); + // PIR_LOG(INFO) << LOG_DESC("message") << LOG_KV("message", + // std::string(message.begin(),message.end())); + + if (pointKey.size() < newBytes.size()) + { + BOOST_THROW_EXCEPTION( + CipherLengthFailException() << errinfo_comment("encrypt ot newBytes fail")); + } + bcos::bytes encryptMessage; + for (uint32_t k = 0; k < newBytes.size(); ++k) + { + encryptMessage.push_back(newBytes[k] ^ pointKey[k]); + // encryptMessage.push_back(message[k]); + } + encryptMessagePair.push_back(encryptMessage); + } + PIR_LOG(INFO) << LOG_DESC("init result"); + ReceiverMessage result; + result.pointWList = pointWList; + result.encryptMessagePair = encryptMessagePair; + result.encryptCipher = encryptCipher; + PIR_LOG(INFO) << LOG_DESC("end ReceiverMessage"); + return result; +} + +bcos::bytes BaseOT::finishSender(const bcos::bytes scalarBlidingB, + const std::vector pointWList, const std::vector encryptMessagePair, + std::vector encryptCipher) +{ + PIR_LOG(INFO) << LOG_DESC("finishSender"); + // std::vector indexList; + std::vector decryptKeyList; + if (encryptMessagePair.size() != pointWList.size()) + { + PIR_LOG(ERROR) << LOG_DESC("check encryptMessagePair and pointWList fail") + << LOG_KV("encryptMessagePair.size", encryptMessagePair.size()) + << LOG_KV("pointWList.size", pointWList.size()); + BOOST_THROW_EXCEPTION(CipherLengthFailException() + << errinfo_comment("check sendObfuscatedHash and pointWList fail")); + } + + for (uint32_t i = 0; i < pointWList.size(); ++i) + { + bcos::bytes pointW = pointWList[i]; + PIR_LOG(INFO) << LOG_DESC("BaseOT::finishSender") << LOG_KV("pointW", toHex(pointW)); + + bcos::bytes messagePair = encryptMessagePair[i]; + bcos::bytes key = m_ecc->ecMultiply(pointW, scalarBlidingB); + PIR_LOG(INFO) << LOG_DESC("key") << LOG_KV("key", toHex(key)); + bcos::bytes decryptMessage; + for (uint32_t k = 0; k < messagePair.size(); ++k) + { + decryptMessage.push_back(messagePair[k] ^ key[k]); + // decryptMessage.push_back(messagePair[i][k]); + } + PIR_LOG(INFO) << LOG_DESC("decryptMessage") + << LOG_KV("decryptMessage", + std::string(decryptMessage.begin(), decryptMessage.end())); + if (isPrefix(bcos::bytes(DEFAULT_PREFIX.begin(), DEFAULT_PREFIX.end()), decryptMessage)) + { + // 截取bcos::bytes的16-32个字节 + bcos::bytes aesKey(decryptMessage.begin() + 16, decryptMessage.begin() + 32); + PIR_LOG(INFO) << LOG_DESC("aesKey") << LOG_KV("aesKey", toHex(aesKey)); + PIR_LOG(INFO) << LOG_DESC("encryptCipher") + << LOG_KV("encryptCipher[i]", toHex(encryptCipher[i])); + bcos::bytes decryptData(m_acculator->blockSize()); + OutputBuffer decryptedBytes{decryptData.data(), decryptData.size()}; + m_acculator->decrypt(&decryptedBytes, SymCrypto::OperationMode::CBC, bcos::ref(aesKey), + bcos::ref(m_iv), bcos::ref(encryptCipher[i])); + PIR_LOG(INFO) << LOG_DESC("decryptData") + << LOG_KV("decryptData", + std::string(decryptData.begin(), decryptData.end())); + + return decryptData; + } + } + + return bcos::bytes(); +} + + +std::vector> BaseOT::prepareDataset( + bcos::bytes sendObfuscatedHashPrefix, std::string datasetPath) +{ + PIR_LOG(INFO) << LOG_DESC("prepareDataset") + << LOG_KV( + "sendObfuscatedHashPrefix", std::string(sendObfuscatedHashPrefix.begin(), + sendObfuscatedHashPrefix.end())); + PIR_LOG(INFO) << LOG_DESC("prepareDataset") << LOG_KV("datasetPath", datasetPath); + + std::vector> messageKeypair = + pir::readInputsByMmapWithPrefix(datasetPath, sendObfuscatedHashPrefix); + + return messageKeypair; +} diff --git a/cpp/wedpr-computing/ppc-pir/src/BaseOT.h b/cpp/wedpr-computing/ppc-pir/src/BaseOT.h new file mode 100644 index 00000000..cf3888d7 --- /dev/null +++ b/cpp/wedpr-computing/ppc-pir/src/BaseOT.h @@ -0,0 +1,105 @@ +/** + * Copyright (C) 2022 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 BaseOT.h + * @author: asherli + * @date 2023-03-13 + */ + +#pragma once + +#include "ppc-framework/Common.h" +#include "ppc-framework/crypto/EccCrypto.h" +#include "ppc-framework/crypto/Hash.h" +#include "ppc-framework/crypto/SymCrypto.h" + +#include "ppc-framework/protocol/Protocol.h" +#include +#include +#include + + +namespace ppc::crypto +{ +struct SenderMessage +{ + std::string taskId; + // std::vector idIndexList; + // 私有保存的密钥 + bcos::bytes scalarBlidingA; + bcos::bytes scalarBlidingB; + // 发送的数据 + bcos::bytes pointX; + bcos::bytes pointY; + bcos::bytes pointZ; + // 筛选前缀 + bcos::bytes sendObfuscatedHash; +}; + + +struct ReceiverMessage +{ + std::string path; + std::vector pointWList; + // 加密的AES key, baseOT交互的结果 + std::vector encryptMessagePair; + // 加密的AES cipher + std::vector encryptCipher; +}; + +class BaseOT : public std::enable_shared_from_this +{ +public: + using Ptr = std::shared_ptr; + + BaseOT() = delete; + ~BaseOT() = default; + + BaseOT(EccCrypto::Ptr _ecc, Hash::Ptr _hash); + + + // sender use id_list = [id1,id2,...], generate bliding a, b + // calculate X = a * G, Y = b * G, c_id = a * b, z_delta = c_id * Gm z_0 = (c_id - id) * G + // z_0_list = [z_0_id1,z_0_id2,...] + // obfuscatedOrder披露多少个字符 + SenderMessage senderGenerateCipher( + const bcos::bytes _choicesMessage, const uint32_t obfuscatedOrder); + + // receiver generate random ri, si + // calculate wi = si * X + ri * G, zi = z0 + id * G + // key = si * zi + ri * Y, Ei = key xor mi + // mi is AES key for Enc(message) + ReceiverMessage receiverGenerateMessage(const bcos::bytes pointX, const bcos::bytes pointY, + const std::vector> messageKeypair, + const bcos::bytes pointZ); + + // calculate b * G xor Ei = key + // AES decrypt message + bcos::bytes finishSender(const bcos::bytes scalarBlidingB, + const std::vector pointWList, + const std::vector encryptMessagePair, std::vector encryptCipher); + + std::vector> prepareDataset( + bcos::bytes sendObfuscatedHash, std::string datasetPath); + + +private: + EccCrypto::Ptr m_ecc; + Hash::Ptr m_hash; + bcos::bytes m_iv = bcos::bytes(0); + ppc::crypto::SymCrypto::Ptr m_acculator; +}; + +} // namespace ppc::crypto diff --git a/cpp/wedpr-computing/ppc-pir/src/CMakeLists.txt b/cpp/wedpr-computing/ppc-pir/src/CMakeLists.txt new file mode 100644 index 00000000..d1b6a28a --- /dev/null +++ b/cpp/wedpr-computing/ppc-pir/src/CMakeLists.txt @@ -0,0 +1,31 @@ +set(TARS_HEADER_DIR ${CMAKE_BINARY_DIR}/generated/ppc-pir/tars) +find_program(TARS_TARS2CPP tars2cpp REQUIRED) +file(GLOB_RECURSE SOURCES "*.cpp" "*.h") + +file(GLOB_RECURSE TARS_INPUT "*.tars") + +# generate tars +if (TARS_INPUT) + foreach (TARS_FILE ${TARS_INPUT}) + get_filename_component(TARS_NAME ${TARS_FILE} NAME_WE) + get_filename_component(TARS_PATH ${TARS_FILE} PATH) + add_custom_command( + OUTPUT ${TARS_HEADER_DIR}/${TARS_NAME}.h + WORKING_DIRECTORY ${TARS_PATH} + COMMAND ${TARS_TARS2CPP} ${TARS_FILE} --unjson --without-trace --dir=${TARS_HEADER_DIR} + COMMENT "generating ${TARS_FILE} to ${TARS_HEADER_DIR}" + VERBATIM + ) + + list(APPEND OUT_TARS_H_LIST ${TARS_HEADER_DIR}/${TARS_NAME}.h) + endforeach () +endif () + +set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${OUT_TARS_H_LIST}") +include_directories(${TARS_HEADER_DIR}) + +add_library(${PIR_TARGET} ${SOURCES} ${OUT_TARS_H_LIST}) +target_include_directories(${PIR_TARGET} PUBLIC + $) + +target_link_libraries(${PIR_TARGET} PUBLIC ${PSI_FRAMEWORK_TARGET} ${CRYPTO_TARGET}) diff --git a/cpp/wedpr-computing/ppc-pir/src/Common.h b/cpp/wedpr-computing/ppc-pir/src/Common.h new file mode 100644 index 00000000..561a89aa --- /dev/null +++ b/cpp/wedpr-computing/ppc-pir/src/Common.h @@ -0,0 +1,199 @@ +/* + * Copyright (C) 2022 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 Common.h + * @author: asherli + * @date 2023-03-13 + */ +#pragma once +#include "ppc-framework/Common.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define PIR_LOG(LEVEL) BCOS_LOG(LEVEL) << LOG_BADGE("PIR") + +namespace ppc::pir +{ +// const std::string DEFAULT_MESSAGE = "message not found"; +const std::string DEFAULT_PREFIX = "PPC_DEFAULT_MESG"; + + +enum class OTPIRMessageType : uint8_t +{ + HELLO_RECEIVER = 0x01, + RESULTS = 0x02 +}; + +enum class OTPIRRetCode : int +{ + ON_EXCEPTION = -3000, + UNDEFINED_TASK_ROLE = -3001, + INVALID_TASK_PARAM = -3002 +}; + +inline bool isPrefixMatched(const bcos::bytes& _prefix, const char* begin, const char* end) +{ + size_t prefixLen = _prefix.size(); + if (end - begin < prefixLen) + return false; + for (size_t i = 0; i < prefixLen; ++i) + { + if (_prefix[i] != *(begin + i)) + return false; + } + return true; +} + +// 从Task param解析 +struct PirTaskMessage +{ + std::string searchId; + std::string requestAgencyId; + std::string requestAgencyDataset; + uint32_t prefixLength; +}; + +// 通过前缀读取符合要求的行,写到buffer中 +// 我们约定id在每行最前 +inline std::vector> readInputsByMmapWithPrefix( + const std::string& _path, const bcos::bytes& _prefix) +{ + std::vector> _buffer; + int fd = open(_path.c_str(), O_RDONLY); + struct stat fs + { + }; + + if (fd == -1 || fstat(fd, &fs) == -1) + { + BOOST_THROW_EXCEPTION(std::runtime_error("open file error: " + _path)); + } + + char* buf = (char*)mmap(nullptr, fs.st_size, PROT_READ, MAP_PRIVATE, fd, 0); + if (buf == MAP_FAILED) + { + close(fd); + BOOST_THROW_EXCEPTION(std::runtime_error("mmap file to memory error: " + _path)); + } + + char* buf_end = buf + fs.st_size; + + char *begin = buf, *end = buf, c; + while (true) + { + if (!(*end == '\r' || *end == '\n')) + { + if (++end < buf_end) + continue; + } + else if (1 + end < buf_end) + { + // see if we got "\r\n" or "\n\r" here + c = *(1 + end); + if ((c == '\r' || c == '\n') && c != *end) + ++end; + } + // 判断_prefix和buf中begin, end这一行的前缀是否相同 + if (isPrefixMatched(_prefix, begin, end)) + { + std::string st(begin, end); + std::stringstream ss(st); + std::string idIndex; + std::getline(ss, idIndex, ','); + // 将begin, end这一行的前缀是否相同按逗号分割,取逗号前的内容 + std::pair pairTmp; + pairTmp.first = bcos::bytes(idIndex.begin(), idIndex.end()); + pairTmp.second = bcos::bytes(begin, end); + _buffer.push_back(pairTmp); + // _buffer[bcos::bytes(idIndex.begin(), idIndex.end())] = bcos::bytes(begin, end); + // _buffer->push_back(bcos::bytes(begin, end)); + } + + if ((begin = ++end) >= buf_end) + break; + } + + munmap(buf, fs.st_size); + close(fd); + return _buffer; +} + +inline PirTaskMessage parseJson(std::string_view _param) +{ + PIR_LOG(TRACE) << LOG_BADGE("parseJson") LOG_KV("_param", _param); + Json::Reader reader; + Json::Value result; + if (!reader.parse(_param.begin(), _param.end(), result)) + { + BOOST_THROW_EXCEPTION( + BCOS_ERROR((int)OTPIRRetCode::INVALID_TASK_PARAM, "invalid task param: invalid json")); + } + PIR_LOG(TRACE) << LOG_BADGE("result type") LOG_KV("result", result.type()); + if (!result.isObject() || result.empty()) + { + BOOST_THROW_EXCEPTION(BCOS_ERROR((int)OTPIRRetCode::INVALID_TASK_PARAM, + "invalid task param:: the param must be object")); + } + PirTaskMessage taskMessage; + + if (!result.isMember("searchId")) + { + BOOST_THROW_EXCEPTION(BCOS_ERROR((int)OTPIRRetCode::INVALID_TASK_PARAM, + "invalid task param:: the param searchId not found")); + } + if (!result.isMember("requestAgencyId")) + { + BOOST_THROW_EXCEPTION(BCOS_ERROR((int)OTPIRRetCode::INVALID_TASK_PARAM, + "invalid task param:: the param requestAgencyId not found")); + } + if (!result.isMember("prefixLength")) + { + BOOST_THROW_EXCEPTION(BCOS_ERROR((int)OTPIRRetCode::INVALID_TASK_PARAM, + "invalid task param:: the param prefixLength not found")); + } + // if(!result.isMember("requestAgencyDataset")){ + // BOOST_THROW_EXCEPTION(BCOS_ERROR((int)OTPIRRetCode::INVALID_TASK_PARAM, + // "invalid task param:: the param requestAgencyDataset not found")); + // } + taskMessage.searchId = result["searchId"].asString(); + taskMessage.requestAgencyId = result["requestAgencyId"].asString(); + // taskMessage.requestAgencyDataset = result["requestAgencyDataset"].asString(); + taskMessage.prefixLength = result.get("prefixLength", 0).asInt(); + // taskMessage.prefixLength = result['prefixLength'].asInt(); + // if(result.isMember("requestAgencyDataset")){ + // taskMessage.requestAgencyDataset = result["requestAgencyDataset"].asString(); + // } + return taskMessage; +} + + +DERIVE_PPC_EXCEPTION(CipherLengthFailException); +DERIVE_PPC_EXCEPTION(FIleDeleteFailException); +} // namespace ppc::pir \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-pir/src/OtPIRConfig.h b/cpp/wedpr-computing/ppc-pir/src/OtPIRConfig.h new file mode 100644 index 00000000..e51b1ade --- /dev/null +++ b/cpp/wedpr-computing/ppc-pir/src/OtPIRConfig.h @@ -0,0 +1,68 @@ +/** + * Copyright (C) 2022 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 CM2020PSIConfig.h + * @author: shawnhe + * @date 2022-12-7 + */ + +#pragma once +#include + +#include + +#include "Common.h" +#include "ppc-crypto/src/oprf/EcdhOprf.h" +#include "ppc-framework/crypto/CryptoBox.h" +#include "ppc-framework/crypto/Oprf.h" +#include "ppc-framework/protocol/Protocol.h" +#include "ppc-psi/src/PSIConfig.h" +#include "protocol/src/PPCMessage.h" + +namespace ppc::pir +{ +class OtPIRConfig : public ppc::psi::PSIConfig +{ +public: + using Ptr = std::shared_ptr; + + OtPIRConfig(std::string const& _selfPartyID, ppc::front::FrontInterface::Ptr _front, + ppc::crypto::CryptoBox::Ptr _cryptoBox, bcos::ThreadPool::Ptr _threadPool, + ppc::io::DataResourceLoader::Ptr _dataResourceLoader, int _holdingMessageMinutes, + uint16_t _parallelism = 3, + const front::PPCMessageFactory::Ptr& _msgFactory = + std::make_shared()) + : PSIConfig(ppc::protocol::TaskAlgorithmType::OT_PIR_2PC, _selfPartyID, std::move(_front), + _msgFactory, std::move(_dataResourceLoader), _holdingMessageMinutes), + m_cryptoBox(std::move(_cryptoBox)), + m_threadPool(std::move(_threadPool)), + m_parallelism(_parallelism) + {} + + virtual ~OtPIRConfig() = default; + +public: + crypto::Hash::Ptr const& hash() const { return m_cryptoBox->hashImpl(); } + crypto::EccCrypto::Ptr const& eccCrypto() const { return m_cryptoBox->eccCrypto(); } + bcos::ThreadPool::Ptr const& threadPool() const { return m_threadPool; } + uint16_t parallelism() const { return m_parallelism; } + +private: + ppc::crypto::CryptoBox::Ptr m_cryptoBox; + bcos::ThreadPool::Ptr m_threadPool; + uint16_t m_parallelism; +}; + +} // namespace ppc::pir \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-pir/src/OtPIRFactory.h b/cpp/wedpr-computing/ppc-pir/src/OtPIRFactory.h new file mode 100644 index 00000000..eb86632f --- /dev/null +++ b/cpp/wedpr-computing/ppc-pir/src/OtPIRFactory.h @@ -0,0 +1,45 @@ +/** + * Copyright (C) 2022 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 CM2020PSIFactory.h + * @author: shawnhe + * @date 2022-12-7 + */ +#pragma once +#include "OtPIRImpl.h" +#include "ppc-framework/crypto/CryptoBox.h" +#include "ppc-framework/io/DataResourceLoader.h" + +namespace ppc::pir +{ +class OtPIRFactory +{ +public: + using Ptr = std::shared_ptr; + OtPIRFactory() = default; + virtual ~OtPIRFactory() = default; + + virtual OtPIRImpl::Ptr buildOtPIR(std::string const& _selfParty, + ppc::front::FrontInterface::Ptr _front, ppc::crypto::CryptoBox::Ptr _cryptoBox, + bcos::ThreadPool::Ptr _threadPool, ppc::io::DataResourceLoader::Ptr _dataResourceLoader, + int _holdingMessageMinutes) + { + auto config = + std::make_shared(_selfParty, std::move(_front), std::move(_cryptoBox), + std::move(_threadPool), std::move(_dataResourceLoader), _holdingMessageMinutes); + return std::make_shared(config); + } +}; +} // namespace ppc::pir \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-pir/src/OtPIRImpl.cpp b/cpp/wedpr-computing/ppc-pir/src/OtPIRImpl.cpp new file mode 100644 index 00000000..a37fd892 --- /dev/null +++ b/cpp/wedpr-computing/ppc-pir/src/OtPIRImpl.cpp @@ -0,0 +1,582 @@ +/* + * Copyright (C) 2022 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 AYSService.cpp + * @author: asherli + * @date 2023-03-20 + */ + +#include "OtPIRImpl.h" +#include "BaseOT.h" +#include "Common.h" +#include "OtPIR.h" +#include "ppc-framework/protocol/Protocol.h" +#include "ppc-front/Common.h" +#include "wedpr-protocol/tars/TarsSerialize.h" +#include + + +using namespace ppc; +using namespace bcos; +using namespace ppc::io; +using namespace ppc::protocol; +using namespace ppc::pir; +using namespace ppc::task; +using namespace ppc::psi; + + +OtPIRImpl::OtPIRImpl(const OtPIRConfig::Ptr& _config, unsigned _idleTimeMs) + : Worker("OT-PIR", _idleTimeMs), + TaskGuarder(_config, TaskAlgorithmType::OT_PIR_2PC, "OT-PIR-Timer"), + m_config(_config), + m_msgQueue(std::make_shared()), + m_ioService(std::make_shared()), + m_parallelism(m_config->parallelism()) +{ + m_senderThreadPool = + std::make_shared("OT-PIR-Sender", std::thread::hardware_concurrency()); + m_ot = std::make_shared(m_config->eccCrypto(), m_config->hash()); +} + +void OtPIRImpl::start() +{ + if (m_started) + { + PIR_LOG(WARNING) << LOG_DESC("The OT-PIR has already been started"); + return; + } + PIR_LOG(INFO) << LOG_DESC("Start the OT-PIR"); + m_started = true; + + // start a thread to execute task + startWorking(); + + m_thread = std::make_shared([&] { + bcos::pthread_setThreadName("otPir_io_service"); + while (m_started) + { + try + { + m_ioService->run(); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + if (m_started && m_ioService->stopped()) + { + m_ioService->restart(); + } + } + catch (std::exception& e) + { + FRONT_LOG(WARNING) + << LOG_DESC("Exception in OT-PIR Thread:") << boost::diagnostic_information(e); + } + } + PIR_LOG(INFO) << "OT-PIR exit"; + }); + + startPingTimer(); +} + +void OtPIRImpl::stop() +{ + if (!m_started) + { + return; + } + PIR_LOG(INFO) << LOG_DESC("Stop OT-PIR"); + m_started = false; + + if (m_config->threadPool()) + { + m_config->threadPool()->stop(); + } + + finishWorker(); + if (isWorking()) + { + // stop the worker thread + stopWorking(); + terminate(); + } + + if (m_senderThreadPool) + { + m_senderThreadPool->stop(); + } + if (m_ioService) + { + m_ioService->stop(); + } + // stop the thread + if (m_thread->get_id() != std::this_thread::get_id()) + { + m_thread->join(); + } + else + { + m_thread->detach(); + } + stopPingTimer(); + + PIR_LOG(INFO) << LOG_DESC("OT-PIR stopped"); +} + +// register to the front to get the message related to cm2020-psi +void OtPIRImpl::onReceiveMessage(ppc::front::PPCMessageFace::Ptr _msg) +{ + try + { + m_msgQueue->push(_msg); + + // notify to handle the message + m_signal.notify_all(); + } + catch (std::exception const& e) + { + PIR_LOG(WARNING) << LOG_DESC("onReceiveMessage exception") << printPPCMsg(_msg) + << LOG_KV("error", boost::diagnostic_information(e)); + } +} + +void OtPIRImpl::onReceivedErrorNotification(ppc::front::PPCMessageFace::Ptr const& _message) +{ + PIR_LOG(WARNING) << LOG_DESC("onReceivedErrorNotification") << printPPCMsg(_message); + // finish the task while the peer is failed + auto taskState = findPendingTask(_message->taskID()); + if (taskState) + { + taskState->onPeerNotifyFinish(); + + wakeupWorker(); + } +} + +void OtPIRImpl::onSelfError(const std::string& _taskID, bcos::Error::Ptr _error, bool _noticePeer) +{ + PIR_LOG(WARNING) << LOG_DESC("onSelfError") << LOG_KV("task", _taskID) + << LOG_KV("error", _error->errorMessage()) + << LOG_KV("noticePeer", _noticePeer); + + auto taskState = findPendingTask(_taskID); + if (!taskState) + { + return; + } + + auto result = std::make_shared(taskState->task()->id()); + result->setError(std::move(_error)); + taskState->onTaskFinished(result, _noticePeer); + + wakeupWorker(); +} + + +// ot-pir main processing function +// for ut to make this function public +void OtPIRImpl::executeWorker() +{ + checkFinishedTask(); + auto result = m_msgQueue->tryPop(c_popWaitMs); + if (result.first) + { + handleReceivedMessage(result.second); + return; + } + waitSignal(); +} + + +void OtPIRImpl::checkFinishedTask() +{ + std::set finishedTask; + { + bcos::WriteGuard l(x_pendingTasks); + if (m_pendingTasks.empty()) + { + return; + } + + for (auto it = m_pendingTasks.begin(); it != m_pendingTasks.end();) + { + auto task = it->second; + if (task->finished()) + { + finishedTask.insert(it->first); + } + it++; + } + } + for (auto& taskID : finishedTask) + { + removeReceiver(taskID); + removeSender(taskID); + removePendingTask(taskID); + // asyncRunTask(); + } +} + + +void OtPIRImpl::handleReceivedMessage(const ppc::front::PPCMessageFace::Ptr& _message) +{ + PIR_LOG(TRACE) << LOG_DESC("handleReceivedMessage") << printPPCMsg(_message); + + m_config->threadPool()->enqueue([self = weak_from_this(), _message]() { + try + { + auto pir = self.lock(); + if (!pir) + { + return; + } + switch (int(_message->messageType())) + { + case int(CommonMessageType::ErrorNotification): + { + pir->onReceivedErrorNotification(_message); + break; + } + case int(CommonMessageType::PingPeer): + { + break; + } + case int(OTPIRMessageType::HELLO_RECEIVER): + { + pir->onHelloReceiver(_message); + break; + } + case int(OTPIRMessageType::RESULTS): + { + pir->onSnederResults(_message); + break; + } + default: + { + PIR_LOG(WARNING) << LOG_DESC("unsupported messageType ") + << unsigned(_message->messageType()); + break; + } + } + } + catch (std::exception const& e) + { + PIR_LOG(WARNING) << LOG_DESC("handleReceivedMessage exception") + << LOG_KV("type", unsigned(_message->messageType())) + << printPPCMsg(_message) + << LOG_KV("error", boost::diagnostic_information(e)); + } + }); +} + +void OtPIRImpl::onHelloReceiver(const ppc::front::PPCMessageFace::Ptr& _message) +{ + // 接收方不需要记录taskID + // if (m_taskState->taskDone()) + // { + // return; + // } + PIR_LOG(DEBUG) << LOG_BADGE("onHelloReceiver") << LOG_KV("taskID", _message->taskID()) + << LOG_KV("seq", _message->seq()) << LOG_KV("length", _message->length()); + ppctars::SenderMessageParams senderMessageParams; + ppctars::serialize::decode(*_message->data(), senderMessageParams); + // crypto::SenderMessage senderMessage; + // TODO: how to find my dataset + // m_taskState->setReader(io::LineReader::Ptr _reader, int64_t _readerParam) + + try + { + // auto writer = m_taskState->reader(); + auto receiver = findReceiver(_message->taskID()); + auto path = receiver.path; + PIR_LOG(INFO) << LOG_BADGE("onHelloReceiver") << LOG_KV("taskID", _message->taskID()) + << LOG_KV("requestAgencyDataset", path) + << LOG_KV("sendObfuscatedHash", + std::string(senderMessageParams.sendObfuscatedHash.begin(), + senderMessageParams.sendObfuscatedHash.end())); + + auto messageKeypair = m_ot->prepareDataset(senderMessageParams.sendObfuscatedHash, path); + auto receiverMessage = m_ot->receiverGenerateMessage(senderMessageParams.pointX, + senderMessageParams.pointY, messageKeypair, senderMessageParams.pointZ); + ppctars::ReceiverMessageParams receiverMessageParams; + receiverMessageParams.encryptMessagePair = receiverMessage.encryptMessagePair; + receiverMessageParams.encryptCipher = receiverMessage.encryptCipher; + receiverMessageParams.pointWList = receiverMessage.pointWList; + // PIR_LOG(INFO) << LOG_BADGE("buildPPCMessage"); + + auto message = m_config->ppcMsgFactory()->buildPPCMessage(uint8_t(protocol::TaskType::PIR), + uint8_t(protocol::TaskAlgorithmType::OT_PIR_2PC), m_taskID, + std::make_shared()); + message->setMessageType(uint8_t(OTPIRMessageType::RESULTS)); + ppctars::serialize::encode(receiverMessageParams, *message->data()); + // PIR_LOG(INFO) << LOG_BADGE("asyncSendMessage"); + + m_config->front()->asyncSendMessage( + m_taskState->peerID(), message, m_config->networkTimeout(), + [self = weak_from_this()](bcos::Error::Ptr _error) { + auto receiver = self.lock(); + if (!receiver) + { + return; + } + if (_error && _error->errorCode()) + { + receiver->onReceiverTaskDone(std::move(_error)); + } + }, + nullptr); + auto endTask = std::make_shared(m_taskState->task()->id()); + m_taskState->onTaskFinished(endTask, true); + } + catch (bcos::Error const& e) + { + PIR_LOG(WARNING) << LOG_DESC("onHelloReceiver exception") << LOG_KV("code", e.errorCode()) + << LOG_KV("msg", e.errorMessage()); + onSelfError(m_taskID, std::make_shared(e.errorCode(), e.errorMessage()), true); + } +} + +void OtPIRImpl::onSnederResults(ppc::front::PPCMessageFace::Ptr _message) +{ + PIR_LOG(DEBUG) << LOG_BADGE("onSnederResults") << LOG_KV("taskID", _message->taskID()) + << LOG_KV("seq", _message->seq()); + + ppctars::ReceiverMessageParams receiverMessageParams; + ppctars::serialize::decode(*_message->data(), receiverMessageParams); + crypto::SenderMessage senderMessage = findSender(_message->taskID()); + PIR_LOG(DEBUG) << LOG_BADGE("onSnederResults") + << LOG_KV("scalarBlidingB", toHex(senderMessage.scalarBlidingB)) + << LOG_KV("pointWList Size", receiverMessageParams.pointWList.size()) + << LOG_KV("encryptCipher Size", receiverMessageParams.encryptCipher.size()) + << LOG_KV("encryptMessagePair Size", + receiverMessageParams.encryptMessagePair.size()); + bcos::bytes result = + m_ot->finishSender(senderMessage.scalarBlidingB, receiverMessageParams.pointWList, + receiverMessageParams.encryptMessagePair, receiverMessageParams.encryptCipher); + saveResults(result); + auto endTask = std::make_shared(m_taskState->task()->id()); + m_taskState->onTaskFinished(endTask, true); +} + +void OtPIRImpl::asyncRunTask( + ppc::protocol::Task::ConstPtr _task, TaskResponseCallback&& _onTaskFinished) +{ + // TODO + PIR_LOG(INFO) << LOG_DESC("receive a task") << LOG_KV("taskID", _task->id()); + m_taskID = _task->id(); + addTask(_task, [self = weak_from_this(), taskID = _task->id(), _onTaskFinished]( + ppc::protocol::TaskResult::Ptr&& _result) { + auto result = std::move(_result); + _onTaskFinished(std::move(result)); + PIR_LOG(INFO) << LOG_DESC("finish a task") << LOG_KV("taskID", taskID); + auto pir = self.lock(); + if (!pir) + { + return; + } + pir->m_parallelism++; + }); + asyncRunTask(); +} + +void OtPIRImpl::asyncRunTask() +{ + PIR_LOG(INFO) << LOG_DESC("asyncRunTask") << LOG_KV("current semaphore", m_parallelism); + + if (m_parallelism <= 0) + { + return; + } + + std::pair taskPair; + { + bcos::UpgradableGuard l(x_taskQueue); + if (m_taskQueue.empty()) + { + return; + } + + bcos::UpgradeGuard ul(l); + taskPair = m_taskQueue.front(); + m_taskQueue.pop(); + m_parallelism--; + } + + auto task = taskPair.first; + + bcos::Error::Ptr error; + + // add pending task + m_taskState = + m_taskStateFactory->createTaskState(task, std::move(taskPair.second), false, m_config); + m_taskState->setPeerID(getPeerID(task)); + // m_taskState->registerNotifyPeerFinishHandler([self = weak_from_this(), task]() { + // auto pir = self.lock(); + // if (!pir) + // { + // return; + // } + + // pir->noticePeerToFinish(task); + // }); + addPendingTask(m_taskState); + + try + { + auto dataResource = task->selfParty()->dataResource(); + auto role = task->selfParty()->partyIndex(); + + if (role == uint16_t(PartyType::Client)) + { + auto originData = m_taskState->task()->param(); + + PIR_LOG(TRACE) << LOG_DESC("originData") << LOG_KV("originData", originData); + PirTaskMessage taskMessage = parseJson(originData); + PIR_LOG(TRACE) << LOG_DESC("taskMessage") + << LOG_KV("requestAgencyDataset", taskMessage.requestAgencyDataset) + << LOG_KV("prefixLength", taskMessage.prefixLength) + << LOG_KV("searchId", taskMessage.searchId); + auto writer = + loadWriter(task->id(), dataResource, m_taskState->task()->enableOutputExists()); + m_taskState->setWriter(writer); + runSenderGenerateCipher(taskMessage); + } + else if (role == uint16_t(PartyType::Server)) + { + // server接受任务请求,初始化reader + PIR_LOG(TRACE) << LOG_DESC("Server init"); + crypto::ReceiverMessage receiverMessage; + receiverMessage.path = dataResource->desc()->path(); + addReceiver(receiverMessage); + // m_resource = dataResource; + // auto reader = loadReader(task->id(), dataResource, DataSchema::Bytes); + // m_taskState->setReader(reader, -1); + } + else + { + PIR_LOG(WARNING) << LOG_DESC("undefined task role") << unsigned(role); + onSelfError(task->id(), + std::make_shared( + (int)OTPIRRetCode::UNDEFINED_TASK_ROLE, "undefined task role"), + true); + } + } + catch (bcos::Error const& e) + { + PIR_LOG(WARNING) << LOG_DESC("asyncRunTask exception") << printTaskInfo(task) + << LOG_KV("code", e.errorCode()) << LOG_KV("msg", e.errorMessage()); + onSelfError( + task->id(), std::make_shared(e.errorCode(), e.errorMessage()), true); + } + catch (const std::exception& e) + { + PIR_LOG(WARNING) << LOG_DESC("asyncRunTask exception") << printTaskInfo(task) + << LOG_KV("error", boost::diagnostic_information(e)); + onSelfError(task->id(), + std::make_shared((int)OTPIRRetCode::ON_EXCEPTION, + "exception caught while running task: " + boost::diagnostic_information(e)), + true); + } + + // notify the taskInfo to the front + error = m_config->front()->notifyTaskInfo(task->id()); + if (error && error->errorCode()) + { + onSelfError(task->id(), error, true); + } +} + +void OtPIRImpl::runSenderGenerateCipher(PirTaskMessage taskMessage) +{ + if (m_taskState->taskDone()) + { + return; + } + crypto::SenderMessage senderMessage = m_ot->senderGenerateCipher( + bcos::bytes(taskMessage.searchId.begin(), taskMessage.searchId.end()), + taskMessage.prefixLength); + ppctars::SenderMessageParams senderMessageParams; + senderMessageParams.pointX = senderMessage.pointX; + senderMessageParams.pointY = senderMessage.pointY; + senderMessageParams.pointZ = senderMessage.pointZ; + // senderMessageParams.requestAgencyDataset = taskMessage.requestAgencyDataset; + senderMessageParams.sendObfuscatedHash = senderMessage.sendObfuscatedHash; + auto message = m_config->ppcMsgFactory()->buildPPCMessage(uint8_t(protocol::TaskType::PIR), + uint8_t(protocol::TaskAlgorithmType::OT_PIR_2PC), m_taskID, + std::make_shared()); + message->setMessageType(uint8_t(OTPIRMessageType::HELLO_RECEIVER)); + ppctars::serialize::encode(senderMessageParams, *message->data()); + addSender(senderMessage); + // PIR_LOG(INFO) << LOG_BADGE("runSenderGenerateCipher") << LOG_KV("taskID", m_taskID) << + // LOG_KV("requestAgencyDataset", senderMessageParams.requestAgencyDataset); + PIR_LOG(INFO) << LOG_BADGE("runSenderGenerateCipher") << LOG_KV("taskID", m_taskID) + << LOG_KV("sendObfuscatedHash", + std::string(senderMessageParams.sendObfuscatedHash.begin(), + senderMessageParams.sendObfuscatedHash.end())); + // senderMessageParams.taskId = m_taskID; + m_config->front()->asyncSendMessage( + m_taskState->peerID(), message, m_config->networkTimeout(), + [self = weak_from_this()](bcos::Error::Ptr _error) { + auto receiver = self.lock(); + if (!receiver) + { + return; + } + if (_error && _error->errorCode()) + { + receiver->onReceiverTaskDone(std::move(_error)); + } + }, + nullptr); +} + + +void OtPIRImpl::onReceiverTaskDone(bcos::Error::Ptr _error) +{ + if (m_taskState->taskDone() && (!_error || _error->errorCode() == 0)) + { + return; + } + + PIR_LOG(INFO) << LOG_BADGE("onReceiverTaskDone") LOG_KV("taskID", m_taskID); + + std::string message; + if (_error) + { + message = "\nStatus: FAIL\nMessage: " + _error->errorMessage(); + m_taskResult->setError(std::move(_error)); + } + m_taskState->onTaskFinished(m_taskResult, true); + + PIR_LOG(INFO) << LOG_BADGE("receiverTaskDone") << LOG_KV("taskID", m_taskID) + << LOG_KV("detail", message); +} + + +void OtPIRImpl::saveResults(bcos::bytes result) +{ + PIR_LOG(INFO) << LOG_BADGE("saveResults") LOG_KV("taskID", m_taskID); + try + { + DataBatch::Ptr finalResults = std::make_shared(); + finalResults->append(result); + m_taskState->writeLines(finalResults, DataSchema::Bytes); + } + catch (const std::exception& e) + { + PIR_LOG(WARNING) << LOG_KV("taskID", m_taskID) + << LOG_KV("error", boost::diagnostic_information(e)); + auto error = std::make_shared( + (int)OTPIRRetCode::ON_EXCEPTION, boost::diagnostic_information(e)); + onReceiverTaskDone(error); + } +} diff --git a/cpp/wedpr-computing/ppc-pir/src/OtPIRImpl.h b/cpp/wedpr-computing/ppc-pir/src/OtPIRImpl.h new file mode 100644 index 00000000..d48773a2 --- /dev/null +++ b/cpp/wedpr-computing/ppc-pir/src/OtPIRImpl.h @@ -0,0 +1,202 @@ +/* + * Copyright (C) 2022 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 AYSService.h + * @author: asherli + * @date 2023-03-13 + */ +#pragma once +#include "Common.h" +// #include "OtPIR.h" +#include "BaseOT.h" +#include "OtPIRConfig.h" +#include "ppc-framework/protocol/DataResource.h" +#include "ppc-framework/protocol/Task.h" +#include "ppc-framework/task/TaskFrameworkInterface.h" +#include "ppc-psi/src/psi-framework/TaskGuarder.h" +#include "ppc-rpc/src/RpcFactory.h" +#include +#include +#include +#include +#include + +namespace ppc::pir +{ +class OtPIRImpl : public std::enable_shared_from_this, + public bcos::Worker, + public psi::TaskGuarder, // taskGuarder并不一定属于psi-framework + public ppc::task::TaskFrameworkInterface +// class OtPIRImpl : public std::enable_shared_from_this +{ +public: + using Ptr = std::shared_ptr; + // OtPIRImpl() = default; + OtPIRImpl(const OtPIRConfig::Ptr& _config, unsigned _idleTimeMs = 0); + ~OtPIRImpl() override = default; + using OtPIRMsgQueue = bcos::ConcurrentQueue; + using OtPIRMsgQueuePtr = std::shared_ptr; + + // run task + void asyncRunTask(ppc::protocol::Task::ConstPtr _task, + ppc::task::TaskResponseCallback&& _onTaskFinished) override; + + void start() override; + void stop() override; + + // register to the front to get the message related to ot-pir + void onReceiveMessage(ppc::front::PPCMessageFace::Ptr _message) override; + + void onReceivedErrorNotification(ppc::front::PPCMessageFace::Ptr const& _message) override; + void onSelfError( + const std::string& _taskID, bcos::Error::Ptr _error, bool _noticePeer) override; + + // ot-pir main processing function + // for ut to make this function public + void executeWorker() override; + + void handleReceivedMessage(const ppc::front::PPCMessageFace::Ptr& _message); + + void onHelloReceiver(const ppc::front::PPCMessageFace::Ptr& _message); + // void onReceiveHelloSender(const ppc::front::PPCMessageFace::Ptr& _message); + + void onSnederResults(ppc::front::PPCMessageFace::Ptr _message); + const std::string& taskID() const { return m_taskID; } + + + // void makeBaseOt(Json::Value const& request, Json::Value& response); + // void encryptDataset(Json::Value const& request, Json::Value& response); + + // void setAYSConfig(AYSConfig const& aysConfig); + // std::vector prepareDataset(bcos::bytes sendObfuscatedHash, std::string + // datasetPath); + +protected: + void asyncRunTask(); + void checkFinishedTask(); + void runSenderGenerateCipher(PirTaskMessage taskMessage); + void saveResults(bcos::bytes result); + + void onReceiverTaskDone(bcos::Error::Ptr _error); + // void runReceiverGenerateMessage(ppctars::SenderMessageParams senderMessageParams); + // void runFinishSender(PirTaskMessage taskMessage); + + void addTask( + ppc::protocol::Task::ConstPtr _task, ppc::task::TaskResponseCallback&& _onTaskFinished) + { + bcos::WriteGuard l(x_taskQueue); + m_taskQueue.push({std::move(_task), std::move(_onTaskFinished)}); + } + + crypto::ReceiverMessage findReceiver(const std::string& _taskID) + { + bcos::ReadGuard l(x_receivers); + auto it = m_receivers.find(_taskID); + if (it != m_receivers.end()) + { + return it->second; + } + return crypto::ReceiverMessage(); + } + void addReceiver(crypto::ReceiverMessage _receiver) + { + bcos::WriteGuard l(x_receivers); + m_receivers[m_taskID] = _receiver; + } + void removeReceiver(const std::string& _taskID) + { + bcos::WriteGuard l(x_receivers); + auto it = m_receivers.find(_taskID); + if (it != m_receivers.end()) + { + m_receivers.erase(it); + } + } + + crypto::SenderMessage findSender(const std::string& _taskID) + { + bcos::ReadGuard l(x_senders); + auto it = m_senders.find(_taskID); + if (it != m_senders.end()) + { + return it->second; + } + return crypto::SenderMessage(); + } + void addSender(crypto::SenderMessage _sender) + { + bcos::WriteGuard l(x_senders); + // m_taskID + m_senders[m_taskID] = _sender; + } + void removeSender(const std::string& _taskID) + { + bcos::WriteGuard l(x_senders); + auto it = m_senders.find(_taskID); + if (it != m_senders.end()) + { + m_senders.erase(it); + } + } + // 为true时启动时会从配置中加载文件作为匹配源 + bool m_enableMemoryFile = false; + ppc::protocol::DataResource m_resource; + + +private: + void wakeupWorker() { m_signal.notify_all(); } + + bool m_started{false}; + std::shared_ptr m_thread; + std::shared_ptr m_ioService; + OtPIRConfig::Ptr m_config; + + std::shared_ptr m_senderThreadPool; + crypto::BaseOT::Ptr m_ot; + std::atomic m_parallelism; + OtPIRMsgQueuePtr m_msgQueue; + + boost::condition_variable m_signal; + + const int c_popWaitMs = 5; + boost::mutex x_signal; + // 查询方需要的数据,包含要发送的和私有保存的 + // crypto::SenderMessage senderMessage; + std::unordered_map m_senders; + mutable bcos::SharedMutex x_senders; + + // 数据方发送的数据,全部要发送 + // crypto::ReceiverMessage receiverMessage; + std::unordered_map m_receivers; + mutable bcos::SharedMutex x_receivers; + + std::vector> messageKeypair; + std::queue> + m_taskQueue; + mutable bcos::SharedMutex x_taskQueue; + + // // setup的系统参数,分桶大小来决定披露前k个bit 目前版本由TASK先传入 + // const int obfuscation_order = 6; + std::string m_taskID; + ppc::psi::TaskState::Ptr m_taskState; + ppc::protocol::TaskResult::Ptr m_taskResult; + + void waitSignal() + { + boost::unique_lock l(x_signal); + m_signal.wait_for(l, boost::chrono::milliseconds(5)); + } +}; +} // namespace ppc::pir \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-pir/src/protocol/OtPIR.tars b/cpp/wedpr-computing/ppc-pir/src/protocol/OtPIR.tars new file mode 100644 index 00000000..664e5ae4 --- /dev/null +++ b/cpp/wedpr-computing/ppc-pir/src/protocol/OtPIR.tars @@ -0,0 +1,15 @@ +module ppctars { + struct SenderMessageParams { + 1 require vector pointX; + 2 require vector pointY; + 3 require vector pointZ; + 4 require vector sendObfuscatedHash; + 5 require string requestAgencyDataset; + }; + + struct ReceiverMessageParams { + 1 require vector> pointWList; + 2 require vector> encryptMessagePair; + 3 require vector> encryptCipher; + }; +}; diff --git a/cpp/wedpr-computing/ppc-pir/tests/CMakeLists.txt b/cpp/wedpr-computing/ppc-pir/tests/CMakeLists.txt new file mode 100644 index 00000000..ba2cabe0 --- /dev/null +++ b/cpp/wedpr-computing/ppc-pir/tests/CMakeLists.txt @@ -0,0 +1,10 @@ +file(GLOB_RECURSE SOURCES "*.cpp" "*.h") + +# cmake settings +set(TEST_BINARY_NAME test-ppc-pir) + +add_executable(${TEST_BINARY_NAME} ${SOURCES}) +target_include_directories(${TEST_BINARY_NAME} PRIVATE .) + +target_link_libraries(${TEST_BINARY_NAME} PUBLIC ${PIR_TARGET} ${BOOST_UNIT_TEST}) +add_test(NAME test-pir WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} COMMAND ${TEST_BINARY_NAME}) \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-pir/tests/FakeOtPIRFactory.h b/cpp/wedpr-computing/ppc-pir/tests/FakeOtPIRFactory.h new file mode 100644 index 00000000..30e6ce60 --- /dev/null +++ b/cpp/wedpr-computing/ppc-pir/tests/FakeOtPIRFactory.h @@ -0,0 +1,90 @@ +/** + * Copyright (C) 2022 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 FakeOtPIRFactory.h + * @author: shawnhe + * @date 2022-12-19 + */ +#pragma once + +#include "ppc-crypto-core/src/hash/BLAKE2bHash.h" +#include "ppc-crypto-core/src/hash/Sha512Hash.h" +#include "ppc-crypto/src/ecc/Ed25519EccCrypto.h" +#include "ppc-crypto/src/ecc/OpenSSLEccCrypto.h" +#include "ppc-framework/crypto/CryptoBox.h" +#include "ppc-io/src/DataResourceLoaderImpl.h" +#include "ppc-tools/src/config/PPCConfig.h" +#include "test-utils/FakeFront.h" +#include + +using namespace bcos; +using namespace ppc::protocol; +using namespace ppc::psi; +using namespace ppc::pir; +using namespace ppc::crypto; +using namespace ppc::io; +using namespace ppc::front; +using namespace ppc::tools; + +namespace ppc::test +{ +class FakeOtPIRImpl : public OtPIRImpl +{ +public: + using Ptr = std::shared_ptr; + FakeOtPIRImpl(OtPIRConfig::Ptr const& _config, unsigned _idleTimeMs = 0) + : OtPIRImpl(_config, _idleTimeMs) + {} + ~FakeOtPIRImpl() override = default; +}; + +class FakeOtPIRFactory : public OtPIRFactory +{ +public: + using Ptr = std::shared_ptr; + + FakeOtPIRFactory() + : m_front(std::make_shared()), + m_dataResourceLoader(std::make_shared( + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr)), + m_threadPool(std::make_shared("ot-pir", 4)) + { + auto hashImpl = std::make_shared(); + auto eccCrypto = + std::make_shared(hashImpl, ppc::protocol::ECCCurve::P256); + m_cryptoBox = std::make_shared(hashImpl, eccCrypto); + } + + ~FakeOtPIRFactory() override = default; + + OtPIRImpl::Ptr createOtPIR(std::string const& _selfParty) + { + auto config = std::make_shared( + _selfParty, m_front, m_cryptoBox, m_threadPool, m_dataResourceLoader, 1); + + return std::make_shared(config); + } + + DataResourceLoaderImpl::Ptr resourceLoader() { return m_dataResourceLoader; } + FakeFront::Ptr front() { return m_front; } + CryptoBox::Ptr cryptoBox() { return m_cryptoBox; } + +private: + FakeFront::Ptr m_front; + DataResourceLoaderImpl::Ptr m_dataResourceLoader; + ThreadPool::Ptr m_threadPool; + CryptoBox::Ptr m_cryptoBox; +}; +} // namespace ppc::test \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-pir/tests/TestBaseOT.cpp b/cpp/wedpr-computing/ppc-pir/tests/TestBaseOT.cpp new file mode 100644 index 00000000..615e309b --- /dev/null +++ b/cpp/wedpr-computing/ppc-pir/tests/TestBaseOT.cpp @@ -0,0 +1,254 @@ +/* + * Copyright (C) 2022 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 applicabl 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 TestCEMService.cpp + * @author: asherli + * @date 2023-03-13 + */ +#include "FakeOtPIRFactory.h" +#include "ppc-crypto-core/src/hash/HashFactoryImpl.h" +#include "ppc-crypto/src/ecc/EccCryptoFactoryImpl.h" +#include "ppc-crypto/src/ecc/OpenSSLEccCrypto.h" +#include "ppc-framework/protocol/Protocol.h" +#include "ppc-pir/src/BaseOT.h" +#include "ppc-pir/src/Common.h" +#include "ppc-pir/src/OtPIRImpl.h" +#include "test-utils/TaskMock.h" +#include +#include +#include +#include + +using namespace ppc::pir; +using namespace ppc::crypto; +using namespace ppc::pir; +using namespace bcos; +using namespace bcos::test; + +namespace ppc::test +{ +BOOST_FIXTURE_TEST_SUITE(OtPIRest, TestPromptFixture) + +BOOST_AUTO_TEST_CASE(testBaseOT) +{ + // 统计函数执行时间 + std::cout << "testBaseOT" << std::endl; + + auto eccFactory = std::make_shared(); + auto hashFactory = std::make_shared(); + auto hash = hashFactory->createHashImpl((int8_t)ppc::protocol::HashImplName::SHA512); + EccCrypto::Ptr ecc = eccFactory->createEccCrypto((int8_t)ppc::protocol::ECCCurve::P256, hash); + // auto aysService = std::make_shared(); + // auto aes = std::make_shared( + // OpenSSLAES::AESType::AES128, + // SymCrypto::OperationMode::CBC, _seed, bcos::bytes()); + + std::string datasetPath = "../../../../wedpr-computing/ppc-pir/tests/data/AysPreDataset.csv"; + // std::cout<< "aysService->prepareDataset" << std::endl; + std::string prefix = "testmsg1"; + bcos::bytes sendObfuscatedHash(prefix.begin(), prefix.end()); + + uint32_t obfuscatedOrder = 10; + auto baseOT = std::make_shared(ecc, hash); + auto messageKeypair = baseOT->prepareDataset(sendObfuscatedHash, datasetPath); + // for(auto iter = messageKeypair.begin(); iter != messageKeypair.end(); + // ++iter) + // { + // std::string pairKey(iter->first.begin(), iter->first.end()); + // std::string pairValue(iter->second.begin(), iter->second.end()); + // // for(uint32_t i = 0; i < messageKeypair.size(); ++i) { + // // std::cout<< "pairKey:"<< pairKey << std::endl; + // // std::cout<< "pairValue:"<< pairValue << std::endl; + // } + auto start = std::chrono::high_resolution_clock::now(); + + std::string choice = "testmsg1100"; + // std::cout<< "baseOT->senderGenerateCipher" << std::endl; + auto senderMessage = + baseOT->senderGenerateCipher(bcos::bytes(choice.begin(), choice.end()), obfuscatedOrder); + // std::cout<< "baseOT->receiverGenerateMessage" << std::endl; + auto receiverMessage = baseOT->receiverGenerateMessage( + senderMessage.pointX, senderMessage.pointY, messageKeypair, senderMessage.pointZ); + + // std::cout<< "baseOT->finishSender" << std::endl; + auto result = baseOT->finishSender(senderMessage.scalarBlidingB, receiverMessage.pointWList, + receiverMessage.encryptMessagePair, receiverMessage.encryptCipher); + + auto end = std::chrono::high_resolution_clock::now(); + + auto duration = std::chrono::duration_cast(end - start); + std::cout << "执行时间 time: " << duration.count() << " microseconds" << std::endl; + + if (result.size() == 0) + { + std::cout << "final result: message not found" << std::endl; + } + else + { + std::cout << "final result: " << std::string(result.begin(), result.end()) << std::endl; + } + // for(uint32_t i = 0; i < result.size(); ++i) + // { + // std::cout<< std::string(result[i].begin(), result[i].end()) << + // std::endl; + // } + + BOOST_CHECK(true); +} + +void testOTPIR(FakeOtPIRFactory::Ptr _factory, OtPIRImpl::Ptr _sender, OtPIRImpl::Ptr _receiver, + ppc::protocol::Task::ConstPtr _senderPirTask, ppc::protocol::Task::ConstPtr _receiverPirTask, + std::vector const& _expectedPIRResult, bool _expectedSuccess, + int _expectedErrorCode = 0) +{ + std::atomic flag = 0; + + _sender->asyncRunTask(_senderPirTask, [_senderPirTask, _expectedSuccess, _expectedErrorCode, + &flag](ppc::protocol::TaskResult::Ptr&& _response) { + if (_expectedSuccess) + { + BOOST_CHECK(_response->error() == nullptr || _response->error()->errorCode() == 0); + BOOST_CHECK(_response->taskID() == _senderPirTask->id()); + auto result = _response->error(); + BOOST_CHECK(result == nullptr || result->errorCode() == 0); + } + else + { + BOOST_CHECK(_response->error() != nullptr); + auto result = _response->error(); + BOOST_CHECK(result != nullptr); + BOOST_CHECK(_response->error()->errorCode() == _expectedErrorCode); + } + flag++; + }); + _sender->start(); + + _receiver->asyncRunTask(_receiverPirTask, + [_receiverPirTask, _expectedSuccess, &flag](ppc::protocol::TaskResult::Ptr&& _response) { + if (_expectedSuccess) + { + BOOST_CHECK(_response->error() == nullptr || _response->error()->errorCode() == 0); + BOOST_CHECK(_response->taskID() == _receiverPirTask->id()); + auto result = _response->error(); + BOOST_CHECK(result == nullptr || result->errorCode() == 0); + } + else + { + BOOST_CHECK(_response->error() != nullptr); + auto result = _response->error(); + BOOST_CHECK(result != nullptr); + } + flag++; + }); + _receiver->start(); + + // wait for the task finish and check + while (flag < 2) + { + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } + + _sender->stop(); + _receiver->stop(); + + // if (_expectedSuccess && !_expectedPIRResult.empty()) + // { + // checkTaskPIRResult(_factory->resourceLoader(), _receiverPirTask, + // _expectedPIRResult.size(), + // _expectedPIRResult); + // } +} + +void testOTPIRImplFunc(const std::string& _taskID, const std::string& _params, bool _syncResults, + PartyResource::Ptr _senderParty, PartyResource::Ptr _receiverParty, + std::vector const& _expectedPIRResult, bool _expectedSuccess, + int _expectedErrorCode = 0) +{ + auto factory = std::make_shared(); + + // fake the sender + std::string senderAgencyName = "sender"; + auto senderPIR = factory->createOtPIR("sender"); + + // fake the receiver + std::string receiverAgencyName = _receiverParty->id(); + auto receiverPIR = factory->createOtPIR(receiverAgencyName); + + // register the server-pir into the front + factory->front()->registerOTPIR(senderAgencyName, senderPIR); + factory->front()->registerOTPIR(receiverAgencyName, receiverPIR); + + // trigger the pir task + auto senderPIRTask = std::make_shared(senderAgencyName); + senderPIRTask->setId(_taskID); + senderPIRTask->setParam(_params); + senderPIRTask->setEnableOutputExists(true); + senderPIRTask->setSelf(_senderParty); + senderPIRTask->addParty(_receiverParty); + senderPIRTask->setSyncResultToPeer(_syncResults); + senderPIRTask->setAlgorithm((uint8_t)TaskAlgorithmType::OT_PIR_2PC); + senderPIRTask->setType((uint8_t)ppc::protocol::TaskType::PIR); + + auto receiverPIRTask = std::make_shared(receiverAgencyName); + receiverPIRTask->setId(_taskID); + receiverPIRTask->setParam(_params); + receiverPIRTask->setEnableOutputExists(true); + receiverPIRTask->setSelf(_receiverParty); + receiverPIRTask->addParty(_senderParty); + receiverPIRTask->setSyncResultToPeer(_syncResults); + receiverPIRTask->setAlgorithm((uint8_t)TaskAlgorithmType::OT_PIR_2PC); + receiverPIRTask->setType((uint8_t)ppc::protocol::TaskType::PIR); + + testOTPIR(factory, senderPIR, receiverPIR, senderPIRTask, receiverPIRTask, _expectedPIRResult, + _expectedSuccess, _expectedErrorCode); +} + +BOOST_AUTO_TEST_CASE(testNormalOtPIRCase) +{ + std::string otSearchPath = "../../../../wedpr-computing/ppc-pir/tests/data/AysPreDataset.csv"; + std::string outputPath = "../../../../wedpr-computing/ppc-pir/tests/data/output.csv"; + + uint32_t count = 513; + // prepareInputs(senderPath, count, receiverPath, count, count); + + auto senderParty = mockParty((uint16_t)ppc::protocol::PartyType::Client, "sender", + "senderPartyResource", "sender_inputs", protocol::DataResourceType::FILE, ""); + auto senderOutputDesc = std::make_shared(); + senderOutputDesc->setPath(outputPath); + senderParty->mutableDataResource()->setOutputDesc(senderOutputDesc); + + auto receiverParty = mockParty((uint16_t)ppc::protocol::PartyType::Server, "receiver", + "receiverPartyResource", "receiver_inputs", DataResourceType::FILE, otSearchPath); + + // auto receiverOutputDesc = std::make_shared(); + // receiverOutputDesc->setPath(outputPath); + // receiverParty->mutableDataResource()->setOutputDesc(receiverOutputDesc); + + std::vector expectedResult; + for (uint32_t i = 0; i < count; i++) + { + expectedResult.emplace_back(std::to_string(100000 + i)); + } + + std::string jobParams = + "{\"searchId\":\"testmsg1100\",\"requestAgencyId\":" + "\"receiver\",\"prefixLength\":6}"; + + testOTPIRImplFunc( + "0x12345678", jobParams, true, senderParty, receiverParty, expectedResult, true, 0); +} + +BOOST_AUTO_TEST_SUITE_END() +} // namespace ppc::test diff --git a/cpp/wedpr-computing/ppc-pir/tests/data/AysPreDataset.csv b/cpp/wedpr-computing/ppc-pir/tests/data/AysPreDataset.csv new file mode 100644 index 00000000..590b61f2 --- /dev/null +++ b/cpp/wedpr-computing/ppc-pir/tests/data/AysPreDataset.csv @@ -0,0 +1,3 @@ +id,x1 +1,test +2,test2 diff --git a/cpp/wedpr-computing/ppc-pir/tests/main.cpp b/cpp/wedpr-computing/ppc-pir/tests/main.cpp new file mode 100644 index 00000000..2c06f9b5 --- /dev/null +++ b/cpp/wedpr-computing/ppc-pir/tests/main.cpp @@ -0,0 +1,2 @@ +#define BOOST_TEST_MAIN +#include \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-pir/tests/test.json b/cpp/wedpr-computing/ppc-pir/tests/test.json new file mode 100644 index 00000000..37bf327b --- /dev/null +++ b/cpp/wedpr-computing/ppc-pir/tests/test.json @@ -0,0 +1,6 @@ +{ + "searchId": "testmsg1100", + "requestAgencyId": "1002", + "requestAgencyDataset": "../../../../wedpr-computing/ppc-pir/tests/data/AysPreDataset.csv", + "prefixLength": 6 +} \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-psi/CMakeLists.txt b/cpp/wedpr-computing/ppc-psi/CMakeLists.txt new file mode 100644 index 00000000..8e5aa738 --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/CMakeLists.txt @@ -0,0 +1,18 @@ +add_subdirectory(src/psi-framework) +add_subdirectory(src/labeled-psi) +add_subdirectory(src/ra2018-psi) +add_subdirectory(src/ecdh-psi) +add_subdirectory(src/cm2020-psi) +add_subdirectory(src/ecdh-multi-psi) +#add_subdirectory(src/ecdh-conn-psi) + +if(DEMO) + add_subdirectory(demo) +endif() +add_subdirectory(src/bs-ecdh-psi) + +if (TESTS) + enable_testing() + set(CTEST_OUTPUT_ON_FAILURE TRUE) + add_subdirectory(tests) +endif() diff --git a/cpp/wedpr-computing/ppc-psi/demo/CMakeLists.txt b/cpp/wedpr-computing/ppc-psi/demo/CMakeLists.txt new file mode 100644 index 00000000..6a6508e5 --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/demo/CMakeLists.txt @@ -0,0 +1,7 @@ +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) + +set(HASH_COLLISION_BINARY_NAME hash_collision_bench) +add_executable(${HASH_COLLISION_BINARY_NAME} hash_collision_bench.cpp) +target_link_libraries(${HASH_COLLISION_BINARY_NAME} ${CRYPTO_TARGET} ${IO_TARGET}) + +unset(CMAKE_RUNTIME_OUTPUT_DIRECTORY) diff --git a/cpp/wedpr-computing/ppc-psi/demo/hash_collision_bench.cpp b/cpp/wedpr-computing/ppc-psi/demo/hash_collision_bench.cpp new file mode 100644 index 00000000..9bc55861 --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/demo/hash_collision_bench.cpp @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2022 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 hash_collision_bench.cpp + * @desc: bench for hash collision test + * @author: yujiechen + * @date 2022-12-30 + */ +#include "ppc-crypto-core/src/hash/BitMixMurmurHash.h" +#include "ppc-crypto-core/src/hash/Sha256Hash.h" +#include "ppc-crypto/src/ecc/OpenSSLEccCrypto.h" +#include "ppc-crypto/src/oprf/RA2018Oprf.h" +#include "ppc-io/src/FileLineReader.h" + + +using namespace ppc::crypto; +using namespace ppc::io; +using namespace bcos; + +void Usage(std::string const& _appName) +{ + std::cout << _appName << "[file1] [file2] [hashBits]" << std::endl; +} + +int main(int argc, char* argv[]) +{ + if (argc < 3) + { + Usage(argv[0]); + return -1; + } + auto file1 = argv[1]; + auto file2 = argv[2]; + int hashBits = 32; + if (argc == 4) + { + hashBits = atoi(argv[3]); + } + if (hashBits != 32 && hashBits != 64) + { + std::cout << "Invalid hashBits, must be 32 or 64" << std::endl; + return -1; + } + std::cout << "hash_collision_bench, file1: " << file1 << std::endl; + std::cout << "hash_collision_bench, file2: " << file2 << std::endl; + auto lineReader1 = std::make_shared(file1); + auto lineReader2 = std::make_shared(file2); + + // load all data + auto dataBatch1 = lineReader1->next(-1, DataSchema::Bytes); + auto dataBatch2 = lineReader2->next(-1, DataSchema::Bytes); + std::cout << "* file1 element size:" << dataBatch1->size() << std::endl; + std::cout << "* file2 element size:" << dataBatch2->size() << std::endl; + + auto hashImpl = std::make_shared(); + auto eccCrypto = + std::make_shared(hashImpl, ppc::protocol::ECCCurve::P256); + auto privateKey = eccCrypto->generateRandomScalar(); + auto oprf = std::make_shared(privateKey, eccCrypto, hashImpl); + // full-evaluate + std::vector result1; + oprf->fullEvaluate(dataBatch1, result1); + std::vector result2; + oprf->fullEvaluate(dataBatch2, result2); + + // calculate the hash + std::set hashData; + auto hasher = std::make_shared(); + for (uint64_t i = 0; i < result1.size(); i++) + { + hashData.insert(hasher->hash(result1.at(i), hashBits)); + } + uint64_t collisionCount = 0; + // check the collision + for (uint64_t i = 0; i < result2.size(); i++) + { + auto hashResult = hasher->hash(result2.at(i), hashBits); + if (hashData.count(hashResult)) + { + collisionCount++; + auto collisionElement = dataBatch2->get(i); + std::cout << "* collision: " + << std::string(collisionElement.begin(), collisionElement.end()) << std::endl; + } + } + std::cout << "* hash_collision_bench test finished!" << std::endl; + std::cout << "* collisionCount: " << collisionCount << std::endl; + std::cout << "* file1 element size: " << dataBatch1->size() << std::endl; + std::cout << "* file2 element size: " << dataBatch2->size() << std::endl; + return 0; +} \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-psi/src/Common.h b/cpp/wedpr-computing/ppc-psi/src/Common.h new file mode 100644 index 00000000..4b95a8f5 --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/Common.h @@ -0,0 +1,167 @@ +/* + * Copyright (C) 2022 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 Common.h + * @author: yujiechen + * @date 2022-12-26 + */ +#pragma once +#include "ppc-framework/Common.h" +#include "ppc-tools/src/common/MemInfo.h" +#include +#include +#define PSI_LOG(LEVEL) BCOS_LOG(LEVEL) << LOG_BADGE("PSI") + +namespace ppc::psi +{ +enum class CommonMessageType : uint8_t +{ + ErrorNotification = 0xff, + PingPeer = 0xfe, +}; + +// the common psi packet-type +enum class PSIPacketType : uint32_t +{ + CancelTaskNotification = 0x01, // notify the peer that the task has been canceled for some + // reason + TaskSyncMsg = 0x02, // sync the task information + HandshakeRequest = 0x03, // the handshake request + HandshakeResponse = 0x04, // the handshake response + PSIResultSyncMsg = 0x05, // sync the psi-result to the psi-server in some cases + PSIResultSyncResponse = 0x06, // response for psi-result-sync + HandshakeSuccess = 0x07, // the client response to the server when handshake-success +}; + +// packetType for ra2018-psi +enum class RA2018PacketType : uint32_t +{ + CuckooFilterRequest = 100, // the client request the cuckoofilter + CuckooFilterResponse = 101, // the server response the cuckoofilter + EvaluateRequest = 102, // the client request the server to evaluate-data + EvaluateResponse = 103, // the server response the evaluated-data + MissingCuckooFilterRequest = 104, // request the missed cuckoo-filter + MissingCuckooFilterResponse, // response to the missed-cuckoo-filter-request +}; + +// packetType for ecdh-psi +enum class ECDHPacketType : uint32_t +{ + EvaluateRequest = 100, + EvaluateResponse = 101, + ServerBlindedData = 102, + SyncDataBatchInfo = 103, +}; + +enum PSIRetCode : int +{ + Success = 0, + TaskParamsError = -1000, + PeerNodeDown = -1001, + DuplicatedTask = -1002, + LoadDataFailed = -1003, + PeerNotifyFinish = -1004, + InvalidTaskParamForRA2018 = -1005, + DataResourceOccupied = -1006, + UnsupportedCommand = -1007, + LoadCuckooFilterDataError = -1008, + UnknownPSIPacketType = -1009, + TaskNotFound = -1010, + TaskInProcessing = -1011, + OnlySupportOnePeer = -1012, + UnsupportedPartyType = -1013, + NotSpecifyInputDataResource = -1014, + NotSpecifyOutputDataResource = -1015, + NotOfflineFullEvaluated = -1016, + BlindDataError = -1017, + syncCuckooFilterError = -1018, + NotSpecifyPeerDataResource = -1019, + HandshakeFailed = -1020, + SyncPSIResultFailed = -1021, + RA2018PSIDisabled = -1022, + HandleTaskError = -1023, + TaskNotReady = -1024, + TaskIsNotRunning = -1025, + OnException = -1026, + TaskExists = -1027, + TaskKilled = -1028, + TaskCountReachMax = -1029, + TaskTimeout = -1030 +}; + +enum CacheState +{ + Evaluating = 0, + Finalizing = 1, + Finalized = 2, + IntersectionProgressing = 3, + Intersectioned = 4, + StoreProgressing = 5, + Stored = 6, + Syncing = 7, + Synced = 8, +}; + +inline std::ostream& operator<<(std::ostream& _out, CacheState const& _state) +{ + switch (_state) + { + case CacheState::Evaluating: + _out << "Evaluating"; + break; + case CacheState::Finalizing: + _out << "Finalizing"; + break; + case CacheState::Finalized: + _out << "Finalized"; + break; + case CacheState::IntersectionProgressing: + _out << "IntersectionProgressing"; + break; + case CacheState::Intersectioned: + _out << "Intersectioned"; + break; + case CacheState::StoreProgressing: + _out << "StoreProgressing"; + break; + case CacheState::Stored: + _out << "Stored"; + break; + case CacheState::Syncing: + _out << "Syncing"; + break; + case CacheState::Synced: + _out << "Synced"; + break; + default: + _out << "UnknownCacheState"; + break; + } + return _out; +} + +inline void checkHostResource(uint64_t minNeededMemoryGB) +{ +#ifdef __linux__ + if (!ppc::tools::hasAvailableMem(minNeededMemoryGB)) + { + BOOST_THROW_EXCEPTION(WeDPRException() << bcos::errinfo_comment( + "Lack of memory, please try again later. minNeededMemoryGB: " + + std::to_string(minNeededMemoryGB))); + } +#endif +} + +} // namespace ppc::psi diff --git a/cpp/wedpr-computing/ppc-psi/src/PSIConfig.h b/cpp/wedpr-computing/ppc-psi/src/PSIConfig.h new file mode 100644 index 00000000..9bfd1650 --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/PSIConfig.h @@ -0,0 +1,174 @@ +/* + * Copyright (C) 2022 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 PSIConfig.h + * @author: yujiechen + * @date 2022-10-25 + */ +#pragma once +#include "Common.h" +#include "bcos-utilities/Common.h" +#include "ppc-framework/Helper.h" +#include "ppc-framework/front/FrontInterface.h" +#include "ppc-framework/io/DataResourceLoader.h" +#include "ppc-framework/protocol/Constant.h" +#include "ppc-framework/protocol/Protocol.h" +#include "psi-framework/interfaces/PSIMessageInterface.h" +#include +#include +#include + +namespace ppc::psi +{ +class PSIConfig +{ +public: + using Ptr = std::shared_ptr; + PSIConfig(ppc::protocol::TaskAlgorithmType _algorithmType, + ppc::io::DataResourceLoader::Ptr _dataResourceLoader, uint32_t minNeededMemoryGB = 1) + : m_algorithmType(_algorithmType), + m_dataResourceLoader(std::move(_dataResourceLoader)), + m_minNeededMemoryGB(minNeededMemoryGB) + {} + + PSIConfig(ppc::protocol::TaskAlgorithmType _algorithmType, const std::string& _selfParty, + ppc::front::FrontInterface::Ptr _front, + ppc::front::PPCMessageFaceFactory::Ptr _ppcMsgFactory, + ppc::io::DataResourceLoader::Ptr _dataResourceLoader, int _holdingMessageMinutes, + uint32_t minNeededMemoryGB = 1) + : m_algorithmType(_algorithmType), + m_selfParty(_selfParty), + m_front(std::move(_front)), + m_ppcMsgFactory(std::move(_ppcMsgFactory)), + m_dataResourceLoader(std::move(_dataResourceLoader)), + m_networkTimeout(_holdingMessageMinutes * 60 * 1000), + m_taskExpireTime(m_networkTimeout), + m_minNeededMemoryGB(minNeededMemoryGB) + { + PSI_LOG(INFO) << LOG_DESC("create PSIConfig") << LOG_KV("algorithmType", m_algorithmType) + << LOG_KV("holdingMessageMinutes", _holdingMessageMinutes) + << LOG_KV("networkTimeout", m_networkTimeout) + << LOG_KV("taskExpireTime", m_taskExpireTime) + << LOG_KV("minNeededMemoryGB", m_minNeededMemoryGB); + } + + virtual ~PSIConfig() = default; + + ppc::front::FrontInterface::Ptr const& front() const { return m_front; } + std::string selfParty() const { return m_selfParty; } + + ppc::protocol::TaskAlgorithmType algorithmType() const { return m_algorithmType; } + ppc::front::PPCMessageFaceFactory::Ptr const& ppcMsgFactory() const { return m_ppcMsgFactory; } + int networkTimeout() const { return m_networkTimeout; } + + bcos::Error::Ptr sendMessage(std::string const& _receiver, front::PPCMessageFace::Ptr _message) + { + std::promise completedFuture; + m_front->asyncSendMessage( + _receiver, std::move(_message), m_networkTimeout, + [&completedFuture]( + const bcos::Error::Ptr& _error) { completedFuture.set_value(_error); }, + nullptr); + + return completedFuture.get_future().get(); + } + + void generateAndSendPPCMessage(std::string const& _peerID, std::string const& _taskID, + PSIMessageInterface::Ptr const& _msg, std::function _callback, + uint32_t _seq = 0, ppc::front::CallbackFunc _responseCallback = nullptr) + { + auto ppcMsg = generatePPCMsg(_taskID, _msg, _seq); + PSI_LOG(TRACE) << LOG_DESC("generateAndSendPPCMessage") << LOG_KV("peer", _peerID) + << printPSIMessage(_msg) << LOG_KV("msgType", (int)_msg->packetType()) + << LOG_KV("seq", _seq); + m_front->asyncSendMessage( + _peerID, ppcMsg, m_networkTimeout, + [_callback](bcos::Error::Ptr _error) { + if (_callback) + { + _callback(std::move(_error)); + } + }, + _responseCallback); + // release the large buffer if no-need to use + if (ppcMsg->data() && ppcMsg->data()->size() > ppc::protocol::LARGE_MSG_THRESHOLD) + { + PSI_LOG(INFO) << LOG_DESC("sendMsg: Release large buffer since the message") + << LOG_KV("size", ppcMsg->data()->size()); + ppcMsg->releasePayload(); + MallocExtension::instance()->ReleaseFreeMemory(); + } + } + + void asyncSendResponse(bcos::bytes const& fromNode, std::string const& _taskID, + std::string const& _uuid, PSIMessageInterface::Ptr const& _msg, + ppc::front::ErrorCallbackFunc _callback, uint32_t _seq = 0) + { + auto ppcMsg = generatePPCMsg(_taskID, _msg, _seq); + PSI_LOG(TRACE) << LOG_DESC("sendResponse") << LOG_KV("peer", printNodeID(fromNode)) + << printPPCMsg(ppcMsg) << LOG_KV("msgType", (int)_msg->packetType()) + << LOG_KV("uuid", _uuid); + m_front->asyncSendResponse(fromNode, _uuid, ppcMsg, _callback); + } + + ppc::io::DataResourceLoader::Ptr const& dataResourceLoader() const + { + return m_dataResourceLoader; + } + + int taskExpireTime() const { return m_taskExpireTime; } + void setTaskExpireTime(int _taskExpireTime) { m_taskExpireTime = _taskExpireTime; } + + std::vector agencyList() const { return m_front->agencies(); } + + uint32_t minNeededMemoryGB() const { return m_minNeededMemoryGB; } + +protected: + ppc::front::PPCMessageFace::Ptr generatePPCMsg( + std::string const& _taskID, PSIMessageInterface::Ptr const& _msg, uint32_t _seq) + { + if (_msg->partyID().empty()) + { + _msg->setPartyID(m_selfParty); + } + auto encodedData = _msg->encode(); + auto ppcMsg = m_ppcMsgFactory->buildPPCMessage(); + ppcMsg->setTaskType((uint8_t)ppc::protocol::TaskType::PSI); + ppcMsg->setAlgorithmType((uint8_t)m_algorithmType); + ppcMsg->setTaskID(_taskID); + ppcMsg->setSender(m_selfParty); + ppcMsg->setData(encodedData); + ppcMsg->setSeq(_seq); + return ppcMsg; + } + +protected: + // the psi-alogrithm-type + ppc::protocol::TaskAlgorithmType m_algorithmType; + std::string m_selfParty; + ppc::front::FrontInterface::Ptr m_front; + // the front message factory + ppc::front::PPCMessageFaceFactory::Ptr m_ppcMsgFactory; + ppc::io::DataResourceLoader::Ptr m_dataResourceLoader; + + // the network-timeout, default 300s + int m_networkTimeout = 300000; + + // the task-expire time + int m_taskExpireTime = 10000; + + uint32_t m_minNeededMemoryGB = 1; +}; +} // namespace ppc::psi \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-psi/src/bs-ecdh-psi/BsEcdhPSIFactory.h b/cpp/wedpr-computing/ppc-psi/src/bs-ecdh-psi/BsEcdhPSIFactory.h new file mode 100644 index 00000000..cd3adf3c --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/bs-ecdh-psi/BsEcdhPSIFactory.h @@ -0,0 +1,46 @@ +/** + * 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 BsEcdhPSIFactory.h + * @author: shawnhe + * @date 2023-09-20 + */ + +#pragma once +#include "BsEcdhPSIFactory.h" +#include "ppc-framework/io/DataResourceLoader.h" +#include "ppc-psi/src/PSIConfig.h" +#include "ppc-psi/src/bs-ecdh-psi/BsEcdhPSIImpl.h" + +namespace ppc::psi +{ +class BsEcdhPSIFactory +{ +public: + using Ptr = std::shared_ptr; + BsEcdhPSIFactory() = default; + virtual ~BsEcdhPSIFactory() = default; + + virtual BsEcdhPSIImpl::Ptr buildBsEcdhPSI(bcos::ThreadPool::Ptr _threadPool, + ppc::io::DataResourceLoader::Ptr _dataResourceLoader, uint32_t _timeoutMinutes, + uint32_t minNeededMemoryGB = 1) + { + auto config = std::make_shared(ppc::protocol::TaskAlgorithmType::BS_ECDH_PSI, + std::move(_dataResourceLoader), minNeededMemoryGB); + return std::make_shared( + std::move(config), std::move(_threadPool), _timeoutMinutes); + } +}; +} // namespace ppc::psi \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-psi/src/bs-ecdh-psi/BsEcdhPSIImpl.cpp b/cpp/wedpr-computing/ppc-psi/src/bs-ecdh-psi/BsEcdhPSIImpl.cpp new file mode 100644 index 00000000..64cccd0a --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/bs-ecdh-psi/BsEcdhPSIImpl.cpp @@ -0,0 +1,385 @@ +/** + * 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 BsEcdhPSIImpl.cpp + * @author: shawnhe + * @date 2023-09-20 + */ + +#include "BsEcdhPSIImpl.h" + +using namespace bcos; +using namespace ppc::psi; +using namespace ppc::io; +using namespace ppc::protocol; + +BsEcdhResult::Ptr BsEcdhPSIImpl::getTaskStatus(GetTaskStatusRequest::Ptr _request) +{ + ReadGuard l(x_tasks); + auto state = m_taskStates.find(_request->taskID); + if (state == m_taskStates.end()) + { + auto result = std::make_shared(_request->taskID); + result->setError(std::make_shared(TaskNotFound, "Task not found.")); + return result; + } + + if (isNotExecutable(state->second->status())) + { + return state->second->result(); + } + + return prepareResultWithoutLock(_request->taskID, toString(state->second->status())); +} + +BsEcdhResult::Ptr BsEcdhPSIImpl::updateTaskStatus(UpdateTaskStatusRequest::Ptr _request) +{ + BS_ECDH_PSI_LOG(INFO) << LOG_DESC("update task status") << LOG_KV("taskID", _request->taskID) + << LOG_KV("status", _request->status); + + WriteGuard l(x_tasks); + auto state = m_taskStates.find(_request->taskID); + if (state == m_taskStates.end()) + { + auto result = std::make_shared(_request->taskID); + result->setError(std::make_shared(TaskNotFound, "Task not found.")); + return result; + } + + auto status = fromString(_request->status); + if (status == TaskStatus::RUNNING) + { + state->second->restartTask(); + } + else if (status == TaskStatus::PAUSING) + { + state->second->pauseTask(); + } + + if (isNotExecutable(state->second->status())) + { + return state->second->result(); + } + + return prepareResultWithoutLock(_request->taskID, toString(state->second->status())); +} + + +BsEcdhResult::Ptr BsEcdhPSIImpl::killTask(KillTaskRequest::Ptr _request) +{ + BS_ECDH_PSI_LOG(INFO) << LOG_DESC("kill task") << LOG_KV("taskID", _request->taskID); + + WriteGuard l(x_tasks); + auto result = std::make_shared(_request->taskID); + auto state = m_taskStates.find(_request->taskID); + if (state == m_taskStates.end()) + { + result->setError(std::make_shared(TaskNotFound, "Task not found.")); + return result; + } + + if (isExecutable(state->second->status())) + { + GetTaskStatusResponse response; + response.taskID = _request->taskID; + response.status = toString(TaskStatus::FAILED); + auto ecdhResult = std::make_shared(_request->taskID, response.serialize()); + ecdhResult->setError(std::make_shared(TaskKilled, "Task has been killed.")); + state->second->setResult(ecdhResult); + state->second->updateStatus(TaskStatus::FAILED); + } + + auto cache = m_taskCaches.find(state->second->taskID()); + if (cache != m_taskCaches.end()) + { + BS_ECDH_PSI_LOG(INFO) << LOG_DESC("clean finished task cache") + << LOG_KV("taskID", cache->second->taskID()); + m_taskCaches.erase(cache); + } + + return std::make_shared(_request->taskID); +} + +void BsEcdhPSIImpl::asyncRunTask( + RunTaskRequest::Ptr _request, std::function&& _onTaskFinished) +{ + try + { + BS_ECDH_PSI_LOG(INFO) << LOG_DESC("receive a task") + << LOG_KV("request", _request->toString()); + auto state = findTaskState(_request->taskID); + if (state) + { + BS_ECDH_PSI_LOG(WARNING) + << LOG_DESC("asyncRunTask, task exists.") << LOG_KV("taskID", _request->taskID); + if (_onTaskFinished) + { + _onTaskFinished(std::make_shared(_request->taskID)); + } + return; + } + + if (taskCount() >= MAX_TASK_COUNT) + { + BS_ECDH_PSI_LOG(WARNING) + << LOG_DESC("task count reach max.") << LOG_KV("taskID", _request->taskID); + auto result = std::make_shared(_request->taskID); + result->setError(std::make_shared(TaskCountReachMax, "Task count reaches max.")); + if (_onTaskFinished) + { + _onTaskFinished(std::move(result)); + } + return; + } + + // init task state + auto taskState = std::make_shared( + _request->taskID, TaskStatus::PENDING, m_timeoutMinutes); + // check the memory + checkHostResource(m_config->minNeededMemoryGB()); + // create ecdh cache + auto cache = std::make_shared( + _request->taskID, m_threadPool, m_taskGuarder, _request->dataResource, + _request->enableAudit, m_enableOutputExists, + [self = weak_from_this(), taskID = _request->taskID] { + auto psi = self.lock(); + if (psi) + { + psi->onSelfCiphersReady(taskID); + } + }, + [self = weak_from_this(), taskID = _request->taskID] { + auto psi = self.lock(); + if (psi) + { + psi->onAllCiphersReady(taskID); + } + }, + [self = weak_from_this(), taskID = _request->taskID]( + protocol::TaskStatus _status, BsEcdhResult::Ptr _result) { + auto psi = self.lock(); + if (psi) + { + psi->onTaskFinished(taskID, _status, std::move(_result)); + } + }, + _request->partnerInputsSize); + cache->start(); + + // add task + addTask(std::move(taskState), std::move(cache)); + + if (_onTaskFinished) + { + _onTaskFinished(std::make_shared(_request->taskID)); + } + } + catch (std::exception const& e) + { + BS_ECDH_PSI_LOG(ERROR) << LOG_DESC("asyncRunTask") + << LOG_KV("exception", boost::diagnostic_information(e)); + auto result = std::make_shared(_request->taskID); + result->setError(std::make_shared( + TaskParamsError, "Init task error: " + boost::diagnostic_information(e))); + if (_onTaskFinished) + { + _onTaskFinished(std::move(result)); + } + } +} + +BsEcdhResult::Ptr BsEcdhPSIImpl::fetchCipher(FetchCipherRequest::Ptr _request) +{ + auto result = checkTaskRequest(_request->taskID); + if (result.first) + { + return result.first; + } + return result.second->fetchCipher(std::move(_request)); +} + +BsEcdhResult::Ptr BsEcdhPSIImpl::sendEcdhCipher(SendEcdhCipherRequest::Ptr _request) +{ + auto result = checkTaskRequest(_request->taskID); + if (result.first) + { + return result.first; + } + return result.second->onEcdhCipherReceived(std::move(_request)); +} + +BsEcdhResult::Ptr BsEcdhPSIImpl::sendPartnerCipher(SendPartnerCipherRequest::Ptr _request) +{ + auto result = checkTaskRequest(_request->taskID); + if (result.first) + { + return result.first; + } + return result.second->onPartnerCipherReceived(std::move(_request)); +} + +std::pair BsEcdhPSIImpl::checkTaskRequest( + const std::string& _taskID) +{ + auto result = std::make_shared(_taskID); + + auto state = findTaskState(_taskID); + if (!state) + { + BS_ECDH_PSI_LOG(INFO) << LOG_DESC("checkTaskRequest, task not found.") + << LOG_KV("taskID", _taskID); + result->setError(std::make_shared(TaskNotFound, "Task not found.")); + return {result, nullptr}; + } + + // Even if the task is completed, the browser can continue to send ciphers. + if (state->status() != TaskStatus::RUNNING && state->status() != TaskStatus::PAUSING && + state->status() != TaskStatus::COMPLETED) + { + BS_ECDH_PSI_LOG(INFO) << LOG_DESC("checkTaskRequest, task is not running.") + << LOG_KV("taskID", _taskID); + result->setError(std::make_shared(TaskIsNotRunning, "Task is not running.")); + return {result, nullptr}; + } + + auto cache = findTaskCache(_taskID); + if (!cache) + { + BS_ECDH_PSI_LOG(INFO) << LOG_DESC("checkTaskRequest, task not found.") + << LOG_KV("taskID", _taskID); + result->setError(std::make_shared(TaskNotFound, "Task cache not found.")); + return {result, nullptr}; + } + + state->active(); + return {nullptr, cache}; +} + +void BsEcdhPSIImpl::start() +{ + if (m_started) + { + BS_ECDH_PSI_LOG(ERROR) << LOG_DESC("The BS-ECDH-PSI has already been started"); + return; + } + BS_ECDH_PSI_LOG(INFO) << LOG_DESC("Start the BS-ECDH-PSI"); + m_started = true; + + if (m_taskCleaner) + { + m_taskCleaner->registerTimeoutHandler([self = weak_from_this()] { + auto psi = self.lock(); + if (psi) + { + psi->checkAndCleanTask(); + } + }); + m_taskCleaner->start(); + } +} + + +void BsEcdhPSIImpl::stop() +{ + if (!m_started) + { + return; + } + BS_ECDH_PSI_LOG(INFO) << LOG_DESC("Stop BS-ECDH-PSI"); + m_started = false; + + if (m_taskCleaner) + { + m_taskCleaner->stop(); + } +} + +void BsEcdhPSIImpl::checkAndCleanTask() +{ + try + { + WriteGuard l(x_tasks); + for (auto state = m_taskStates.begin(); state != m_taskStates.end();) + { + state->second->autoPauseChecking(); + if (isNotExecutable(state->second->status()) || state->second->isTimeout() || + state->second->isExpired()) + { + auto cache = m_taskCaches.find(state->second->taskID()); + if (cache != m_taskCaches.end()) + { + BS_ECDH_PSI_LOG(INFO) << LOG_DESC("clean finished task cache") + << LOG_KV("taskID", cache->second->taskID()); + m_taskCaches.erase(cache); + } + } + + if (state->second->isExpired()) + { + BS_ECDH_PSI_LOG(INFO) + << LOG_DESC("clean expired task") << LOG_KV("taskID", state->second->taskID()); + state = m_taskStates.erase(state); + } + else + { + ++state; + } + } + } + catch (std::exception const& e) + { + BS_ECDH_PSI_LOG(ERROR) << LOG_DESC("checkAndCleanTask") + << LOG_KV("exception", boost::diagnostic_information(e)); + } + m_taskCleaner->restart(); +} + +void BsEcdhPSIImpl::onSelfCiphersReady(const std::string& _taskID) +{ + BS_ECDH_PSI_LOG(INFO) << LOG_DESC("onSelfCiphersReady") << LOG_KV("taskID", _taskID); + WriteGuard l(x_tasks); + auto state = m_taskStates.find(_taskID); + if (state != m_taskStates.end()) + { + state->second->setupAutoPause(); + } +} + +void BsEcdhPSIImpl::onAllCiphersReady(const std::string& _taskID) +{ + BS_ECDH_PSI_LOG(INFO) << LOG_DESC("allCiphersReady") << LOG_KV("taskID", _taskID); + WriteGuard l(x_tasks); + auto state = m_taskStates.find(_taskID); + if (state != m_taskStates.end()) + { + state->second->cancelAutoPause(); + } +} + +void BsEcdhPSIImpl::onTaskFinished( + const std::string& _taskID, protocol::TaskStatus _status, BsEcdhResult::Ptr _result) +{ + BS_ECDH_PSI_LOG(INFO) << LOG_DESC("onTaskFinished") << LOG_KV("taskID", _taskID) + << LOG_KV("status", toString(_status)); + { + WriteGuard l(x_tasks); + auto state = m_taskStates.find(_taskID); + if (state != m_taskStates.end()) + { + state->second->updateStatus(_status); + state->second->setResult(std::move(_result)); + } + } +} diff --git a/cpp/wedpr-computing/ppc-psi/src/bs-ecdh-psi/BsEcdhPSIImpl.h b/cpp/wedpr-computing/ppc-psi/src/bs-ecdh-psi/BsEcdhPSIImpl.h new file mode 100644 index 00000000..2b8de4ad --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/bs-ecdh-psi/BsEcdhPSIImpl.h @@ -0,0 +1,164 @@ +/** + * 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 BsEcdhPSIImpl.h + * @author: shawnhe + * @date 2023-09-20 + */ + +#pragma once + +#include "BsEcdhPSIInterface.h" +#include "Common.h" +#include "core/BsEcdhCache.h" +#include "core/BsEcdhIoHandler.h" +#include "core/BsEcdhTaskState.h" +#include "ppc-psi/src/psi-framework/TaskGuarder.h" +#include +#include +#include +#include +#include +#include + +namespace ppc::psi +{ +class BsEcdhPSIImpl : public BsEcdhPSIInterface, public std::enable_shared_from_this +{ +public: + using Ptr = std::shared_ptr; + + BsEcdhPSIImpl( + PSIConfig::Ptr _config, bcos::ThreadPool::Ptr _threadPool, uint32_t _timeoutMinutes) + : m_config(std::move(_config)), + m_threadPool(std::move(_threadPool)), + m_taskCleaner(std::make_shared(PAUSE_THRESHOLD, "BsEcdhTaskCleaner")), + m_timeoutMinutes(_timeoutMinutes) + { + m_taskGuarder = std::make_shared(m_config); + } + + virtual ~BsEcdhPSIImpl() = default; + + BsEcdhResult::Ptr getTaskStatus(GetTaskStatusRequest::Ptr _request) override; + + virtual BsEcdhResult::Ptr updateTaskStatus(UpdateTaskStatusRequest::Ptr _request) override; + + virtual BsEcdhResult::Ptr killTask(KillTaskRequest::Ptr _request) override; + + void asyncRunTask(RunTaskRequest::Ptr _request, + std::function&& _onTaskFinished) override; + + BsEcdhResult::Ptr fetchCipher(FetchCipherRequest::Ptr _request) override; + + BsEcdhResult::Ptr sendEcdhCipher(SendEcdhCipherRequest::Ptr _request) override; + + BsEcdhResult::Ptr sendPartnerCipher(SendPartnerCipherRequest::Ptr _request) override; + + void start() override; + + void stop() override; + + // allow the output-path exists, for ut + void enableOutputExists() { m_enableOutputExists = true; } + +protected: + void checkAndCleanTask(); + std::pair checkTaskRequest(const std::string& _taskID); + void onSelfCiphersReady(const std::string& _taskID); + void onAllCiphersReady(const std::string& _taskID); + void onTaskFinished( + const std::string& _taskID, protocol::TaskStatus _status, BsEcdhResult::Ptr _result); + + void addTask(BsEcdhTaskState::Ptr _state, BsEcdhCache::Ptr _cache) + { + bcos::WriteGuard l(x_tasks); + m_taskStates[_state->taskID()] = std::move(_state); + m_taskCaches[_cache->taskID()] = std::move(_cache); + } + + BsEcdhCache::Ptr findTaskCache(const std::string& _taskID) + { + bcos::ReadGuard l(x_tasks); + auto cache = m_taskCaches.find(_taskID); + if (cache == m_taskCaches.end()) + { + return nullptr; + } + + return cache->second; + } + + BsEcdhTaskState::Ptr findTaskState(const std::string& _taskID) + { + bcos::ReadGuard l(x_tasks); + auto state = m_taskStates.find(_taskID); + if (state == m_taskStates.end()) + { + return nullptr; + } + + return state->second; + } + + uint32_t taskCount() + { + bcos::ReadGuard l(x_tasks); + uint32_t count = 0; + for (auto& state : m_taskStates) + { + if (state.second->status() != protocol::TaskStatus::COMPLETED && + state.second->status() != protocol::TaskStatus::FAILED) + { + count++; + } + } + return count; + } + + BsEcdhResult::Ptr prepareResultWithoutLock( + const std::string& _taskID, const std::string& _status) + { + GetTaskStatusResponse response; + response.taskID = _taskID; + response.status = _status; + + auto cache = m_taskCaches.find(_taskID); + if (cache != m_taskCaches.end()) + { + response.step = cache->second->step(); + response.index = cache->second->index(); + response.progress = cache->second->progress(); + } + return std::make_shared(_taskID, response.serialize()); + } + +private: + bool m_enableOutputExists = false; + + PSIConfig::Ptr m_config; + bcos::ThreadPool::Ptr m_threadPool; + std::shared_ptr m_taskCleaner; + uint32_t m_timeoutMinutes; + TaskGuarder::Ptr m_taskGuarder; + + std::unordered_map m_taskCaches; + std::unordered_map m_taskStates; + mutable bcos::SharedMutex x_tasks; + + std::atomic m_started{false}; +}; + +} // namespace ppc::psi \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-psi/src/bs-ecdh-psi/BsEcdhPSIInterface.h b/cpp/wedpr-computing/ppc-psi/src/bs-ecdh-psi/BsEcdhPSIInterface.h new file mode 100644 index 00000000..6a3534fb --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/bs-ecdh-psi/BsEcdhPSIInterface.h @@ -0,0 +1,58 @@ +/** + * 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 BSECDHPSIInterface.h + * @author: shawnhe + * @date 2023-09-20 + */ +#pragma once +#include "ppc-framework/protocol/Protocol.h" +#include "ppc-framework/protocol/Task.h" +#include "ppc-psi/src/bs-ecdh-psi/protocol/BsEcdhResult.h" +#include "ppc-psi/src/bs-ecdh-psi/protocol/Message.h" +#include +#include + +namespace ppc::psi +{ +class BsEcdhPSIInterface +{ +public: + using Ptr = std::shared_ptr; + + BsEcdhPSIInterface() = default; + + virtual ~BsEcdhPSIInterface() = default; + + virtual BsEcdhResult::Ptr getTaskStatus(GetTaskStatusRequest::Ptr _request) = 0; + + virtual BsEcdhResult::Ptr updateTaskStatus(UpdateTaskStatusRequest::Ptr _request) = 0; + + virtual BsEcdhResult::Ptr killTask(KillTaskRequest::Ptr _request) = 0; + + virtual void asyncRunTask(RunTaskRequest::Ptr _request, + std::function&& _onTaskFinished) = 0; + + virtual BsEcdhResult::Ptr fetchCipher(FetchCipherRequest::Ptr _request) = 0; + + virtual BsEcdhResult::Ptr sendEcdhCipher(SendEcdhCipherRequest::Ptr _request) = 0; + + virtual BsEcdhResult::Ptr sendPartnerCipher(SendPartnerCipherRequest::Ptr _request) = 0; + + virtual void start() = 0; + + virtual void stop() = 0; +}; +} // namespace ppc::psi \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-psi/src/bs-ecdh-psi/CMakeLists.txt b/cpp/wedpr-computing/ppc-psi/src/bs-ecdh-psi/CMakeLists.txt new file mode 100644 index 00000000..25163dcd --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/bs-ecdh-psi/CMakeLists.txt @@ -0,0 +1,4 @@ +file(GLOB_RECURSE SRCS *.cpp) +add_library(${BS_ECDH_PSI_TARGET} ${SRCS}) + +target_link_libraries(${BS_ECDH_PSI_TARGET} PUBLIC ${PSI_FRAMEWORK_TARGET} wedpr_ecc TBB::tbb) diff --git a/cpp/wedpr-computing/ppc-psi/src/bs-ecdh-psi/Common.h b/cpp/wedpr-computing/ppc-psi/src/bs-ecdh-psi/Common.h new file mode 100644 index 00000000..3e241b5b --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/bs-ecdh-psi/Common.h @@ -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 Common.h + * @author: shawnhe + * @date 2023-09-22 + */ + +#pragma once + +#include "ppc-framework/Common.h" +#include "ppc-framework/protocol/PPCMessageFace.h" + +#include +#include + + +namespace ppc::psi +{ +DERIVE_PPC_EXCEPTION(BsEcdhException); + +#define BS_ECDH_PSI_LOG(LEVEL) BCOS_LOG(LEVEL) << LOG_BADGE("PSI: BS-ECDH-PSI") +#define INDEX_FILE_SUFFIX ".index" +#define AUDIT_FILE_SUFFIX ".evidence" +#define MAX_TASK_COUNT 32 +#define PAUSE_THRESHOLD 60000 + +} // namespace ppc::psi diff --git a/cpp/wedpr-computing/ppc-psi/src/bs-ecdh-psi/core/BsEcdhCache.cpp b/cpp/wedpr-computing/ppc-psi/src/bs-ecdh-psi/core/BsEcdhCache.cpp new file mode 100644 index 00000000..6b89ed32 --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/bs-ecdh-psi/core/BsEcdhCache.cpp @@ -0,0 +1,555 @@ +/** + * 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 BsEcdhCache.cpp + * @author: shawnhe + * @date 2023-09-20 + */ + +#include "BsEcdhCache.h" + +using namespace bcos; +using namespace ppc::psi; +using namespace ppc::io; +using namespace ppc::protocol; + +void BsEcdhCache::start() +{ + m_threadPool->enqueue([self = weak_from_this()]() { + auto cache = self.lock(); + if (!cache) + { + return; + } + cache->prepareCipher(); + }); +} + +void BsEcdhCache::generateKey() +{ + m_key.resize(SCALAR_SIZE + 1); + COutputBuffer outputBuffer{(char*)m_key.data(), SCALAR_SIZE}; + auto ret = wedpr_random_scalar(&outputBuffer); + if (ret != WEDPR_SUCCESS) + { + BOOST_THROW_EXCEPTION(BCOS_ERROR( + (int64_t)PSIRetCode::OnException, "Generate key error, code: " + std::to_string(ret))); + } + m_key.resize(outputBuffer.len); +} + +std::string BsEcdhCache::genCipherWithBase64(const std::string& _input) +{ + std::string hash(POINT_SIZE + 1, 0); + CInputBuffer message{(char*)_input.data(), _input.size()}; + COutputBuffer point{(char*)hash.data(), POINT_SIZE}; + auto ret = wedpr_hash_to_curve(&message, &point); + if (ret != WEDPR_SUCCESS) + { + BOOST_THROW_EXCEPTION(BCOS_ERROR( + (int64_t)PSIRetCode::OnException, "Hash to curve error, code: " + std::to_string(ret))); + } + + CInputBuffer key{(char*)m_key.data(), m_key.size()}; + std::string cipher(POINT_SIZE + 1, 0); + CInputBuffer hashPoint{(char*)point.data, point.len}; + COutputBuffer cipherPoint{(char*)cipher.data(), cipher.size()}; + ret = wedpr_point_scalar_multi(&hashPoint, &key, &cipherPoint); + if (ret != WEDPR_SUCCESS) + { + BOOST_THROW_EXCEPTION(BCOS_ERROR((int64_t)PSIRetCode::OnException, + "Point multiply by scalar, code: " + std::to_string(ret))); + } + return base64Encode(bytesConstRef((byte*)cipherPoint.data, cipherPoint.len)); +} + +std::string BsEcdhCache::genEcdhCipherWithBase64(const std::string& _point) +{ + auto point = base64Decode(_point); + CInputBuffer rawPoint{(char*)point.data(), point.size()}; + CInputBuffer key{(char*)m_key.data(), m_key.size()}; + std::string ecdhCipher(POINT_SIZE + 1, 0); + COutputBuffer ecdhCipherPoint{(char*)ecdhCipher.data(), ecdhCipher.size()}; + auto ret = wedpr_point_scalar_multi(&rawPoint, &key, &ecdhCipherPoint); + if (ret != WEDPR_SUCCESS) + { + BOOST_THROW_EXCEPTION(BCOS_ERROR((int64_t)PSIRetCode::OnException, + "Point multiply by scalar, code: " + std::to_string(ret))); + } + return base64Encode(bytesConstRef((byte*)ecdhCipherPoint.data, ecdhCipherPoint.len)); +} + +void BsEcdhCache::prepareIoHandler() +{ + BS_ECDH_PSI_LOG(INFO) << LOG_DESC("start preparing io handler") << LOG_KV("taskID", m_taskID); + + auto reader = m_taskGuarder->loadReader(m_taskID, m_dataResource, DataSchema::String); + + auto resultWriter = m_taskGuarder->loadWriter(m_taskID, m_dataResource, m_enableOutputExists); + + auto outputPath = m_dataResource->outputDesc()->path(); + auto indexPath = outputPath + INDEX_FILE_SUFFIX; + m_dataResource->mutableOutputDesc()->setPath(indexPath); + auto indexWriter = m_taskGuarder->loadWriter(m_taskID, m_dataResource, m_enableOutputExists); + + LineWriter::Ptr evidenceWriter = nullptr; + if (m_enableAudit) + { + auto evidencePath = outputPath + AUDIT_FILE_SUFFIX; + m_dataResource->mutableOutputDesc()->setPath(evidencePath); + evidenceWriter = m_taskGuarder->loadWriter(m_taskID, m_dataResource, m_enableOutputExists); + } + + m_ioHandler = std::make_shared( + m_taskID, reader, resultWriter, indexWriter, evidenceWriter); + + BS_ECDH_PSI_LOG(INFO) << LOG_DESC("finish preparing io handler") << LOG_KV("taskID", m_taskID); +} + +void BsEcdhCache::prepareCipher() +{ + try + { + BS_ECDH_PSI_LOG(INFO) << LOG_DESC("start preparing cipher") << LOG_KV("taskID", m_taskID); + + prepareIoHandler(); + + // generate ecc sk + generateKey(); + // write key into evidence file + m_ioHandler->appendEvidence( + "WB KEY", base64Encode(bytesConstRef(m_key.data(), m_key.size()))); + + m_originInputs = m_ioHandler->loadInputs(); + if (!m_originInputs || m_originInputs->size() == 0) + { + BOOST_THROW_EXCEPTION(BCOS_ERROR((int64_t)PSIRetCode::OnException, "Data is empty.")); + } + m_inputsSize = m_originInputs->size(); + m_ciphers.reserve(m_inputsSize); + m_ciphers.resize(m_inputsSize); + m_ecdhCiphers.reserve(m_inputsSize); + m_ecdhCiphers.resize(m_inputsSize); + m_ecdhCiphersMap.reserve(m_inputsSize); + m_ecdhCipherFlags.assign(m_inputsSize, false); + + tbb::parallel_for(tbb::blocked_range(0U, m_inputsSize), [&](auto const& range) { + for (auto i = range.begin(); i < range.end(); i++) + { + m_ciphers[i] = std::move(genCipherWithBase64(m_originInputs->get(i))); + } + }); + + // write ciphers into evidence file + m_ioHandler->appendEvidences("WB CIPHERS", m_ciphers); + + if (m_onSelfCiphersReady) + { + m_step = ProcessingSelfCiphers; + m_onSelfCiphersReady(); + } + + BS_ECDH_PSI_LOG(INFO) << LOG_DESC("finish preparing cipher") << LOG_KV("taskID", m_taskID); + } + catch (const std::exception& e) + { + onSelfException("prepareCipher", e); + } +} + +uint32_t BsEcdhCache::findCurrentIndex( + const std::vector& _flags, uint32_t _offset, uint32_t _total) +{ + uint32_t final = _offset; + do + { + final++; + } while (_flags[final] && (final < _total)); + + return final; +} + +BsEcdhResult::Ptr BsEcdhCache::fetchCipher(FetchCipherRequest::Ptr _request) +{ + try + { + ReadGuard l(x_ecdhCiphers); + if (m_selfEcdhCiphersReady) + { + BOOST_THROW_EXCEPTION( + BCOS_ERROR((int64_t)PSIRetCode::OnException, "WB ciphers hava been processed.")); + } + + auto response = std::make_shared(); + response->taskID = m_taskID; + response->offset = _request->offset; + response->total = m_inputsSize; + response->ciphers.clear(); + + uint32_t end = _request->offset + _request->size >= m_inputsSize ? + m_inputsSize : + _request->offset + _request->size; + for (uint32_t i = _request->offset; i < end; i++) + { + response->ciphers.push_back(m_ciphers[i]); + } + response->size = response->ciphers.size(); + + return std::make_shared(m_taskID, response->serialize()); + } + catch (const std::exception& e) + { + return onRequestException("fetchCipher", e); + } +} + +BsEcdhResult::Ptr BsEcdhCache::onEcdhCipherReceived(SendEcdhCipherRequest::Ptr _request) +{ + try + { + WriteGuard l(x_ecdhCiphers); + if (m_selfEcdhCiphersReady) + { + return std::make_shared(m_taskID); + } + + // save ecdh ciphers + uint32_t end = _request->offset + _request->ecdhCiphers.size() >= m_inputsSize ? + m_inputsSize : + _request->offset + _request->ecdhCiphers.size(); + for (uint32_t i = _request->offset; i < end; i++) + { + if (!m_ecdhCipherFlags[i]) + { + m_ecdhCipherFlags[i] = true; + m_receivedEcdhCipherCount++; + } + m_ecdhCiphers[i] = _request->ecdhCiphers[i - _request->offset]; + } + auto total = + m_inputsSize + m_partnerInputsSize == 0 ? 1 : m_inputsSize + m_partnerInputsSize; + uint64_t currentCount = m_receivedPartnerCipherCount + m_receivedEcdhCipherCount; + m_progress = currentCount * 100 / total; + if (m_progress % 10 == 0) + { + BS_ECDH_PSI_LOG(INFO) << LOG_DESC("onEcdhCipherReceived") + << LOG_KV("totalReceived", currentCount) + << LOG_KV("progress", m_progress) << LOG_KV("taskID", m_taskID); + } + + if (_request->offset == m_selfIndex) + { + m_selfIndex = findCurrentIndex(m_ecdhCipherFlags, _request->offset, m_inputsSize); + } + + if (m_receivedEcdhCipherCount == m_inputsSize) + { + m_step = ProcessingPartnerCiphers; + m_selfEcdhCiphersReady.exchange(true); + m_threadPool->enqueue([self = weak_from_this()]() { + auto cache = self.lock(); + if (!cache) + { + return; + } + cache->onAllSelfEcdhCiphersReady(); + }); + } + + return std::make_shared(m_taskID); + } + catch (const std::exception& e) + { + return onRequestException("onEcdhCipherReceived", e); + } +} + +BsEcdhResult::Ptr BsEcdhCache::onPartnerCipherReceived(SendPartnerCipherRequest::Ptr _request) +{ + try + { + WriteGuard l(x_partnerCiphers); + if (m_partnerEcdhCiphersReady) + { + return std::make_shared(m_taskID); + } + + if (m_partnerCiphers.empty()) + { + if (m_partnerInputsSize == 0) + { + // compatible with older versions + m_partnerInputsSize = _request->total; + } + m_partnerCiphers.reserve(m_partnerInputsSize); + m_partnerCiphers.resize(m_partnerInputsSize); + m_partnerEcdhCiphers.reserve(m_partnerInputsSize); + m_partnerEcdhCiphers.resize(m_partnerInputsSize); + m_partnerCipherFlags.assign(m_partnerInputsSize, false); + } + + // save partner ciphers + uint32_t end = _request->offset + _request->partnerCiphers.size() >= m_partnerInputsSize ? + m_partnerInputsSize : + _request->offset + _request->partnerCiphers.size(); + for (uint32_t i = _request->offset; i < end; i++) + { + if (!m_partnerCipherFlags[i]) + { + m_partnerCipherFlags[i] = true; + m_receivedPartnerCipherCount++; + } + + m_partnerCiphers[i] = _request->partnerCiphers[i - _request->offset]; + } + + auto total = + m_inputsSize + m_partnerInputsSize == 0 ? 1 : m_inputsSize + m_partnerInputsSize; + uint64_t currentCount = m_receivedPartnerCipherCount + m_receivedEcdhCipherCount; + m_progress = currentCount * 100 / total; + if (m_progress % 10 == 0) + { + BS_ECDH_PSI_LOG(INFO) << LOG_DESC("onPartnerCipherReceived") + << LOG_KV("totalReceived", currentCount) + << LOG_KV("progress", m_progress) << LOG_KV("taskID", m_taskID); + } + + bool error = false; + // compute partner ecdh ciphers + tbb::parallel_for( + tbb::blocked_range(0U, end - _request->offset), [&](auto const& range) { + for (auto i = range.begin(); i < range.end(); i++) + { + auto index = _request->offset + i; + try + { + m_partnerEcdhCiphers[index] = + std::move(genEcdhCipherWithBase64(_request->partnerCiphers[i])); + } + catch (const std::exception& e) + { + error = true; + BS_ECDH_PSI_LOG(WARNING) + << LOG_DESC("genEcdhCipherWithBase64") + << LOG_KV("cipher", _request->partnerCiphers[i]) + << LOG_KV("exception", boost::diagnostic_information(e)); + } + } + }); + + if (error) + { + BOOST_THROW_EXCEPTION( + BCOS_ERROR((int64_t)PSIRetCode::OnException, "Compute partner ecdh ciphers error")); + } + + if (_request->offset == m_partnerIndex) + { + m_partnerIndex = + findCurrentIndex(m_partnerCipherFlags, _request->offset, m_partnerInputsSize); + } + + if (m_receivedPartnerCipherCount == m_partnerInputsSize) + { + m_partnerEcdhCiphersReady.exchange(true); + m_threadPool->enqueue([self = weak_from_this()]() { + auto cache = self.lock(); + if (!cache) + { + return; + } + cache->onAllPartnerEcdhCiphersReady(); + }); + } + + return std::make_shared(m_taskID); + } + catch (const std::exception& e) + { + return onRequestException("onPartnerCipherReceived", e); + } +} + +void BsEcdhCache::onAllSelfEcdhCiphersReady() +{ + BS_ECDH_PSI_LOG(INFO) << LOG_DESC("onAllSelfEcdhCiphersReady") << LOG_KV("taskID", m_taskID); + + for (uint32_t i = 0; i < m_inputsSize; i++) + { + m_ecdhCiphersMap[m_ecdhCiphers[i]] = i; + } + + // write ecdh ciphers into evidence file + m_ioHandler->appendEvidences("WB ECDH CIPHERS", m_ecdhCiphers); + + // release memory + std::vector().swap(m_ciphers); + std::vector().swap(m_ecdhCiphers); + std::vector().swap(m_ecdhCipherFlags); + MallocExtension::instance()->ReleaseFreeMemory(); + + if (m_partnerEcdhCiphersReady) + { + onAllEcdhCiphersReady(); + } +} + +void BsEcdhCache::onAllPartnerEcdhCiphersReady() +{ + BS_ECDH_PSI_LOG(INFO) << LOG_DESC("onAllPartnerEcdhCiphersReady") << LOG_KV("taskID", m_taskID); + + if (m_selfEcdhCiphersReady) + { + onAllEcdhCiphersReady(); + } +} + +void BsEcdhCache::onAllEcdhCiphersReady() +{ + if (m_allCiphersReady.exchange(true)) + { + return; + } + + BS_ECDH_PSI_LOG(INFO) << LOG_DESC("onAllCiphersReady") << LOG_KV("taskID", m_taskID); + if (m_onAllCiphersReady) + { + m_onAllCiphersReady(); + } + + m_step = ComputingResults; + + try + { + // write partner ciphers into evidence file at the end + m_ioHandler->appendEvidences("PARTNER CIPHERS", m_partnerCiphers); + + // release memory + std::vector().swap(m_partnerCiphers); + std::vector().swap(m_partnerCipherFlags); + MallocExtension::instance()->ReleaseFreeMemory(); + + m_ioHandler->uploadEvidences(); + + // find intersections + DataBatch::Ptr partnerIndexes = std::make_shared(); + std::unordered_set intersections; + uint32_t dumpSize = 0; + for (uint32_t i = 0; i < m_partnerInputsSize; i++) + { + if (m_ecdhCiphersMap.contains(m_partnerEcdhCiphers[i])) + { + auto index = m_ecdhCiphersMap[m_partnerEcdhCiphers[i]]; + auto data = m_originInputs->get(index); + if (!intersections.contains(data)) + { + intersections.insert(data); + partnerIndexes->append(std::to_string(i)); + } + else + { + dumpSize++; + } + } + } + + // release memory + if (m_originInputs) + { + m_originInputs->setData(std::vector()); + } + std::unordered_map().swap(m_ecdhCiphersMap); + std::vector().swap(m_partnerEcdhCiphers); + MallocExtension::instance()->ReleaseFreeMemory(); + + auto resultCount = intersections.size(); + m_ioHandler->saveResults(intersections); + m_ioHandler->saveIndexes(partnerIndexes); + + std::unordered_set().swap(intersections); + partnerIndexes->setData(std::vector()); + MallocExtension::instance()->ReleaseFreeMemory(); + + BS_ECDH_PSI_LOG(INFO) << LOG_DESC( + "finish computing results and start constructing response") + << LOG_KV("taskID", m_taskID); + + // construct response + auto response = std::make_shared(); + response->taskID = m_taskID; + response->status = toString(TaskStatus::COMPLETED); + response->intersections = resultCount; + response->party0Size = m_inputsSize; + response->party1Size = m_partnerInputsSize; + auto timeCosts = std::to_string(utcSteadyTime() - m_startTime) + "ms"; + response->timeCost = timeCosts; + response->step = DownloadIndex; + response->progress = 100; + + auto result = std::make_shared(m_taskID, response->serialize()); + if (m_onTaskFinished) + { + m_onTaskFinished(TaskStatus::COMPLETED, result); + } + + BS_ECDH_PSI_LOG(INFO) << LOG_BADGE("BsEcdhPsiTaskDone") << LOG_KV("taskID", m_taskID) + << LOG_KV("inputsSize", m_inputsSize) + << LOG_KV("partnerInputsSize", m_partnerInputsSize) + << LOG_KV("resultCount", resultCount) << LOG_KV("dumpSize", dumpSize) + << LOG_KV("timeCost", timeCosts) + << LOG_KV("resultFileID", response->resultFileID) + << LOG_KV("resultFileMd5", response->resultFileMd5) + << LOG_KV("partnerIndexFileID", response->partnerIndexFileID) + << LOG_KV("partnerIndexFileMd5", response->partnerIndexFileMd5) + << LOG_KV("evidenceFileID", response->evidenceFileID) + << LOG_KV("evidenceFileMd5", response->evidenceFileMd5); + } + catch (const std::exception& e) + { + return onSelfException("onAllCiphersReady", e); + } +} + +void BsEcdhCache::onSelfException(const std::string& _module, const std::exception& e) +{ + BS_ECDH_PSI_LOG(ERROR) << LOG_DESC("onSelfException") << LOG_KV("taskID", m_taskID) + << LOG_KV("module", _module) + << LOG_KV("exception", boost::diagnostic_information(e)); + + GetTaskStatusResponse response; + response.taskID = m_taskID; + response.status = toString(TaskStatus::FAILED); + auto result = std::make_shared(m_taskID, response.serialize()); + result->setError(std::make_shared( + (int)PSIRetCode::OnException, "Task failed: " + boost::diagnostic_information(e))); + + if (m_onTaskFinished) + { + m_onTaskFinished(TaskStatus::FAILED, result); + } +} + +BsEcdhResult::Ptr BsEcdhCache::onRequestException( + const std::string& _module, const std::exception& e) +{ + BS_ECDH_PSI_LOG(WARNING) << LOG_DESC("onRequestException") << LOG_KV("taskID", m_taskID) + << LOG_KV("module", _module) + << LOG_KV("exception", boost::diagnostic_information(e)); + + auto result = std::make_shared(m_taskID); + result->setError(std::make_shared( + (int)PSIRetCode::OnException, "Task failed: " + boost::diagnostic_information(e))); + return result; +} diff --git a/cpp/wedpr-computing/ppc-psi/src/bs-ecdh-psi/core/BsEcdhCache.h b/cpp/wedpr-computing/ppc-psi/src/bs-ecdh-psi/core/BsEcdhCache.h new file mode 100644 index 00000000..035d3ba8 --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/bs-ecdh-psi/core/BsEcdhCache.h @@ -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 BsEcdhCache.h + * @author: shawnhe + * @date 2023-09-20 + */ + +#pragma once + +#include "BsEcdhIoHandler.h" +#include "ppc-psi/src/Common.h" +#include "ppc-psi/src/bs-ecdh-psi/Common.h" +#include "ppc-psi/src/bs-ecdh-psi/ffi/wedpr_ffi_edwards25519.h" +#include "ppc-psi/src/bs-ecdh-psi/protocol/BsEcdhResult.h" +#include "ppc-psi/src/bs-ecdh-psi/protocol/Message.h" +#include "ppc-psi/src/psi-framework/TaskGuarder.h" +#include +#include +#include +#include + +namespace ppc::psi +{ +enum TaskStep : int +{ + Initializing = 1, + ProcessingSelfCiphers, + ProcessingPartnerCiphers, + ComputingResults, + // execution in ppcs-adm + DownloadIndex, +}; + +class BsEcdhCache : public std::enable_shared_from_this +{ +public: + using Ptr = std::shared_ptr; + BsEcdhCache(std::string _taskID, bcos::ThreadPool::Ptr _threadPool, + TaskGuarder::Ptr _taskGuarder, protocol::DataResource::Ptr _dataResource, bool _enableAudit, + bool _enableOutputExists, std::function&& _onSelfCiphersReady, + std::function&& _onAllCiphersReady, + std::function&& _onTaskFinished, + uint32_t _partnerInputsSize) + : m_taskID(std::move(_taskID)), + m_threadPool(std::move(_threadPool)), + m_taskGuarder(std::move(_taskGuarder)), + m_dataResource(std::move(_dataResource)), + m_enableAudit(_enableAudit), + m_enableOutputExists(_enableOutputExists), + m_onSelfCiphersReady(std::move(_onSelfCiphersReady)), + m_onAllCiphersReady(std::move(_onAllCiphersReady)), + m_onTaskFinished(std::move(_onTaskFinished)), + m_partnerInputsSize(_partnerInputsSize) + { + m_startTime = bcos::utcSteadyTime(); + BS_ECDH_PSI_LOG(INFO) << LOG_DESC("create BsEcdhCache") + << LOG_KV("partnerInputsSize", m_partnerInputsSize) + << LOG_KV("taskID", m_taskID); + } + ~BsEcdhCache() + { + if (m_ioHandler) + { + m_ioHandler->clean(); + } + // release the memory to os + std::vector().swap(m_ciphers); + std::vector().swap(m_ecdhCiphers); + std::vector().swap(m_ecdhCipherFlags); + std::vector().swap(m_partnerCiphers); + std::vector().swap(m_partnerCipherFlags); + std::unordered_map().swap(m_ecdhCiphersMap); + std::vector().swap(m_partnerEcdhCiphers); + if (m_originInputs) + { + m_originInputs->setData(std::vector()); + } + MallocExtension::instance()->ReleaseFreeMemory(); + BS_ECDH_PSI_LOG(INFO) << LOG_DESC("the BsEcdhCache destroyed") + << LOG_KV("taskID", m_taskID); + } + + void start(); + + [[nodiscard]] std::string taskID() const { return m_taskID; } + + [[nodiscard]] uint32_t step() const { return m_step; } + + [[nodiscard]] uint32_t index() const + { + if (m_step == ProcessingSelfCiphers) + { + return m_selfIndex; + } + else if (m_step == ProcessingPartnerCiphers) + { + return m_partnerIndex; + } + else + { + return 0; + } + } + + [[nodiscard]] int progress() const { return m_progress; } + + BsEcdhResult::Ptr fetchCipher(FetchCipherRequest::Ptr _request); + + BsEcdhResult::Ptr onEcdhCipherReceived(SendEcdhCipherRequest::Ptr _request); + + BsEcdhResult::Ptr onPartnerCipherReceived(SendPartnerCipherRequest::Ptr _request); + +public: + // for unit test + bcos::bytes key() { return m_key; } + void setKey(const bcos::bytes& _key) { m_key.assign(_key.begin(), _key.end()); } + + void generateKey(); + std::string genCipherWithBase64(const std::string& _input); + std::string genEcdhCipherWithBase64(const std::string& _point); + +private: + void prepareIoHandler(); + void prepareCipher(); + static uint32_t findCurrentIndex( + const std::vector& _flags, uint32_t _offset, uint32_t _total); + void onAllSelfEcdhCiphersReady(); + void onAllPartnerEcdhCiphersReady(); + void onAllEcdhCiphersReady(); + void onSelfException(const std::string& _module, const std::exception& e); + BsEcdhResult::Ptr onRequestException(const std::string& _module, const std::exception& e); + +private: + std::string m_taskID; + bcos::ThreadPool::Ptr m_threadPool; + TaskGuarder::Ptr m_taskGuarder; + protocol::DataResource::Ptr m_dataResource; + bool m_enableAudit; + bool m_enableOutputExists; + BsEcdhIoHandler::Ptr m_ioHandler; + std::function m_onSelfCiphersReady; + std::function m_onAllCiphersReady; + std::function m_onTaskFinished; + + ppc::io::DataBatch::Ptr m_originInputs; + uint32_t m_inputsSize{0}; + uint32_t m_partnerInputsSize; + uint64_t m_startTime; + + bcos::bytes m_key; + std::vector m_ciphers; + + mutable bcos::SharedMutex x_ecdhCiphers; + std::vector m_ecdhCiphers; + std::unordered_map m_ecdhCiphersMap; + std::vector m_ecdhCipherFlags; + uint32_t m_receivedEcdhCipherCount{0}; + std::atomic m_selfEcdhCiphersReady{false}; + + mutable bcos::SharedMutex x_partnerCiphers; + std::vector m_partnerCiphers; + std::vector m_partnerCipherFlags; + uint32_t m_receivedPartnerCipherCount{0}; + + std::vector m_partnerEcdhCiphers; + std::atomic m_partnerEcdhCiphersReady{false}; + + std::atomic m_step{Initializing}; + std::atomic m_selfIndex{0}; + std::atomic m_partnerIndex{0}; + std::atomic m_progress{0}; + + std::atomic m_allCiphersReady{false}; +}; + +} // namespace ppc::psi diff --git a/cpp/wedpr-computing/ppc-psi/src/bs-ecdh-psi/core/BsEcdhIoHandler.h b/cpp/wedpr-computing/ppc-psi/src/bs-ecdh-psi/core/BsEcdhIoHandler.h new file mode 100644 index 00000000..07b198ea --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/bs-ecdh-psi/core/BsEcdhIoHandler.h @@ -0,0 +1,202 @@ +/** + * 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 BsEcdhIoHandler.h + * @author: shawnhe + * @date 2023-09-22 + */ + +#pragma once + +#include + +#include "ppc-framework/io/DataResourceLoader.h" +#include "ppc-framework/io/LineReader.h" +#include "ppc-psi/src/bs-ecdh-psi/Common.h" + +namespace ppc::psi +{ +class BsEcdhIoHandler +{ +public: + using Ptr = std::shared_ptr; + + BsEcdhIoHandler(std::string _taskID, ppc::io::LineReader::Ptr _reader, + ppc::io::LineWriter::Ptr _resultWriter, ppc::io::LineWriter::Ptr _indexWriter, + ppc::io::LineWriter::Ptr _evidenceWriter) + : m_taskID(std::move(_taskID)), + m_reader(std::move(_reader)), + m_resultWriter(std::move(_resultWriter)), + m_indexWriter(std::move(_indexWriter)), + m_evidenceWriter(std::move(_evidenceWriter)) + {} + + virtual ~BsEcdhIoHandler() = default; + + [[nodiscard]] std::string taskID() const { return m_taskID; } + + [[nodiscard]] ppc::io::LineReader::Ptr reader() const { return m_reader; } + + [[nodiscard]] ppc::io::LineWriter::Ptr resultWriter() const { return m_resultWriter; } + + [[nodiscard]] ppc::io::LineWriter::Ptr indexWriter() const { return m_indexWriter; } + + [[nodiscard]] ppc::io::LineWriter::Ptr evidenceWriter() const { return m_evidenceWriter; } + + io::DataBatch::Ptr loadInputs() + { + BS_ECDH_PSI_LOG(INFO) << LOG_DESC("start loading inputs") << LOG_KV("taskID", m_taskID); + int64_t nextParam = m_reader->type() == protocol::DataResourceType::MySQL ? 0 : -1; + auto data = m_reader->next(nextParam, io::DataSchema::String); + BS_ECDH_PSI_LOG(INFO) << LOG_DESC("finish loading inputs") << LOG_KV("taskID", m_taskID) + << LOG_KV("inputsSize", data->size()); + return data; + } + + protocol::FileInfo::Ptr saveResults(const std::unordered_set& _results) + { + BS_ECDH_PSI_LOG(INFO) << LOG_DESC("start saving results") << LOG_KV("taskID", m_taskID) + << LOG_KV("resultsSize", _results.size()); + writeByDataBatch(m_resultWriter, _results); + m_resultWriter->flush(); + m_resultWriter->close(); + // upload + m_resultWriter->upload(); + m_resultWriter->clean(); + BS_ECDH_PSI_LOG(INFO) << LOG_DESC("finish saving results") << LOG_KV("taskID", m_taskID) + << LOG_KV("resultsSize", _results.size()); + return m_resultWriter->fileInfo(); + } + + protocol::FileInfo::Ptr saveIndexes(const io::DataBatch::Ptr& _indexes) + { + BS_ECDH_PSI_LOG(INFO) << LOG_DESC("start saving indexes") << LOG_KV("taskID", m_taskID) + << LOG_KV("indexesSize", _indexes->size()); + m_indexWriter->writeLine(_indexes, io::DataSchema::String, "\n"); + + m_indexWriter->flush(); + m_indexWriter->close(); + // upload + m_indexWriter->upload(); + m_indexWriter->clean(); + BS_ECDH_PSI_LOG(INFO) << LOG_DESC("finish saving indexes") << LOG_KV("taskID", m_taskID) + << LOG_KV("indexesSize", _indexes->size()); + return m_indexWriter->fileInfo(); + } + + void appendEvidence(const std::string& _tag, const std::string& _evidence) + { + BS_ECDH_PSI_LOG(INFO) << LOG_DESC("append evidence") << LOG_KV("taskID", m_taskID) + << LOG_KV("tag", _tag); + if (!m_evidenceWriter) + { + return; + } + io::DataBatch::Ptr dataBatch = std::make_shared(); + dataBatch->append(_tag); + dataBatch->append(_evidence); + m_evidenceWriter->writeLine(dataBatch, io::DataSchema::String, "\n"); + m_evidenceWriter->flush(); + } + + void appendEvidences(const std::string& _tag, const std::vector& _evidences) + { + BS_ECDH_PSI_LOG(INFO) << LOG_DESC("start appending evidences") << LOG_KV("taskID", m_taskID) + << LOG_KV("tag", _tag) << LOG_KV("evidencesSize", _evidences.size()); + if (!m_evidenceWriter) + { + return; + } + io::DataBatch::Ptr dataBatch = std::make_shared(); + dataBatch->append(_tag); + m_evidenceWriter->writeLine(dataBatch, io::DataSchema::String, "\n"); + m_evidenceWriter->flush(); + writeByDataBatch(m_evidenceWriter, _evidences); + BS_ECDH_PSI_LOG(INFO) << LOG_DESC("finish appending evidences") + << LOG_KV("taskID", m_taskID) << LOG_KV("tag", _tag) + << LOG_KV("evidencesSize", _evidences.size()); + } + + protocol::FileInfo::Ptr uploadEvidences() + { + BS_ECDH_PSI_LOG(INFO) << LOG_DESC("start uploading evidences") + << LOG_KV("taskID", m_taskID); + if (!m_evidenceWriter) + { + return nullptr; + } + m_evidenceWriter->flush(); + m_evidenceWriter->close(); + // upload + m_evidenceWriter->upload(); + m_evidenceWriter->clean(); + return m_evidenceWriter->fileInfo(); + BS_ECDH_PSI_LOG(INFO) << LOG_DESC("finish uploading evidences") + << LOG_KV("taskID", m_taskID); + } + + void clean() + { + if (m_reader) + { + m_reader->clean(); + } + if (m_resultWriter) + { + m_resultWriter->clean(); + } + if (m_indexWriter) + { + m_indexWriter->clean(); + } + if (m_evidenceWriter) + { + m_evidenceWriter->clean(); + } + } + + template + static void writeByDataBatch(const ppc::io::LineWriter::Ptr& _writer, const Container& _data) + { + io::DataBatch::Ptr dataBatch = std::make_shared(); + uint32_t count = 0; + for (const auto& line : _data) + { + dataBatch->append(line); + count++; + if (count == 1000000) + { + _writer->writeLine(dataBatch, io::DataSchema::String, "\n"); + _writer->flush(); + dataBatch = std::make_shared(); + count = 0; + } + } + if (count > 0) + { + _writer->writeLine(dataBatch, io::DataSchema::String, "\n"); + _writer->flush(); + } + } + +private: + std::string m_taskID; + ppc::io::LineReader::Ptr m_reader; + ppc::io::LineWriter::Ptr m_resultWriter; + ppc::io::LineWriter::Ptr m_indexWriter; + ppc::io::LineWriter::Ptr m_evidenceWriter; +}; + +} // namespace ppc::psi diff --git a/cpp/wedpr-computing/ppc-psi/src/bs-ecdh-psi/core/BsEcdhTaskState.h b/cpp/wedpr-computing/ppc-psi/src/bs-ecdh-psi/core/BsEcdhTaskState.h new file mode 100644 index 00000000..b69f235a --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/bs-ecdh-psi/core/BsEcdhTaskState.h @@ -0,0 +1,184 @@ +/** + * 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 BsEcdhTaskState.h + * @author: shawnhe + * @date 2023-09-22 + */ + +#pragma once + +#include "ppc-framework/io/DataResourceLoader.h" +#include "ppc-framework/io/LineReader.h" +#include "ppc-framework/protocol/Protocol.h" +#include "ppc-psi/src/bs-ecdh-psi/Common.h" +#include "ppc-psi/src/bs-ecdh-psi/protocol/BsEcdhResult.h" +#include "ppc-psi/src/psi-framework/TaskGuarder.h" +#include +#include +#include + +namespace ppc::psi +{ +#define BS_VALIDITY_TERM 86400000 +#define MIN_BS_ACTIVE_COUNT 3 + +class BsEcdhTaskState +{ +public: + using Ptr = std::shared_ptr; + + BsEcdhTaskState(std::string _taskID, protocol::TaskStatus _status, uint32_t _timeoutMinutes) + : m_taskID(std::move(_taskID)), m_status(_status), m_timeoutMinutes(_timeoutMinutes) + { + m_latestActiveTime = bcos::utcSteadyTime(); + BS_ECDH_PSI_LOG(INFO) << LOG_DESC("new BsEcdhTaskState") << LOG_KV("taskID", m_taskID) + << LOG_KV("createTime", m_latestActiveTime) + << LOG_KV("timeoutMinutes", m_timeoutMinutes); + } + + virtual ~BsEcdhTaskState() = default; + + [[nodiscard]] std::string taskID() const { return m_taskID; } + + [[nodiscard]] protocol::TaskStatus status() const + { + bcos::ReadGuard l(x_state); + return m_status; + } + void updateStatus(protocol::TaskStatus _status) + { + bcos::WriteGuard l(x_state); + m_status = _status; + } + + [[nodiscard]] BsEcdhResult::Ptr result() const + { + bcos::ReadGuard l(x_state); + return m_result; + } + void setResult(BsEcdhResult::Ptr _result) + { + bcos::WriteGuard l(x_state); + m_result = std::move(_result); + } + + void autoPauseChecking() + { + bcos::WriteGuard l(x_state); + // trigger automatic pause + if (m_status == protocol::TaskStatus::RUNNING && + m_latestActiveTime + m_autoPauseThreshold <= bcos::utcSteadyTime()) + { + turnToPausing(); + BS_ECDH_PSI_LOG(INFO) << LOG_DESC("task is pausing") << LOG_KV("taskID", m_taskID); + } + } + + [[nodiscard]] bool isTimeout() + { + bcos::WriteGuard l(x_state); + auto timeout = + isExecutable(m_status) && + m_latestActiveTime + uint64_t(m_timeoutMinutes * 60 * 1000) <= bcos::utcSteadyTime(); + if (timeout) + { + BS_ECDH_PSI_LOG(WARNING) << LOG_DESC("task is timeout") << LOG_KV("taskID", m_taskID); + GetTaskStatusResponse response; + response.taskID = m_taskID; + response.status = toString(protocol::TaskStatus::FAILED); + m_result = std::make_shared(m_taskID, response.serialize()); + m_result->setError( + std::make_shared((int)PSIRetCode::TaskTimeout, "Task is timeout.")); + m_status = protocol::TaskStatus::FAILED; + } + return timeout; + } + + [[nodiscard]] bool isExpired() const + { + bcos::ReadGuard l(x_state); + return m_latestActiveTime + BS_VALIDITY_TERM <= bcos::utcSteadyTime(); + } + + void active() + { + bcos::WriteGuard l(x_state); + + // The task is activated + if (m_status == protocol::TaskStatus::PAUSING && ++activeCount == MIN_BS_ACTIVE_COUNT) + { + activeCount = 0; + turnToRunning(); + } + + m_latestActiveTime = bcos::utcSteadyTime(); + } + + void setupAutoPause() + { + bcos::WriteGuard l(x_state); + turnToRunning(); + } + + void cancelAutoPause() + { + bcos::WriteGuard l(x_state); + m_autoPauseThreshold = BS_VALIDITY_TERM; + } + + void pauseTask() + { + bcos::WriteGuard l(x_state); + if (m_status == protocol::TaskStatus::RUNNING) + { + turnToPausing(); + } + } + + void restartTask() + { + bcos::WriteGuard l(x_state); + if (m_status == protocol::TaskStatus::PAUSING) + { + turnToRunning(); + } + } + +private: + void turnToRunning() + { + m_status = protocol::TaskStatus::RUNNING; + m_autoPauseThreshold = PAUSE_THRESHOLD; + m_latestActiveTime = bcos::utcSteadyTime(); + } + + void turnToPausing() + { + m_status = protocol::TaskStatus::PAUSING; + m_autoPauseThreshold = BS_VALIDITY_TERM; + } + +private: + mutable bcos::SharedMutex x_state; + std::string m_taskID; + protocol::TaskStatus m_status; + BsEcdhResult::Ptr m_result; + std::atomic m_latestActiveTime; + uint64_t m_timeoutMinutes; + uint64_t m_autoPauseThreshold{BS_VALIDITY_TERM}; + uint64_t activeCount{0}; +}; +} // namespace ppc::psi diff --git a/cpp/wedpr-computing/ppc-psi/src/bs-ecdh-psi/ffi/wedpr_ffi_edwards25519.h b/cpp/wedpr-computing/ppc-psi/src/bs-ecdh-psi/ffi/wedpr_ffi_edwards25519.h new file mode 100644 index 00000000..5c689c40 --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/bs-ecdh-psi/ffi/wedpr_ffi_edwards25519.h @@ -0,0 +1,49 @@ +/** + * 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_ffi_edwards25519.h + * @author: shawnhe + * @date 2023-10-10 + */ + + +#ifndef _WEDPR_FFI_EDWARDS25519_H_ +#define _WEDPR_FFI_EDWARDS25519_H_ + +#include +#include +#include + +#include "wedpr_utilities.h" + +extern "C" { +/** + * C interface for 'generate random scalar'. + */ +int8_t wedpr_random_scalar(COutputBuffer* random); + +/** + * C interface for 'hash to curve'. + */ +int8_t wedpr_hash_to_curve(const CInputBuffer* message, COutputBuffer* point); + +/** + * C interface for 'point multiply by scalar'. + */ +int8_t wedpr_point_scalar_multi( + const CInputBuffer* raw_point, const CInputBuffer* scalar, COutputBuffer* point); +} + +#endif diff --git a/cpp/wedpr-computing/ppc-psi/src/bs-ecdh-psi/ffi/wedpr_utilities.h b/cpp/wedpr-computing/ppc-psi/src/bs-ecdh-psi/ffi/wedpr_utilities.h new file mode 100644 index 00000000..9fcf5da2 --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/bs-ecdh-psi/ffi/wedpr_utilities.h @@ -0,0 +1,51 @@ +/** + * 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_utilities.h + * @author: shawnhe + * @date 2023-10-10 + */ + +#ifndef _WEDPR_UTILITIES_H_ +#define _WEDPR_UTILITIES_H_ + +#include +#include +#include +#include +#include + +#define POINT_SIZE 32 +#define SCALAR_SIZE 32 + +extern "C" { + +struct CInputBuffer +{ + const char* data; + uintptr_t len; +}; + +struct COutputBuffer +{ + char* data; + uintptr_t len; +}; + +const int8_t WEDPR_ERROR = -1; +const int8_t WEDPR_SUCCESS = 0; +} // extern "C" + +#endif diff --git a/cpp/wedpr-computing/ppc-psi/src/bs-ecdh-psi/protocol/BsEcdhResult.h b/cpp/wedpr-computing/ppc-psi/src/bs-ecdh-psi/protocol/BsEcdhResult.h new file mode 100644 index 00000000..204a515a --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/bs-ecdh-psi/protocol/BsEcdhResult.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 BsModeResult.h + * @author: shawnhe + * @date 2023-09-21 + */ +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +#include "ppc-framework/protocol/Task.h" + +namespace ppc::psi +{ +class BsEcdhResult : public protocol::TaskResult +{ +public: + using Ptr = std::shared_ptr; + BsEcdhResult(std::string const& _taskID, Json::Value _data = Json::Value{}) + : TaskResult(_taskID), m_data(std::move(_data)) + {} + ~BsEcdhResult() override = default; + + [[nodiscard]] Json::Value const& data() const { return m_data; } + + // serialize the taskResult to json + [[nodiscard]] Json::Value serializeToJson() override + { + Json::Value response; + if (m_error && error()->errorCode()) + { + response["code"] = error()->errorCode(); + response["message"] = error()->errorMessage(); + } + else + { + response["code"] = 0; + response["message"] = "success"; + } + if (!m_data.empty()) + { + response["data"] = m_data; + } + return response; + } + +private: + Json::Value m_data; +}; + +} // namespace ppc::psi diff --git a/cpp/wedpr-computing/ppc-psi/src/bs-ecdh-psi/protocol/Message.h b/cpp/wedpr-computing/ppc-psi/src/bs-ecdh-psi/protocol/Message.h new file mode 100644 index 00000000..397c837e --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/bs-ecdh-psi/protocol/Message.h @@ -0,0 +1,408 @@ +/** + * 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: shawnhe + * @date 2023-09-21 + */ + +#pragma once + +#include "ppc-framework/protocol/Protocol.h" +#include "ppc-framework/rpc/RpcTypeDef.h" +#include "protocol/src/JsonTaskImpl.h" +#include +#include +#include +#include +#include + +namespace ppc::psi +{ +struct GetTaskStatusRequest +{ + using Ptr = std::shared_ptr; + std::string taskID; + + GetTaskStatusRequest() = default; + ~GetTaskStatusRequest() = default; + + explicit GetTaskStatusRequest(const Json::Value& _params) { deserialize(_params); } + + void deserialize(const Json::Value& _params) + { + if (!_params.isMember("taskID")) + { + BOOST_THROW_EXCEPTION( + BCOS_ERROR((int64_t)rpc::RpcError::InvalidRequest, "Must set the taskID field")); + } + taskID = _params["taskID"].asString(); + } +}; + +struct GetTaskStatusResponse +{ + using Ptr = std::shared_ptr; + std::string taskID; + std::string status; + uint32_t step = 0; + uint32_t index = 0; + uint progress = 0; + uint32_t intersections; + uint32_t party0Size; + uint32_t party1Size; + std::string timeCost; + std::string resultFileMd5; + std::string resultFileID; + std::string partnerIndexFileMd5; + std::string partnerIndexFileID; + std::string evidenceFileMd5; + std::string evidenceFileID; + + [[nodiscard]] Json::Value serialize() const + { + Json::Value root; + root["taskID"] = taskID; + root["status"] = status; + root["step"] = step; + root["index"] = index; + root["progress"] = progress; + if (status == protocol::toString(protocol::TaskStatus::COMPLETED)) + { + root["timeCost"] = timeCost; + root["intersections"] = intersections; + root["party0Size"] = party0Size; + root["party1Size"] = party1Size; + if (!resultFileID.empty()) + { + root["resultFileID"] = resultFileID; + root["resultFileMd5"] = resultFileMd5; + } + if (!partnerIndexFileID.empty()) + { + root["partnerIndexFileID"] = partnerIndexFileID; + root["partnerIndexFileMd5"] = partnerIndexFileMd5; + } + if (!evidenceFileID.empty()) + { + root["evidenceFileID"] = evidenceFileID; + root["evidenceFileMd5"] = evidenceFileMd5; + } + } + return root; + } +}; + +struct KillTaskRequest +{ + using Ptr = std::shared_ptr; + std::string taskID; + + KillTaskRequest() = default; + ~KillTaskRequest() = default; + + explicit KillTaskRequest(const Json::Value& _params) { deserialize(_params); } + + void deserialize(const Json::Value& _params) + { + if (!_params.isMember("taskID")) + { + BOOST_THROW_EXCEPTION( + BCOS_ERROR((int64_t)rpc::RpcError::InvalidRequest, "Must set the taskID field")); + } + taskID = _params["taskID"].asString(); + } +}; + +struct UpdateTaskStatusRequest +{ + using Ptr = std::shared_ptr; + std::string taskID; + std::string status; + + UpdateTaskStatusRequest() = default; + ~UpdateTaskStatusRequest() = default; + + explicit UpdateTaskStatusRequest(const Json::Value& _params) { deserialize(_params); } + + void deserialize(const Json::Value& _params) + { + if (!_params.isMember("taskID")) + { + BOOST_THROW_EXCEPTION( + BCOS_ERROR((int64_t)rpc::RpcError::InvalidRequest, "Must set the taskID field")); + } + taskID = _params["taskID"].asString(); + + if (!_params.isMember("status")) + { + BOOST_THROW_EXCEPTION( + BCOS_ERROR((int64_t)rpc::RpcError::InvalidRequest, "Must set the status field")); + } + status = _params["status"].asString(); + } +}; + +struct RunTaskRequest +{ + using Ptr = std::shared_ptr; + std::string taskID; + bool enableAudit{true}; + uint32_t partnerInputsSize{0}; + protocol::DataResource::Ptr dataResource; + + RunTaskRequest() = default; + ~RunTaskRequest() = default; + + explicit RunTaskRequest(const Json::Value& _params, const std::string& _prePath) + { + deserialize(_params, _prePath); + } + + void deserialize(const Json::Value& _params, const std::string& _prePath) + { + if (!_params.isMember("taskID")) + { + BOOST_THROW_EXCEPTION( + BCOS_ERROR((int64_t)rpc::RpcError::InvalidRequest, "Must set the taskID field")); + } + taskID = _params["taskID"].asString(); + + if (_params.isMember("enableAudit")) + { + enableAudit = _params["enableAudit"].asBool(); + } + else + { + enableAudit = true; + } + if (_params.isMember("partnerInputsSize")) + { + partnerInputsSize = _params["partnerInputsSize"].asUInt(); + } + if (!_params.isMember("data")) + { + BOOST_THROW_EXCEPTION( + BCOS_ERROR((int64_t)rpc::RpcError::InvalidRequest, "Must set the data field")); + } + auto jsonTask = std::make_shared("", _prePath); + dataResource = jsonTask->decodeDataResource(_params["data"]); + } + + [[nodiscard]] std::string toString() const + { + std::stringstream ss; + ss << "taskID: " << taskID << ", enableAudit: " << enableAudit << ", " + << protocol::printDataResourceInfo(dataResource) << "\n"; + return ss.str(); + } +}; + +struct FetchCipherRequest +{ + using Ptr = std::shared_ptr; + std::string taskID; + uint32_t offset; + uint32_t size; + + FetchCipherRequest() = default; + ~FetchCipherRequest() = default; + + explicit FetchCipherRequest(const Json::Value& _params) { deserialize(_params); } + + void deserialize(const Json::Value& _params) + { + if (!_params.isMember("taskID")) + { + BOOST_THROW_EXCEPTION( + BCOS_ERROR((int64_t)rpc::RpcError::InvalidRequest, "Must set the taskID field")); + } + taskID = _params["taskID"].asString(); + + if (!_params.isMember("offset")) + { + BOOST_THROW_EXCEPTION( + BCOS_ERROR((int64_t)rpc::RpcError::InvalidRequest, "Must set the offset field")); + } + offset = _params["offset"].asUInt(); + + if (!_params.isMember("size")) + { + BOOST_THROW_EXCEPTION( + BCOS_ERROR((int64_t)rpc::RpcError::InvalidRequest, "Must define the size field")); + } + size = _params["size"].asUInt(); + } +}; + +struct FetchCipherResponse +{ + using Ptr = std::shared_ptr; + std::string taskID; + uint32_t offset; + uint32_t size; + uint32_t total; + std::vector ciphers; + + [[nodiscard]] Json::Value serialize() const + { + Json::Value root; + root["taskID"] = taskID; + root["offset"] = offset; + root["size"] = size; + root["total"] = total; + + Json::Value cipherArray(Json::arrayValue); + for (const std::string& cipher : ciphers) + { + cipherArray.append(cipher); + } + root["ciphers"] = cipherArray; + + return root; + } +}; + +struct SendEcdhCipherRequest +{ + using Ptr = std::shared_ptr; + std::string taskID; + uint32_t offset; + uint32_t size; + std::vector ecdhCiphers; + + SendEcdhCipherRequest() = default; + ~SendEcdhCipherRequest() = default; + + explicit SendEcdhCipherRequest(const Json::Value& _params) { deserialize(_params); } + + void deserialize(const Json::Value& _params) + { + if (!_params.isMember("taskID")) + { + BOOST_THROW_EXCEPTION( + BCOS_ERROR((int64_t)rpc::RpcError::InvalidRequest, "Must set the taskID field")); + } + taskID = _params["taskID"].asString(); + + if (!_params.isMember("offset")) + { + BOOST_THROW_EXCEPTION( + BCOS_ERROR((int64_t)rpc::RpcError::InvalidRequest, "Must set the offset field")); + } + offset = _params["offset"].asUInt(); + + if (!_params.isMember("size")) + { + BOOST_THROW_EXCEPTION( + BCOS_ERROR((int64_t)rpc::RpcError::InvalidRequest, "Must define the size field")); + } + size = _params["size"].asUInt(); + + if (!_params.isMember("ecdhCiphers")) + { + BOOST_THROW_EXCEPTION(BCOS_ERROR( + (int64_t)rpc::RpcError::InvalidRequest, "Must set the ecdhCiphers field")); + } + + const Json::Value& ecdhCiphersJson = _params["ecdhCiphers"]; + if (!ecdhCiphersJson.isArray()) + { + BOOST_THROW_EXCEPTION( + BCOS_ERROR((int64_t)rpc::RpcError::InvalidRequest, "ecdhCiphers must be an array")); + } + + for (const Json::Value& cipher : ecdhCiphersJson) + { + if (!cipher.isString() || cipher.asString().empty()) + { + BOOST_THROW_EXCEPTION(BCOS_ERROR( + (int64_t)rpc::RpcError::InvalidRequest, "Invalid ecdhCipher format")); + } + ecdhCiphers.push_back(cipher.asString()); + } + } +}; + +struct SendPartnerCipherRequest +{ + using Ptr = std::shared_ptr; + std::string taskID; + uint32_t offset{}; + uint32_t size{}; + uint32_t total{}; + std::vector partnerCiphers; + + SendPartnerCipherRequest() = default; + ~SendPartnerCipherRequest() = default; + + explicit SendPartnerCipherRequest(const Json::Value& _params) { deserialize(_params); } + + void deserialize(const Json::Value& _params) + { + if (!_params.isMember("taskID")) + { + BOOST_THROW_EXCEPTION( + BCOS_ERROR((int64_t)rpc::RpcError::InvalidRequest, "Must set the taskID field")); + } + taskID = _params["taskID"].asString(); + + if (!_params.isMember("offset")) + { + BOOST_THROW_EXCEPTION( + BCOS_ERROR((int64_t)rpc::RpcError::InvalidRequest, "Must set the offset field")); + } + offset = _params["offset"].asUInt(); + + if (!_params.isMember("size")) + { + BOOST_THROW_EXCEPTION( + BCOS_ERROR((int64_t)rpc::RpcError::InvalidRequest, "Must define the size field")); + } + size = _params["size"].asUInt(); + + if (!_params.isMember("total")) + { + BOOST_THROW_EXCEPTION( + BCOS_ERROR((int64_t)rpc::RpcError::InvalidRequest, "Must define the total field")); + } + total = _params["total"].asUInt(); + + if (!_params.isMember("partnerCiphers")) + { + BOOST_THROW_EXCEPTION(BCOS_ERROR( + (int64_t)rpc::RpcError::InvalidRequest, "Must set the partnerCiphers field")); + } + + const Json::Value& partnerCiphersJson = _params["partnerCiphers"]; + if (!partnerCiphersJson.isArray()) + { + BOOST_THROW_EXCEPTION(BCOS_ERROR( + (int64_t)rpc::RpcError::InvalidRequest, "partnerCiphers must be an array")); + } + + for (const Json::Value& cipher : partnerCiphersJson) + { + if (!cipher.isString() || cipher.asString().empty()) + { + BOOST_THROW_EXCEPTION(BCOS_ERROR( + (int64_t)rpc::RpcError::InvalidRequest, "Invalid partnerCiphers format")); + } + partnerCiphers.push_back(cipher.asString()); + } + } +}; + +} // namespace ppc::psi \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-psi/src/cm2020-psi/CM2020PSIConfig.h b/cpp/wedpr-computing/ppc-psi/src/cm2020-psi/CM2020PSIConfig.h new file mode 100644 index 00000000..204dd5ab --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/cm2020-psi/CM2020PSIConfig.h @@ -0,0 +1,68 @@ +/** + * Copyright (C) 2022 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 CM2020PSIConfig.h + * @author: shawnhe + * @date 2022-12-7 + */ + +#pragma once +#include + +#include + +#include "Common.h" +#include "ppc-crypto/src/oprf/EcdhOprf.h" +#include "ppc-framework/crypto/CryptoBox.h" +#include "ppc-framework/crypto/Oprf.h" +#include "ppc-framework/protocol/Protocol.h" +#include "ppc-psi/src/PSIConfig.h" +#include "protocol/src/PPCMessage.h" + +namespace ppc::psi +{ +class CM2020PSIConfig : public PSIConfig +{ +public: + using Ptr = std::shared_ptr; + + CM2020PSIConfig(std::string const& _selfPartyID, ppc::front::FrontInterface::Ptr _front, + ppc::crypto::CryptoBox::Ptr _cryptoBox, bcos::ThreadPool::Ptr _threadPool, + ppc::io::DataResourceLoader::Ptr _dataResourceLoader, int _holdingMessageMinutes, + uint32_t minNeededMemoryGB = 1, uint16_t _parallelism = 3, + const front::PPCMessageFactory::Ptr& _msgFactory = + std::make_shared()) + : PSIConfig(ppc::protocol::TaskAlgorithmType::CM_PSI_2PC, _selfPartyID, std::move(_front), + _msgFactory, std::move(_dataResourceLoader), _holdingMessageMinutes, minNeededMemoryGB), + m_cryptoBox(std::move(_cryptoBox)), + m_threadPool(std::move(_threadPool)), + m_parallelism(_parallelism) + {} + + virtual ~CM2020PSIConfig() = default; + +public: + crypto::Hash::Ptr const& hash() const { return m_cryptoBox->hashImpl(); } + crypto::EccCrypto::Ptr const& eccCrypto() const { return m_cryptoBox->eccCrypto(); } + bcos::ThreadPool::Ptr const& threadPool() const { return m_threadPool; } + uint16_t parallelism() const { return m_parallelism; } + +private: + ppc::crypto::CryptoBox::Ptr m_cryptoBox; + bcos::ThreadPool::Ptr m_threadPool; + uint16_t m_parallelism; +}; + +} // namespace ppc::psi \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-psi/src/cm2020-psi/CM2020PSIFactory.h b/cpp/wedpr-computing/ppc-psi/src/cm2020-psi/CM2020PSIFactory.h new file mode 100644 index 00000000..a2f07c63 --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/cm2020-psi/CM2020PSIFactory.h @@ -0,0 +1,45 @@ +/** + * Copyright (C) 2022 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 CM2020PSIFactory.h + * @author: shawnhe + * @date 2022-12-7 + */ +#pragma once +#include "CM2020PSIImpl.h" +#include "ppc-framework/crypto/CryptoBox.h" +#include "ppc-framework/io/DataResourceLoader.h" + +namespace ppc::psi +{ +class CM2020PSIFactory +{ +public: + using Ptr = std::shared_ptr; + CM2020PSIFactory() = default; + virtual ~CM2020PSIFactory() = default; + + virtual CM2020PSIImpl::Ptr buildCM2020PSI(std::string const& _selfParty, + ppc::front::FrontInterface::Ptr _front, ppc::crypto::CryptoBox::Ptr _cryptoBox, + bcos::ThreadPool::Ptr _threadPool, ppc::io::DataResourceLoader::Ptr _dataResourceLoader, + int _holdingMessageMinutes, uint16_t _parallelism, uint32_t minNeededMemoryGB = 1) + { + auto config = std::make_shared(_selfParty, std::move(_front), + std::move(_cryptoBox), std::move(_threadPool), std::move(_dataResourceLoader), + _holdingMessageMinutes, minNeededMemoryGB, _parallelism); + return std::make_shared(config); + } +}; +} // namespace ppc::psi \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-psi/src/cm2020-psi/CM2020PSIImpl.cpp b/cpp/wedpr-computing/ppc-psi/src/cm2020-psi/CM2020PSIImpl.cpp new file mode 100644 index 00000000..fa56d7a0 --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/cm2020-psi/CM2020PSIImpl.cpp @@ -0,0 +1,591 @@ +/** + * Copyright (C) 2022 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 CM2020PSIImpl.cpp + * @author: shawnhe + * @date 2022-12-7 + */ + +#include "CM2020PSIImpl.h" +#include "Common.h" +#include "ppc-tools/src/common/TransTools.h" + +using namespace ppc::psi; +using namespace ppc::protocol; +using namespace ppc::front; +using namespace ppc::tools; +using namespace ppc::crypto; +using namespace ppc::io; +using namespace ppc::task; + +CM2020PSIImpl::CM2020PSIImpl(const CM2020PSIConfig::Ptr& _config, unsigned _idleTimeMs) + : Worker("CM2020-PSI", _idleTimeMs), + TaskGuarder(_config, TaskAlgorithmType::CM_PSI_2PC, "CM2020-PSI-Timer"), + m_config(_config), + m_msgQueue(std::make_shared()), + m_ioService(std::make_shared()), + m_parallelism(m_config->parallelism()) +{ + m_threadPool = std::make_shared( + "CM2020-PSI-ThreadPool", static_cast(std::thread::hardware_concurrency() * 0.75)); + m_ot = std::make_shared(m_config->eccCrypto(), m_config->hash()); +} + +void CM2020PSIImpl::asyncRunTask( + ppc::protocol::Task::ConstPtr _task, TaskResponseCallback&& _onTaskFinished) +{ + CM2020_PSI_LOG(INFO) << LOG_DESC("receive a task") << LOG_KV("taskID", _task->id()); + addTask(_task, [self = weak_from_this(), taskID = _task->id(), _onTaskFinished]( + ppc::protocol::TaskResult::Ptr&& _result) { + try + { + auto result = std::move(_result); + _onTaskFinished(std::move(result)); + CM2020_PSI_LOG(INFO) << LOG_DESC("finish a task") << LOG_KV("taskID", taskID); + auto psi = self.lock(); + if (!psi) + { + return; + } + psi->m_parallelism++; + + auto timer = std::make_shared( + *(psi->m_ioService), boost::posix_time::minutes(WAITING_PEER_FINISH_M)); + timer->async_wait([self, timer, taskID](boost::system::error_code) { + auto psi = self.lock(); + if (!psi) + { + return; + } + // erase the taskInfo from the gateway + CM2020_PSI_LOG(INFO) << LOG_DESC("erase task info") << LOG_KV("taskID", taskID); + psi->m_config->front()->eraseTaskInfo(taskID); + }); + } + catch (std::exception& e) + { + CM2020_PSI_LOG(ERROR) << LOG_DESC("handle callback error after finishing task") + << LOG_KV("exception", boost::diagnostic_information(e)); + } + }); + + m_threadPool->enqueue([self = weak_from_this()]() { + auto psi = self.lock(); + if (!psi) + { + return; + } + try + { + psi->asyncRunTask(); + } + catch (std::exception& e) + { + CM2020_PSI_LOG(ERROR) << LOG_DESC("asyncRunTask error") + << LOG_KV("exception", boost::diagnostic_information(e)); + } + }); +} + +// run task +void CM2020PSIImpl::asyncRunTask() +{ + CM2020_PSI_LOG(INFO) << LOG_DESC("asyncRunTask") << LOG_KV("current semaphore", m_parallelism); + + if (m_parallelism <= 0) + { + return; + } + + std::pair taskPair; + { + bcos::UpgradableGuard l(x_taskQueue); + if (m_taskQueue.empty()) + { + return; + } + + bcos::UpgradeGuard ul(l); + taskPair = m_taskQueue.front(); + m_taskQueue.pop(); + m_parallelism--; + } + + auto task = taskPair.first; + + // check task + auto error = checkTask(task, 2, true, task->syncResultToPeer(), false); + if (error) + { + CM2020_PSI_LOG(ERROR) << LOG_DESC("failed to check task, " + error->errorMessage()) + << printTaskInfo(task); + // notice peer to cancel task + noticePeerToFinish(task); + auto result = std::make_shared(task->id()); + result->setError(std::move(error)); + taskPair.second(std::move(result)); + + // mark this taskID as occupied + m_config->front()->notifyTaskInfo(task->id()); + return; + } + + // add pending task + auto taskState = + m_taskStateFactory->createTaskState(task, std::move(taskPair.second), false, m_config); + taskState->setPeerID(getPeerID(task)); + taskState->registerNotifyPeerFinishHandler([self = weak_from_this(), task]() { + auto psi = self.lock(); + if (!psi) + { + return; + } + CM2020_PSI_LOG(INFO) << LOG_DESC("noticePeerToFinish") << printTaskInfo(task); + psi->noticePeerToFinish(task); + }); + try + { + addPendingTask(taskState); + // check the memory + checkHostResource(m_config->minNeededMemoryGB()); + // prepare reader and writer + auto dataResource = task->selfParty()->dataResource(); + auto reader = loadReader(task->id(), dataResource, DataSchema::Bytes); + taskState->setReader(reader, -1); + + auto role = task->selfParty()->partyIndex(); + if (role == uint16_t(PartyType::Client) || task->syncResultToPeer()) + { + auto writer = loadWriter(task->id(), dataResource, task->enableOutputExists()); + taskState->setWriter(writer); + } + + if (role == uint16_t(PartyType::Client)) + { + auto receiver = std::make_shared(m_config, taskState, m_ot); + receiver->asyncRunTask(); + addReceiver(std::move(receiver)); + } + else if (role == uint16_t(PartyType::Server)) + { + auto sender = std::make_shared( + m_config, taskState, m_ioService, m_ot, m_threadPool); + sender->asyncRunTask(); + addSender(std::move(sender)); + } + else + { + CM2020_PSI_LOG(ERROR) << LOG_DESC("undefined task role") << unsigned(role); + onSelfError(task->id(), + std::make_shared( + (int)CM2020PSIRetCode::UNDEFINED_TASK_ROLE, "undefined task role"), + true); + } + } + catch (bcos::Error const& e) + { + CM2020_PSI_LOG(ERROR) << LOG_DESC("asyncRunTask exception") << printTaskInfo(task) + << LOG_KV("code", e.errorCode()) << LOG_KV("msg", e.errorMessage()); + onSelfError( + task->id(), std::make_shared(e.errorCode(), e.errorMessage()), true); + } + catch (const std::exception& e) + { + CM2020_PSI_LOG(ERROR) << LOG_DESC("asyncRunTask exception") << printTaskInfo(task) + << LOG_KV("exception", boost::diagnostic_information(e)); + onSelfError(task->id(), + std::make_shared((int)CM2020PSIRetCode::ON_EXCEPTION, + "exception caught while running task: " + boost::diagnostic_information(e)), + true); + } + + // notify the taskInfo to the front + error = m_config->front()->notifyTaskInfo(task->id()); + if (error && error->errorCode()) + { + onSelfError(task->id(), error, true); + } +} + +// register to the front to get the message related to cm2020-psi +void CM2020PSIImpl::onReceiveMessage(ppc::front::PPCMessageFace::Ptr _msg) +{ + try + { + m_msgQueue->push(_msg); + + // notify to handle the message + wakeupWorker(); + } + catch (std::exception const& e) + { + CM2020_PSI_LOG(WARNING) << LOG_DESC("onReceiveMessage exception") << printPPCMsg(_msg) + << LOG_KV("exception", boost::diagnostic_information(e)); + } +} + +void CM2020PSIImpl::start() +{ + if (m_started) + { + CM2020_PSI_LOG(ERROR) << LOG_DESC("The CM2020-PSI has already been started"); + return; + } + CM2020_PSI_LOG(INFO) << LOG_DESC("Start the CM2020-PSI"); + m_started = true; + + // start a thread to execute task + startWorking(); + + m_thread = std::make_shared([&] { + bcos::pthread_setThreadName("cm2020_io_service"); + while (m_started) + { + try + { + m_ioService->run(); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + if (m_started && m_ioService->stopped()) + { + m_ioService->restart(); + } + } + catch (std::exception& e) + { + FRONT_LOG(WARNING) << LOG_DESC("Exception in CM2020-PSI Thread:") + << boost::diagnostic_information(e); + } + } + CM2020_PSI_LOG(INFO) << "CM2020-PSI exit"; + }); + + startPingTimer(); +} + +void CM2020PSIImpl::stop() +{ + if (!m_started) + { + return; + } + CM2020_PSI_LOG(INFO) << LOG_DESC("Stop CM2020-PSI"); + m_started = false; + + if (m_config->threadPool()) + { + m_config->threadPool()->stop(); + } + + finishWorker(); + if (isWorking()) + { + // stop the worker thread + stopWorking(); + terminate(); + } + + if (m_threadPool) + { + m_threadPool->stop(); + } + if (m_ioService) + { + m_ioService->stop(); + } + // stop the thread + if (m_thread->get_id() != std::this_thread::get_id()) + { + m_thread->join(); + } + else + { + m_thread->detach(); + } + stopPingTimer(); + + CM2020_PSI_LOG(INFO) << LOG_DESC("CM2020-PSI stopped"); +} + +void CM2020PSIImpl::onReceivedErrorNotification(ppc::front::PPCMessageFace::Ptr const& _message) +{ + CM2020_PSI_LOG(INFO) << LOG_DESC("onReceivedErrorNotification") << printPPCMsg(_message); + // finish the task while the peer is failed + auto taskState = findPendingTask(_message->taskID()); + if (taskState) + { + taskState->onPeerNotifyFinish(); + + wakeupWorker(); + } +} + +void CM2020PSIImpl::onSelfError( + const std::string& _taskID, bcos::Error::Ptr _error, bool _noticePeer) +{ + auto taskState = findPendingTask(_taskID); + if (!taskState) + { + return; + } + + CM2020_PSI_LOG(ERROR) << LOG_DESC("onSelfError") << LOG_KV("task", _taskID) + << LOG_KV("exception", _error->errorMessage()) + << LOG_KV("noticePeer", _noticePeer); + + auto result = std::make_shared(taskState->task()->id()); + result->setError(std::move(_error)); + taskState->onTaskFinished(result, _noticePeer); + + wakeupWorker(); +} + +// cm2020-psi main processing function +// for ut to make this function public +void CM2020PSIImpl::executeWorker() +{ + checkFinishedTask(); + auto result = m_msgQueue->tryPop(c_popWaitMs); + if (result.first) + { + handleReceivedMessage(result.second); + return; + } + waitSignal(); +} + +void CM2020PSIImpl::checkFinishedTask() +{ + std::set finishedTask; + { + bcos::WriteGuard l(x_pendingTasks); + if (m_pendingTasks.empty()) + { + return; + } + + for (auto it = m_pendingTasks.begin(); it != m_pendingTasks.end();) + { + auto task = it->second; + if (task->finished()) + { + finishedTask.insert(it->first); + } + it++; + } + } + for (auto& taskID : finishedTask) + { + removeReceiver(taskID); + removeSender(taskID); + removePendingTask(taskID); + asyncRunTask(); + } +} + +void CM2020PSIImpl::handleReceivedMessage(const ppc::front::PPCMessageFace::Ptr& _message) +{ + CM2020_PSI_LOG(TRACE) << LOG_DESC("handleReceivedMessage") << printPPCMsg(_message); + + m_config->threadPool()->enqueue([self = weak_from_this(), _message]() { + try + { + auto psi = self.lock(); + if (!psi) + { + return; + } + switch (int(_message->messageType())) + { + case int(CommonMessageType::ErrorNotification): + { + psi->onReceivedErrorNotification(_message); + break; + } + case int(CommonMessageType::PingPeer): + { + break; + } + case int(CM2020PSIMessageType::HELLO_RECEIVER): + { + psi->onReceiveHelloReceiver(_message); + break; + } + case int(CM2020PSIMessageType::HELLO_SENDER): + { + psi->onReceiveHelloSender(_message); + break; + } + case int(CM2020PSIMessageType::RECEIVER_SIZE): + { + psi->onReceiveReceiverSize(_message); + break; + } + case int(CM2020PSIMessageType::SENDER_SIZE): + { + psi->onReceiveSenderSize(_message); + break; + } + case int(CM2020PSIMessageType::POINT_A): + { + psi->onReceivePointA(_message); + break; + } + case int(CM2020PSIMessageType::POINT_B_ARRAY): + { + psi->onReceiveBatchPointB(_message); + break; + } + case int(CM2020PSIMessageType::MATRIX): + { + psi->onReceiveMatrix(_message); + break; + } + case int(CM2020PSIMessageType::DO_NEXT_ROUND): + { + psi->onReceiveDoNextRound(_message); + break; + } + case int(CM2020PSIMessageType::HASHES): + { + psi->onReceiveHashes(_message); + break; + } + case int(CM2020PSIMessageType::RESULTS_SIZE): + { + psi->onReceiveResultCount(_message); + break; + } + case int(CM2020PSIMessageType::RESULTS): + { + psi->onReceiveResults(_message); + break; + } + default: + { + CM2020_PSI_LOG(WARNING) + << LOG_DESC("unsupported messageType ") << unsigned(_message->messageType()); + break; + } + } + } + catch (std::exception const& e) + { + CM2020_PSI_LOG(WARNING) + << LOG_DESC("handleReceivedMessage exception") + << LOG_KV("type", unsigned(_message->messageType())) << printPPCMsg(_message) + << LOG_KV("exception", boost::diagnostic_information(e)); + } + }); +} + + +void CM2020PSIImpl::onReceiveHelloReceiver(const ppc::front::PPCMessageFace::Ptr& _message) +{ + auto receiver = findReceiver(_message->taskID()); + if (receiver) + { + receiver->onHandshakeDone(); + } +} + +void CM2020PSIImpl::onReceiveHelloSender(const ppc::front::PPCMessageFace::Ptr& _message) +{ + auto sender = findSender(_message->taskID()); + if (sender) + { + sender->onHandshakeDone(_message); + } +} + +void CM2020PSIImpl::onReceiveReceiverSize(ppc::front::PPCMessageFace::Ptr _message) +{ + auto sender = findSender(_message->taskID()); + if (sender) + { + sender->onReceiverSizeReceived(std::move(_message)); + } +} + +void CM2020PSIImpl::onReceiveSenderSize(ppc::front::PPCMessageFace::Ptr _message) +{ + auto receiver = findReceiver(_message->taskID()); + if (receiver) + { + receiver->onSenderSizeReceived(std::move(_message)); + } +} + +void CM2020PSIImpl::onReceivePointA(ppc::front::PPCMessageFace::Ptr _message) +{ + auto sender = findSender(_message->taskID()); + if (sender) + { + sender->onPointAReceived(std::move(_message)); + } +} + +void CM2020PSIImpl::onReceiveBatchPointB(ppc::front::PPCMessageFace::Ptr _message) +{ + auto receiver = findReceiver(_message->taskID()); + if (receiver) + { + receiver->onBatchPointBReceived(std::move(_message)); + } +} + +void CM2020PSIImpl::onReceiveMatrix(ppc::front::PPCMessageFace::Ptr _message) +{ + auto sender = findSender(_message->taskID()); + if (sender) + { + sender->onMatrixColumnReceived(std::move(_message)); + } +} + +void CM2020PSIImpl::onReceiveDoNextRound(ppc::front::PPCMessageFace::Ptr _message) +{ + auto receiver = findReceiver(_message->taskID()); + if (receiver) + { + receiver->onDoNextRoundReceived(); + } +} + +void CM2020PSIImpl::onReceiveHashes(ppc::front::PPCMessageFace::Ptr _message) +{ + auto receiver = findReceiver(_message->taskID()); + if (receiver) + { + receiver->onHashesReceived(std::move(_message)); + } +} + +void CM2020PSIImpl::onReceiveResultCount(ppc::front::PPCMessageFace::Ptr _message) +{ + auto sender = findSender(_message->taskID()); + if (sender) + { + sender->onResultCountReceived(std::move(_message)); + } +} + +void CM2020PSIImpl::onReceiveResults(ppc::front::PPCMessageFace::Ptr _message) +{ + auto sender = findSender(_message->taskID()); + if (sender) + { + sender->onResultReceived(std::move(_message)); + } +} diff --git a/cpp/wedpr-computing/ppc-psi/src/cm2020-psi/CM2020PSIImpl.h b/cpp/wedpr-computing/ppc-psi/src/cm2020-psi/CM2020PSIImpl.h new file mode 100644 index 00000000..01c6d0ce --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/cm2020-psi/CM2020PSIImpl.h @@ -0,0 +1,185 @@ +/** + * Copyright (C) 2022 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 CM2020PSIImpl.h + * @author: shawnhe + * @date 2022-12-7 + */ + +#pragma once +#include +#include +#include +#include +#include + +#include "../psi-framework/TaskGuarder.h" +#include "../psi-framework/TaskState.h" +#include "CM2020PSIConfig.h" +#include "Common.h" +#include "core/CM2020PSIReceiver.h" +#include "core/CM2020PSISender.h" +#include "ppc-crypto/src/randomot/SimplestOT.h" +#include "ppc-framework/protocol/Task.h" +#include "ppc-framework/task/TaskFrameworkInterface.h" +#include "ppc-front/ppc-front/PPCChannel.h" +#include "ppc-tools/src/common/TransTools.h" +#include "protocol/src/PPCMessage.h" + +namespace ppc::psi +{ +class CM2020PSIImpl : public bcos::Worker, + public TaskGuarder, + public ppc::task::TaskFrameworkInterface, + public std::enable_shared_from_this +{ +public: + using Ptr = std::shared_ptr; + using CM2020PSIMsgQueue = bcos::ConcurrentQueue; + using CM2020PSIMsgQueuePtr = std::shared_ptr; + + CM2020PSIImpl(const CM2020PSIConfig::Ptr& _config, unsigned _idleTimeMs = 0); + + ~CM2020PSIImpl() override = default; + + void asyncRunTask(ppc::protocol::Task::ConstPtr _task, + ppc::task::TaskResponseCallback&& _onTaskFinished) override; + + // register to the front to get the message related to cm2020-psi + void onReceiveMessage(ppc::front::PPCMessageFace::Ptr _message) override; + + void start() override; + void stop() override; + void onReceivedErrorNotification(ppc::front::PPCMessageFace::Ptr const& _message) override; + void onSelfError( + const std::string& _taskID, bcos::Error::Ptr _error, bool _noticePeer) override; + + // cm2020-psi main processing function + // for ut to make this function public + void executeWorker() override; + +protected: + void asyncRunTask(); + void checkFinishedTask(); + + void handleReceivedMessage(const ppc::front::PPCMessageFace::Ptr& _message); + + void onReceiveHelloReceiver(const ppc::front::PPCMessageFace::Ptr& _message); + void onReceiveHelloSender(const ppc::front::PPCMessageFace::Ptr& _message); + + void onReceiveReceiverSize(ppc::front::PPCMessageFace::Ptr _message); + void onReceiveSenderSize(ppc::front::PPCMessageFace::Ptr _message); + + void onReceivePointA(ppc::front::PPCMessageFace::Ptr _message); + void onReceiveBatchPointB(ppc::front::PPCMessageFace::Ptr _message); + + void onReceiveMatrix(ppc::front::PPCMessageFace::Ptr _message); + void onReceiveDoNextRound(ppc::front::PPCMessageFace::Ptr _message); + void onReceiveHashes(ppc::front::PPCMessageFace::Ptr _message); + void onReceiveResultCount(ppc::front::PPCMessageFace::Ptr _message); + void onReceiveResults(ppc::front::PPCMessageFace::Ptr _message); + + void addTask( + ppc::protocol::Task::ConstPtr _task, ppc::task::TaskResponseCallback&& _onTaskFinished) + { + bcos::WriteGuard l(x_taskQueue); + m_taskQueue.push({std::move(_task), std::move(_onTaskFinished)}); + } + + CM2020PSIReceiver::Ptr findReceiver(const std::string& _taskID) + { + bcos::ReadGuard l(x_receivers); + auto it = m_receivers.find(_taskID); + if (it != m_receivers.end()) + { + return it->second; + } + return nullptr; + } + void addReceiver(CM2020PSIReceiver::Ptr _receiver) + { + bcos::WriteGuard l(x_receivers); + m_receivers[_receiver->taskID()] = _receiver; + } + void removeReceiver(const std::string& _taskID) + { + bcos::WriteGuard l(x_receivers); + auto it = m_receivers.find(_taskID); + if (it != m_receivers.end()) + { + m_receivers.erase(it); + } + } + + CM2020PSISender::Ptr findSender(const std::string& _taskID) + { + bcos::ReadGuard l(x_senders); + auto it = m_senders.find(_taskID); + if (it != m_senders.end()) + { + return it->second; + } + return nullptr; + } + void addSender(CM2020PSISender::Ptr _sender) + { + bcos::WriteGuard l(x_senders); + m_senders[_sender->taskID()] = _sender; + } + void removeSender(const std::string& _taskID) + { + bcos::WriteGuard l(x_senders); + auto it = m_senders.find(_taskID); + if (it != m_senders.end()) + { + m_senders.erase(it); + } + } + +private: + void waitSignal() + { + boost::unique_lock l(x_signal); + m_signal.wait_for(l, boost::chrono::milliseconds(5)); + } + + void wakeupWorker() { m_signal.notify_all(); } + + CM2020PSIConfig::Ptr m_config; + CM2020PSIMsgQueuePtr m_msgQueue; + std::shared_ptr m_ioService; + std::shared_ptr m_threadPool; + crypto::SimplestOT::Ptr m_ot; + + std::shared_ptr m_thread; + + std::atomic m_parallelism; + std::queue > + m_taskQueue; + mutable bcos::SharedMutex x_taskQueue; + + std::unordered_map m_receivers; + mutable bcos::SharedMutex x_receivers; + + std::unordered_map m_senders; + mutable bcos::SharedMutex x_senders; + + bool m_started{false}; + boost::condition_variable m_signal; + boost::mutex x_signal; + + const int c_popWaitMs = 5; +}; +} // namespace ppc::psi \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-psi/src/cm2020-psi/CMakeLists.txt b/cpp/wedpr-computing/ppc-psi/src/cm2020-psi/CMakeLists.txt new file mode 100644 index 00000000..74fdf391 --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/cm2020-psi/CMakeLists.txt @@ -0,0 +1,31 @@ +set(TARS_HEADER_DIR ${CMAKE_BINARY_DIR}/generated/ppc-psi/cm2020-psi/tars) +find_program(TARS_TARS2CPP tars2cpp REQUIRED) + +file(GLOB_RECURSE TARS_INPUT "*.tars") + +# generate tars +if (TARS_INPUT) + foreach (TARS_FILE ${TARS_INPUT}) + get_filename_component(TARS_NAME ${TARS_FILE} NAME_WE) + get_filename_component(TARS_PATH ${TARS_FILE} PATH) + add_custom_command( + OUTPUT ${TARS_HEADER_DIR}/${TARS_NAME}.h + WORKING_DIRECTORY ${TARS_PATH} + COMMAND ${TARS_TARS2CPP} ${TARS_FILE} --unjson --without-trace --dir=${TARS_HEADER_DIR} + COMMENT "generating ${TARS_FILE} to ${TARS_HEADER_DIR}" + VERBATIM + ) + + list(APPEND OUT_TARS_H_LIST ${TARS_HEADER_DIR}/${TARS_NAME}.h) + endforeach () +endif () + +set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${OUT_TARS_H_LIST}") +include_directories(${TARS_HEADER_DIR}) + +file(GLOB_RECURSE SRCS *.cpp) +add_library(${CM2020_PSI_TARGET} ${SRCS} ${OUT_TARS_H_LIST}) +target_include_directories(${CM2020_PSI_TARGET} PUBLIC + $) + +target_link_libraries(${CM2020_PSI_TARGET} PUBLIC ${PSI_FRAMEWORK_TARGET} ${CRYPTO_TARGET} TBB::tbb) diff --git a/cpp/wedpr-computing/ppc-psi/src/cm2020-psi/Common.h b/cpp/wedpr-computing/ppc-psi/src/cm2020-psi/Common.h new file mode 100644 index 00000000..6a357406 --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/cm2020-psi/Common.h @@ -0,0 +1,87 @@ +/** + * Copyright (C) 2022 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 Common.h + * @author: shawnhe + * @date 2022-12-7 + */ +#pragma once + +#include "ppc-framework/Common.h" +#include "ppc-framework/protocol/PPCMessageFace.h" +#include +#include +#include + + +namespace ppc::psi +{ +DERIVE_PPC_EXCEPTION(CM2020Exception); + +#define CM2020_PSI_LOG(LEVEL) BCOS_LOG(LEVEL) << LOG_BADGE("PSI: CM2020-PSI") +#define HIGH_PERFORMANCE_BUCKET_NUMBER (256) +#define DEFAULT_BUCKET_NUMBER (320) +#define MAX_BUCKET_NUMBER (400) +#define DEFAULT_HANDLE_WIDTH_POWER (24) +#define MIN_HANDLE_WIDTH (8) +#define MAX_SEND_BUFFER_LENGTH (8 * 1024 * 1024) +#define MIN_BUCKET_SIZE (8 * 1024) +#define MAX_COMPUTE_HASH_SIZE (1 << 26) +#define ENCODE_RATE (2) +#define RESULT_LEN_BYTE (16) +#define WAITING_PEER_FINISH_M (10) + +enum class CM2020PSIMessageType : uint8_t +{ + HELLO_RECEIVER = 0x01, + HELLO_SENDER = 0x02, + RECEIVER_SIZE = 0x03, + SENDER_SIZE = 0x04, + POINT_A = 0x05, + POINT_B_ARRAY = 0x06, + MATRIX = 0x07, + DO_NEXT_ROUND = 0x08, + HASHES = 0x09, + RESULTS_SIZE = 0x0a, + RESULTS = 0x0b +}; + +enum class CM2020PSIRetCode : int +{ + ON_EXCEPTION = -3000, + UNDEFINED_TASK_ROLE = -3001, + INVALID_TASK_PARAM = -3002 +}; + +inline uint32_t dedupDataBatch(ppc::io::DataBatch::Ptr dataBatch) +{ + if (!dataBatch || dataBatch->mutableData() == nullptr || dataBatch->mutableData()->empty()) + { + return 0; + } + auto& data = dataBatch->mutableData(); + // Note: the header field should not been sorted + auto it = data->begin() + 1; + if (it >= data->end()) + { + return data->size(); + } + tbb::parallel_sort(it, data->end()); + auto unique_end = std::unique(it, data->end()); + data->erase(unique_end, data->end()); + return data->size(); +} + +} // namespace ppc::psi diff --git a/cpp/wedpr-computing/ppc-psi/src/cm2020-psi/core/CM2020PSIReceiver.cpp b/cpp/wedpr-computing/ppc-psi/src/cm2020-psi/core/CM2020PSIReceiver.cpp new file mode 100644 index 00000000..faf4abf0 --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/cm2020-psi/core/CM2020PSIReceiver.cpp @@ -0,0 +1,984 @@ +/** + * Copyright (C) 2022 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 CM2020PSIReceiver.cpp + * @author: shawnhe + * @date 2022-12-7 + */ + +#include "CM2020PSIReceiver.h" +#include "CM2020PSI.h" +#include "openssl/rand.h" +#include "ppc-crypto/src/prng/AESPRNG.h" +#include "ppc-tools/src/common/TransTools.h" +#include "wedpr-protocol/tars/TarsSerialize.h" +#include + +using namespace ppc::psi; +using namespace ppc::io; +using namespace ppc::protocol; +using namespace ppc::front; +using namespace ppc::crypto; +using namespace ppc::tools; + +CM2020PSIReceiver::CM2020PSIReceiver( + CM2020PSIConfig::Ptr _config, TaskState::Ptr _taskState, SimplestOT::Ptr _ot) + : m_config(std::move(_config)), m_taskState(std::move(_taskState)), m_ot(std::move(_ot)) +{ + auto task = m_taskState->task(); + m_taskID = task->id(); + m_params = std::make_shared(task->param()); + m_params->setSyncResults(task->syncResultToPeer()); + m_params->setLowBandwidth(task->lowBandwidth()); + m_cm2020Result = std::make_shared(m_taskID); + m_startTimePoint = std::chrono::high_resolution_clock::now(); + m_costs.resize(4); + m_progress = std::make_shared(m_config->threadPool()); +} + +void CM2020PSIReceiver::asyncRunTask() +{ + CM2020_PSI_LOG(INFO) << LOG_DESC("asyncRunTask as receiver") << LOG_KV("taskID", m_taskID); + + m_progress->reset(3, [self = weak_from_this()]() { + /** + * 1. prepare inputs done + * 2. run random OT done + * 3. sender size received + */ + auto receiver = self.lock(); + if (!receiver) + { + return; + } + receiver->preprocessInputs(); + receiver->doOprf(); + }); + + m_config->threadPool()->enqueue([self = weak_from_this()]() { + auto receiver = self.lock(); + if (!receiver) + { + return; + } + receiver->runReceiver(); + }); +} + +void CM2020PSIReceiver::runReceiver() +{ + CM2020_PSI_LOG(INFO) << LOG_BADGE("runReceiver") << LOG_KV("taskID", m_taskID) + << LOG_KV("syncResults", m_params->enableSyncResults()) + << LOG_KV("bucketNumber", m_params->bucketNumber()); + try + { + ppctars::CM2020Params cm2020Params; + cm2020Params.bucketNumber = m_params->bucketNumber(); + cm2020Params.enableSyncResults = m_params->enableSyncResults(); + cm2020Params.lowBandwidth = m_params->lowBandwidth(); + cm2020Params.seed.resize(16); + if (RAND_bytes(cm2020Params.seed.data(), 16) != 1) + { + BOOST_THROW_EXCEPTION(CM2020Exception()); + } + + auto message = m_config->ppcMsgFactory()->buildPPCMessage(uint8_t(protocol::TaskType::PSI), + uint8_t(protocol::TaskAlgorithmType::CM_PSI_2PC), m_taskID, + std::make_shared()); + message->setMessageType(uint8_t(CM2020PSIMessageType::HELLO_SENDER)); + ppctars::serialize::encode(cm2020Params, *message->data()); + CM2020_PSI_LOG(INFO) << LOG_BADGE("runReceiver") << LOG_KV("taskID", m_taskID) + << LOG_KV("syncResults", m_params->enableSyncResults()) + << LOG_KV("message data:", *(bcos::toHexString(*(message->data())))) + << LOG_KV("message size:", message->data()->size()) + << LOG_KV("bucketNumber", m_params->bucketNumber()); + // shake hands with each other + m_config->front()->asyncSendMessage( + m_taskState->peerID(), message, m_config->networkTimeout(), + [self = weak_from_this()](bcos::Error::Ptr _error) { + auto receiver = self.lock(); + if (!receiver) + { + return; + } + if (_error && _error->errorCode()) + { + receiver->onReceiverTaskDone(std::move(_error)); + } + }, + nullptr); + + prepareInputs(); + } + catch (const std::exception& e) + { + onReceiverException("runReceiver", e); + } +} + + +void CM2020PSIReceiver::onHandshakeDone() +{ + if (m_taskState->taskDone()) + { + return; + } + CM2020_PSI_LOG(INFO) << LOG_BADGE("onHandshakeDone") << LOG_KV("taskID", m_taskID); + try + { + m_startTimePoint = std::chrono::high_resolution_clock::now(); + runRandomOT(); + } + catch (const std::exception& e) + { + onReceiverException("runRandomOT", e); + } +} + + +void CM2020PSIReceiver::prepareInputs() +{ + CM2020_PSI_LOG(INFO) << LOG_BADGE("prepareInputs") << LOG_KV("taskID", m_taskID); + try + { + auto originData = m_taskState->task()->selfParty()->dataResource()->rawData(); + if (!originData.empty()) + { + m_ioByInterface = true; + } + + m_originInputs = m_taskState->loadAllData(); + if (!m_originInputs || m_originInputs->size() == 0) + { + BOOST_THROW_EXCEPTION(CM2020Exception() << bcos::errinfo_comment("data is empty")); + } + + m_rInputSize = m_originInputs->size(); + m_originLocations.reserve(m_rInputSize); + m_originLocations.resize(m_rInputSize); + m_oprfOutputs.reserve(m_rInputSize); + m_oprfOutputs.resize(m_rInputSize); + CM2020_PSI_LOG(INFO) << LOG_BADGE("prepareInputs success") << LOG_KV("taskID", m_taskID) + << LOG_KV("inputSize", m_rInputSize); + syncInputsSize(); + } + catch (const std::exception& e) + { + onReceiverException("prepareInputs", e); + } +} + +void CM2020PSIReceiver::syncInputsSize() +{ + CM2020_PSI_LOG(INFO) << LOG_BADGE("syncInputsSize") << LOG_KV("taskID", m_taskID); + + auto data = std::make_shared(); + encodeUnsignedNum(data, m_rInputSize); + CM2020_PSI_LOG(TRACE) << LOG_BADGE("syncInputsSize") << LOG_KV("taskID", m_taskID) + << LOG_KV("data", *bcos::toHexString(*data)) + << LOG_KV("inputSize", m_rInputSize); + auto message = m_config->ppcMsgFactory()->buildPPCMessage( + uint8_t(TaskType::PSI), uint8_t(TaskAlgorithmType::CM_PSI_2PC), m_taskID, data); + message->setMessageType(uint8_t(CM2020PSIMessageType::RECEIVER_SIZE)); + + m_config->front()->asyncSendMessage( + m_taskState->peerID(), message, m_config->networkTimeout(), + [self = weak_from_this()](bcos::Error::Ptr _error) { + auto receiver = self.lock(); + if (!receiver) + { + return; + } + if (_error && _error->errorCode()) + { + receiver->onReceiverTaskDone(std::move(_error)); + } + }, + nullptr); + + m_progress->mark("PREPARE_INPUTS"); +} + +void CM2020PSIReceiver::runRandomOT() +{ + CM2020_PSI_LOG(INFO) << LOG_BADGE("runOT as sender") << LOG_KV("taskID", m_taskID); + m_otState = m_ot->senderGeneratePointA(); + + auto message = m_config->ppcMsgFactory()->buildPPCMessage(uint8_t(protocol::TaskType::PSI), + uint8_t(protocol::TaskAlgorithmType::CM_PSI_2PC), m_taskID, m_otState.second); + message->setMessageType(uint8_t(CM2020PSIMessageType::POINT_A)); + + // send point A to ot receiver + m_config->front()->asyncSendMessage( + m_taskState->peerID(), message, m_config->networkTimeout(), + [self = weak_from_this()](bcos::Error::Ptr _error) { + auto receiver = self.lock(); + if (!receiver) + { + return; + } + if (_error && _error->errorCode()) + { + receiver->onReceiverTaskDone(std::move(_error)); + } + }, + nullptr); +} + +void CM2020PSIReceiver::onBatchPointBReceived(PPCMessageFace::Ptr _message) +{ + if (m_taskState->taskDone()) + { + return; + } + CM2020_PSI_LOG(INFO) << LOG_BADGE("handleBatchPointB") << LOG_KV("taskID", m_taskID) + << LOG_KV("payloadSize", _message->data()->size()); + + try + { + m_senderKeys = m_ot->finishSender(m_otState.first, m_otState.second, _message->data()); + m_progress->mark("RANDOM_OT"); + } + catch (const std::exception& e) + { + onReceiverException("onBatchPointBReceived", e); + } +} + +void CM2020PSIReceiver::onSenderSizeReceived(front::PPCMessageFace::Ptr _message) +{ + if (m_taskState->taskDone()) + { + return; + } + CM2020_PSI_LOG(INFO) << LOG_BADGE("onSenderSizeReceived") << LOG_KV("taskID", m_taskID) + << LOG_KV("payloadSize", _message->data()->size()); + try + { + decodeUnsignedNum(m_sInputSize, _message->data()); + m_progress->mark("RECEIVE_SIZE"); + } + catch (const std::exception& e) + { + onReceiverException("onSenderSizeReceived", e); + } +} + + +void CM2020PSIReceiver::preprocessInputs() +{ + if (m_taskState->taskDone()) + { + return; + } + try + { + CM2020_PSI_LOG(INFO) << LOG_BADGE("preprocessInputs") << LOG_KV("taskID", m_taskID); + bcos::bytesConstRef seed(m_taskID); + auto hash = m_config->hash(); + + tbb::parallel_for(tbb::blocked_range(0U, m_rInputSize), [&](auto const& range) { + for (auto i = range.begin(); i < range.end(); i++) + { + auto state = hash->init(); + hash->update(state, seed); + bcos::bytes data = m_originInputs->getBytes(i); + hash->update(state, bcos::ref(bcos::bytes(data.begin(), data.end()))); + auto res = hash->final(state); + memcpy((bcos::byte*)m_originLocations[i].data(), res.data(), 8 * sizeof(uint32_t)); + } + }); + } + catch (const std::exception& e) + { + onReceiverException("preprocessInputs", e); + } +} + +// considering the memory occupation, we handle the global matrix by 'm_handleWidth' column per +// round, when and only when this round ends, the next round will be made +void CM2020PSIReceiver::doOprf() +{ + if (m_taskState->taskDone()) + { + return; + } + try + { + if (m_oprfRound == 0) + { + auto end = std::chrono::high_resolution_clock::now(); + // costs of rot and first three steps + m_costs[0] = + std::chrono::duration_cast(end - m_startTimePoint) + .count(); + + initMatrixParams(); + } + + CM2020_PSI_LOG(INFO) << LOG_BADGE("doOprf") << LOG_KV("taskID", m_taskID) + << LOG_KV("round", m_oprfRound); + + uint32_t offset = m_oprfRound * m_handleWidth; + if (offset >= m_params->bucketNumber()) + { + auto end = std::chrono::high_resolution_clock::now(); + // costs of oprf + m_costs[1] = + std::chrono::duration_cast(end - m_startTimePoint) + .count(); + + // after negotiating matrix and computing oprf, + // we can receive hash from sender and compute intersection + m_config->threadPool()->enqueue([self = weak_from_this()]() { + auto receiver = self.lock(); + if (!receiver) + { + return; + } + receiver->doPsi(); + }); + } + else + { + m_currentWidth = offset + m_handleWidth < m_params->bucketNumber() ? + m_handleWidth : + m_params->bucketNumber() - offset; + + m_progress->reset(m_currentWidth + 1 + 1, [self = weak_from_this()]() { + auto receiver = self.lock(); + if (!receiver) + { + return; + } + receiver->increaseOprfRound(); + receiver->doOprf(); + }); + + constructMatrices(offset, m_currentWidth); + + for (uint32_t i = 0; i < m_currentWidth; ++i) + { + m_config->threadPool()->enqueue([self = weak_from_this(), i, offset]() { + auto receiver = self.lock(); + if (!receiver) + { + return; + } + + // encrypt matrix A ^ matrix Delta by column, and send it to sender + receiver->negotiateMatrix(offset + i, i); + receiver->progress()->mark("MATRIX" + std::to_string(i)); + }); + } + + // when we get matrix A, we can compute the inputs for final hash and negotiate matrix + // with counterparty in parallel + computeOprfOutputs(offset, m_currentWidth); + m_progress->mark("OPRF"); + } + } + catch (const std::exception& e) + { + onReceiverException("doOprf", e); + } +} + +void CM2020PSIReceiver::initMatrixParams() +{ + if (m_taskState->taskDone()) + { + return; + } + uint32_t maxInputSize = std::max(m_rInputSize, m_sInputSize); + + m_handleWidth = m_params->bucketNumber(); + + if (maxInputSize > (1 << DEFAULT_HANDLE_WIDTH_POWER)) + { + // while handling mass data, we do oprf block by block to prevent OOM + m_handleWidth = m_params->bucketNumber() / + (1 << int(std::ceil(log2(maxInputSize) - DEFAULT_HANDLE_WIDTH_POWER))); + m_handleWidth = std::max(m_handleWidth, (uint32_t)MIN_HANDLE_WIDTH); + } + + m_bucketSizeInBytes = std::max( + uint32_t(MIN_BUCKET_SIZE / 8), uint32_t(((long double)maxInputSize * ENCODE_RATE + 7) / 8)); + m_mask = m_bucketSizeInBytes * 8; + + CM2020_PSI_LOG(INFO) << LOG_BADGE("initMatrixParams") << LOG_KV("taskID", m_taskID) + << LOG_KV("rInputSize", m_rInputSize) + << LOG_KV("bucketNumber", m_params->bucketNumber()) + << LOG_KV("handleWidth", m_handleWidth) + << LOG_KV("bucketSizeInBytes", m_bucketSizeInBytes) + << LOG_KV("mask", m_mask); +} + +void CM2020PSIReceiver::constructMatrices(uint32_t _offset, uint32_t _width) +{ + if (m_taskState->taskDone()) + { + return; + } + CM2020_PSI_LOG(INFO) << LOG_BADGE("constructMatrices") << LOG_KV("offset", _offset) + << LOG_KV("width", _width) << LOG_KV("taskID", m_taskID); + + if (_offset == 0) + { + m_matrixA.reserve(m_handleWidth); + m_matrixA.resize(m_handleWidth); + + m_matrixDelta.reserve(m_handleWidth); + m_matrixDelta.resize(m_handleWidth); + } + + tbb::parallel_for(tbb::blocked_range(0U, _width), [&](auto const& range) { + for (auto i = range.begin(); i < range.end(); i++) + { + // construct matrix A + if (_offset == 0) + { + m_matrixA[i].reserve(m_bucketSizeInBytes); + m_matrixA[i].resize(m_bucketSizeInBytes); + m_matrixDelta[i].reserve(m_bucketSizeInBytes); + m_matrixDelta[i].resize(m_bucketSizeInBytes); + } + AESPRNG prng(m_senderKeys[_offset + i][0]); + prng.generate(m_matrixA[i].data(), m_bucketSizeInBytes); + + // int matrix D + memset(m_matrixDelta[i].data(), 255, m_bucketSizeInBytes); + } + }); +} + + +void CM2020PSIReceiver::negotiateMatrix(uint32_t _bucketIndex, uint32_t _matrixIndex) +{ + if (m_taskState->taskDone()) + { + return; + } + CM2020_PSI_LOG(DEBUG) << LOG_BADGE("negotiateMatrix") << LOG_KV("bucketIndex", _bucketIndex) + << LOG_KV("taskID", m_taskID); + + for (uint32_t j = 0; j < m_rInputSize; j++) + { + uint32_t location = (m_originLocations[j][(_bucketIndex) % 4] * (_bucketIndex) + + m_originLocations[j][4 + (_bucketIndex) % 4]) % + m_mask; + m_matrixDelta[_matrixIndex][location >> 3] &= ~(1 << (location & 7)); + } + + auto buffer = std::make_shared(m_bucketSizeInBytes); + + // use key[1] to encrypt matrixA ^ matrixDelta + AESPRNG prng(m_senderKeys[_bucketIndex][1]); + prng.generate(buffer->data(), m_bucketSizeInBytes); + + tbb::parallel_for(tbb::blocked_range(0U, m_bucketSizeInBytes), [&](auto const& range) { + for (auto i = range.begin(); i < range.end(); i++) + { + buffer->at(i) ^= m_matrixA[_matrixIndex][i]; + buffer->at(i) ^= m_matrixDelta[_matrixIndex][i]; + } + }); + + // handle m_bucketSizeInBytes > 4M + uint32_t totalRound = + (m_bucketSizeInBytes + MAX_SEND_BUFFER_LENGTH - 1) / MAX_SEND_BUFFER_LENGTH; + for (uint32_t round = 0; round < totalRound; round++) + { + uint32_t rLen = round * MAX_SEND_BUFFER_LENGTH; + uint32_t currentLen = uint32_t((round + 1) * MAX_SEND_BUFFER_LENGTH) > m_bucketSizeInBytes ? + m_bucketSizeInBytes - rLen : + MAX_SEND_BUFFER_LENGTH; + + auto sendBuffer = std::make_shared( + buffer->begin() + rLen, buffer->begin() + rLen + currentLen); + auto message = m_config->ppcMsgFactory()->buildPPCMessage(uint8_t(protocol::TaskType::PSI), + uint8_t(protocol::TaskAlgorithmType::CM_PSI_2PC), m_taskID, sendBuffer); + message->setSeq(_bucketIndex * totalRound + round); + message->setMessageType(uint8_t(CM2020PSIMessageType::MATRIX)); + + if (m_params->lowBandwidth()) + { + auto error = m_config->sendMessage(m_taskState->peerID(), message); + if (error && error->errorCode()) + { + onReceiverTaskDone(std::move(error)); + } + } + else + { + m_config->front()->asyncSendMessage( + m_taskState->peerID(), message, m_config->networkTimeout(), + [self = weak_from_this()](bcos::Error::Ptr _error) { + auto receiver = self.lock(); + if (!receiver) + { + return; + } + if (_error && _error->errorCode()) + { + receiver->onReceiverTaskDone(std::move(_error)); + } + }, + nullptr); + } + } +} + +void CM2020PSIReceiver::computeOprfOutputs(uint32_t _offset, uint32_t _width) +{ + if (m_taskState->taskDone()) + { + return; + } + CM2020_PSI_LOG(INFO) << LOG_BADGE("computeOprfOutputs") << LOG_KV("offset", _offset) + << LOG_KV("width", _width) << LOG_KV("taskID", m_taskID); + try + { + tbb::parallel_for(tbb::blocked_range(0U, m_rInputSize), [&](auto const& range) { + for (auto i = range.begin(); i < range.end(); i++) + { + auto newSize = (_offset + _width + 7) / 8; + m_oprfOutputs[i].reserve(newSize); + m_oprfOutputs[i].resize(newSize); + for (uint32_t j = 0; j < _width; j++) + { + uint32_t location = (m_originLocations[i][(_offset + j) % 4] * (_offset + j) + + m_originLocations[i][4 + (_offset + j) % 4]) % + m_mask; + + m_oprfOutputs[i][(_offset + j) >> 3] |= + (uint8_t)((bool)(m_matrixA[j][location >> 3] & (1 << (location & 7)))) + << ((_offset + j) & 7); + } + } + }); + } + catch (const std::exception& e) + { + onReceiverException("computeOprfOutputs", e); + } +} + +void CM2020PSIReceiver::onDoNextRoundReceived() +{ + if (m_taskState->taskDone()) + { + return; + } + CM2020_PSI_LOG(INFO) << LOG_BADGE("onDoNextRoundReceived") << LOG_KV("taskID", m_taskID); + m_progress->mark("NEXT"); +} + +void CM2020PSIReceiver::doPsi() +{ + if (m_taskState->taskDone()) + { + return; + } + CM2020_PSI_LOG(INFO) << LOG_BADGE("doPsi") << LOG_KV("taskID", m_taskID); + + try + { + // receive 2^18 hashes per round + uint32_t number = MAX_SEND_BUFFER_LENGTH / RESULT_LEN_BYTE; + m_maxHashSeq = (m_sInputSize + number - 1) / number; + + m_progress->reset(m_maxHashSeq, [self = weak_from_this()]() { + auto receiver = self.lock(); + if (!receiver) + { + return; + } + receiver->finishPsi(); + }); + + clearOprfMemory(); + computeHash(); + + m_rResults = std::make_shared>(m_rInputSize, 0); + if (m_params->enableSyncResults()) + { + m_sResults = std::make_shared>(m_sInputSize, 0); + } + + bcos::WriteGuard l(x_receivedHash); + m_hashReady.exchange(true); + + tryComputeIntersection(); + } + catch (const std::exception& e) + { + onReceiverException("doPsi", e); + } +} + +void CM2020PSIReceiver::clearOprfMemory() +{ + CM2020_PSI_LOG(INFO) << LOG_BADGE("clearOprfMemory") << LOG_KV("taskID", m_taskID); + + std::vector>().swap(m_originLocations); + std::vector().swap(m_matrixA); + std::vector().swap(m_matrixDelta); + MallocExtension::instance()->ReleaseFreeMemory(); +} + +void CM2020PSIReceiver::computeHash() +{ + if (m_taskState->taskDone()) + { + return; + } + CM2020_PSI_LOG(INFO) << LOG_BADGE("computeHash") << LOG_KV("taskID", m_taskID); + + // avoid OOM + uint32_t totalRound = (m_rInputSize + MAX_COMPUTE_HASH_SIZE - 1) / MAX_COMPUTE_HASH_SIZE; + + auto hash = m_config->hash(); + for (uint32_t round = 0; round < totalRound; round++) + { + uint32_t offset = round * MAX_COMPUTE_HASH_SIZE; + uint32_t currentNum = (round + 1) * MAX_COMPUTE_HASH_SIZE > m_rInputSize ? + m_rInputSize - offset : + MAX_COMPUTE_HASH_SIZE; + + std::vector hashes; + hashes.reserve(currentNum); + hashes.resize(currentNum); + + tbb::parallel_for(tbb::blocked_range(0U, currentNum), [&](auto const& range) { + for (auto i = range.begin(); i < range.end(); i++) + { + auto res = hash->hash(bcos::ref(m_oprfOutputs[offset + i])); + memcpy((bcos::byte*)&hashes[i], res.data(), RESULT_LEN_BYTE); + } + }); + + for (uint32_t i = 0; i < currentNum; i++) + { + m_hashes[hashes[i]] = offset + i; + } + } + + // clear oprf outputs + std::vector>().swap(m_oprfOutputs); + MallocExtension::instance()->ReleaseFreeMemory(); +} + + +void CM2020PSIReceiver::tryComputeIntersection() +{ + if (m_taskState->taskDone()) + { + return; + } + CM2020_PSI_LOG(INFO) << LOG_BADGE("tryComputeIntersection") << LOG_KV("taskID", m_taskID); + for (auto& it : m_receivedHash) + { + uint32_t round = it.first; + bcos::bytesPointer buffer = it.second; + m_config->threadPool()->enqueue([round, buffer, self = weak_from_this()]() { + auto receiver = self.lock(); + if (!receiver) + { + return; + } + receiver->computeIntersection(round, buffer); + }); + } +} + +void CM2020PSIReceiver::onHashesReceived(PPCMessageFace::Ptr _message) +{ + if (m_taskState->taskDone()) + { + return; + } + CM2020_PSI_LOG(DEBUG) << LOG_BADGE("handleReceivedHash") << LOG_KV("taskID", m_taskID) + << LOG_KV("seq", _message->seq()); + + try + { + { + bcos::WriteGuard l(x_receivedHash); + if (!m_hashReady) + { + m_receivedHash[_message->seq()] = _message->data(); + return; + } + } + computeIntersection(_message->seq(), _message->data()); + } + catch (const std::exception& e) + { + onReceiverException("onHashesReceived", e); + } +} + +void CM2020PSIReceiver::computeIntersection(uint32_t _round, bcos::bytesPointer _buffer) +{ + if (m_taskState->taskDone()) + { + return; + } + CM2020_PSI_LOG(DEBUG) << LOG_BADGE("computeIntersection") << LOG_KV("taskID", m_taskID) + << LOG_KV("seq", _round); + try + { + uint32_t hashNum = _buffer->size() / RESULT_LEN_BYTE; + uint32_t handleNum = MAX_SEND_BUFFER_LENGTH / RESULT_LEN_BYTE; + for (uint32_t i = 0; i < hashNum; i++) + { + u128 key = *(u128*)(_buffer->data() + i * RESULT_LEN_BYTE); + if (m_hashes.find(key) != m_hashes.end()) + { + m_rResults->at(m_hashes[key]) = 1; + if (m_params->enableSyncResults()) + { + m_sResults->at(_round * handleNum + i) = 1; + } + m_resultCount++; + } + } + + m_progress->mark((uint64_t)_round); + } + catch (const std::exception& e) + { + onReceiverException("computeIntersection", e); + } +} + +void CM2020PSIReceiver::finishPsi() +{ + if (m_taskState->taskDone()) + { + return; + } + try + { + auto end = std::chrono::high_resolution_clock::now(); + // costs of psi + m_costs[2] = + std::chrono::duration_cast(end - m_startTimePoint).count(); + + CM2020_PSI_LOG(INFO) << LOG_BADGE("finishPsi") LOG_KV("taskID", m_taskID); + if (m_params->enableSyncResults()) + { + syncResults(m_resultCount); + } + + if (m_resultCount > 0) + { + // save results + saveResults(); + } + + onReceiverTaskDone(nullptr); + } + catch (const std::exception& e) + { + onReceiverException("finishPsi", e); + } +} + +void CM2020PSIReceiver::syncResults(uint32_t _count) +{ + if (m_taskState->taskDone()) + { + return; + } + CM2020_PSI_LOG(INFO) << LOG_BADGE("syncResults") << LOG_KV("taskID", m_taskID) + << LOG_KV("count", _count); + + // send the count of results + auto countData = std::make_shared(); + encodeUnsignedNum(countData, uint32_t(_count)); + auto message = m_config->ppcMsgFactory()->buildPPCMessage( + uint8_t(TaskType::PSI), uint8_t(TaskAlgorithmType::CM_PSI_2PC), m_taskID, countData); + message->setMessageType(uint8_t(CM2020PSIMessageType::RESULTS_SIZE)); + + auto error = m_config->sendMessage(m_taskState->peerID(), message); + if (error && error->errorCode()) + { + onReceiverTaskDone(std::move(error)); + } + + if (_count == 0) + { + return; + } + + // send 2^20 indexes per round + uint32_t number = MAX_SEND_BUFFER_LENGTH / sizeof(uint32_t); + uint32_t count = 0, round = 0, totalCount = 0; + uint32_t currentLen = (round + 1) * number > _count ? _count - round * number : number; + auto buffer = std::make_shared(currentLen * sizeof(uint32_t)); + + for (uint32_t index = 0; index < m_sInputSize; index++) + { + if (m_sResults->at(index)) + { + encodeUnsignedNum(buffer->data() + count * sizeof(uint32_t), index); + count++, totalCount++; + if (count == currentLen) + { + auto resMessage = m_config->ppcMsgFactory()->buildPPCMessage(uint8_t(TaskType::PSI), + uint8_t(TaskAlgorithmType::CM_PSI_2PC), m_taskID, buffer); + resMessage->setMessageType(uint8_t(CM2020PSIMessageType::RESULTS)); + resMessage->setSeq(round); + + if (m_params->lowBandwidth()) + { + error = m_config->sendMessage(m_taskState->peerID(), resMessage); + if (error && error->errorCode()) + { + onReceiverTaskDone(std::move(error)); + } + } + else + { + m_config->front()->asyncSendMessage( + m_taskState->peerID(), resMessage, m_config->networkTimeout(), + [self = weak_from_this()](bcos::Error::Ptr _error) { + auto receiver = self.lock(); + if (!receiver) + { + return; + } + if (_error && _error->errorCode()) + { + receiver->onReceiverTaskDone(std::move(_error)); + } + }, + nullptr); + } + + if (totalCount < _count) + { + count = 0, round++; + currentLen = (round + 1) * number > _count ? _count - round * number : number; + buffer = std::make_shared(currentLen * sizeof(uint32_t)); + } + } + } + } +} + +void CM2020PSIReceiver::saveResults() +{ + CM2020_PSI_LOG(INFO) << LOG_BADGE("saveResults") << LOG_KV("taskID", m_taskID); + try + { + if (m_ioByInterface) + { + std::vector results; + for (uint32_t index = 0; index < m_rInputSize; index++) + { + if (m_rResults->at(index)) + { + auto line = m_originInputs->getBytes(index); + results.emplace_back(std::string(line.begin(), line.end())); + } + } + m_cm2020Result->m_outputs.emplace_back(std::move(results)); + } + else + { + DataBatch::Ptr finalResults = std::make_shared(); + for (uint32_t index = 0; index < m_rInputSize; index++) + { + if (m_rResults->at(index)) + { + finalResults->append(m_originInputs->getBytes(index)); + } + } + CM2020_PSI_LOG(INFO) << LOG_BADGE("before dedup") << LOG_KV("taskID", m_taskID) + << LOG_KV("originCount", finalResults->size()); + m_resultCount = dedupDataBatch(finalResults); + CM2020_PSI_LOG(INFO) << LOG_BADGE("after dedup") << LOG_KV("taskID", m_taskID) + << LOG_KV("resultCount", m_resultCount); + m_taskState->writeLines(finalResults, DataSchema::Bytes); + } + } + catch (const std::exception& e) + { + onReceiverException("saveResults", e); + } +} + +void CM2020PSIReceiver::onReceiverException(const std::string& _module, const std::exception& e) +{ + CM2020_PSI_LOG(ERROR) << LOG_BADGE(_module) LOG_KV("taskID", m_taskID) + << LOG_KV("exception", boost::diagnostic_information(e)); + auto error = std::make_shared( + (int)CM2020PSIRetCode::ON_EXCEPTION, boost::diagnostic_information(e)); + onReceiverTaskDone(error); +} + +void CM2020PSIReceiver::onReceiverTaskDone(bcos::Error::Ptr _error) +{ + if (m_taskState->taskDone() && (!_error || _error->errorCode() == 0)) + { + return; + } + + CM2020_PSI_LOG(INFO) << LOG_BADGE("onReceiverTaskDone") LOG_KV("taskID", m_taskID); + + std::string message; + if (_error) + { + message = "\nStatus: FAIL\nMessage: " + _error->errorMessage(); + m_cm2020Result->setError(std::move(_error)); + } + else + { + auto end = std::chrono::high_resolution_clock::now(); + // costs of aftermath + m_costs[3] = + std::chrono::duration_cast(end - m_startTimePoint).count(); + + uint64_t communication = + (uint64_t)m_bucketSizeInBytes * (uint64_t)m_params->bucketNumber() + + (uint64_t)m_sInputSize * (uint64_t)sizeof(u128); + + if (m_params->enableSyncResults()) + { + communication += (uint64_t)m_resultCount * (uint64_t)sizeof(uint32_t); + } + + communication /= (uint64_t)(1024 * 1024); + + m_cm2020Result->m_enableSyncResults = m_params->enableSyncResults(); + m_cm2020Result->m_bucketNumber = m_params->bucketNumber(); + m_cm2020Result->m_communication = std::to_string(communication) + "MB"; + m_cm2020Result->m_intersections = m_resultCount; + m_cm2020Result->m_party0Size = m_rInputSize; + m_cm2020Result->m_party1Size = m_sInputSize; + + message = "\nStatus: SUCCESS\nOrigin Inputs Number: " + std::to_string(m_rInputSize) + + "\nIntersections Number: " + std::to_string(m_resultCount) + + "\nCommunication: " + std::to_string(communication) + + "MB\nTotal Costs: " + std::to_string(m_costs[3]) + "ms\n"; + } + m_taskState->onTaskFinished(m_cm2020Result, true); + + CM2020_PSI_LOG(INFO) << LOG_BADGE("receiverTaskDone") << LOG_KV("taskID", m_taskID) + << LOG_KV("detail", message); +} diff --git a/cpp/wedpr-computing/ppc-psi/src/cm2020-psi/core/CM2020PSIReceiver.h b/cpp/wedpr-computing/ppc-psi/src/cm2020-psi/core/CM2020PSIReceiver.h new file mode 100644 index 00000000..7c3184fd --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/cm2020-psi/core/CM2020PSIReceiver.h @@ -0,0 +1,155 @@ +/** + * Copyright (C) 2022 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 CM2020PSIReceiver.h + * @author: shawnhe + * @date 2022-12-7 + */ + +#pragma once +#include "../../psi-framework/TaskState.h" +#include "../protocol/CM2020PSIResult.h" +#include "TaskParams.h" +#include "ppc-crypto/src/randomot/SimplestOT.h" +#include "ppc-framework/task/TaskFrameworkInterface.h" +#include "ppc-psi/src/cm2020-psi/CM2020PSIConfig.h" +#include "ppc-tools/src/common/Progress.h" +#include +#include + +namespace ppc::psi +{ +class CM2020PSIReceiver : public std::enable_shared_from_this +{ +public: + using Ptr = std::shared_ptr; + + CM2020PSIReceiver( + CM2020PSIConfig::Ptr m_config, TaskState::Ptr _taskState, crypto::SimplestOT::Ptr _ot); + + ~CM2020PSIReceiver() + { + if (m_originInputs) + { + m_originInputs->setData(std::vector()); + } + std::vector>().swap(m_originLocations); + std::vector>().swap(m_oprfOutputs); + std::vector().swap(m_matrixA); + std::vector().swap(m_matrixDelta); + std::unordered_map().swap(m_hashes); + std::unordered_map().swap(m_receivedHash); + std::shared_ptr>().swap(m_rResults); + std::shared_ptr>().swap(m_sResults); + // release the memory to os + MallocExtension::instance()->ReleaseFreeMemory(); + CM2020_PSI_LOG(INFO) << LOG_DESC("the receiver destroyed") << LOG_KV("taskID", m_taskID); + } + + void asyncRunTask(); + + void onHandshakeDone(); + + void onSenderSizeReceived(front::PPCMessageFace::Ptr _message); + + void onBatchPointBReceived(front::PPCMessageFace::Ptr _message); + + void onDoNextRoundReceived(); + + void onHashesReceived(front::PPCMessageFace::Ptr _message); + + const std::string& taskID() const { return m_taskID; } + TaskParams::Ptr params() { return m_params; } + +protected: + void runReceiver(); + void prepareInputs(); + void syncInputsSize(); + void runRandomOT(); + + void preprocessInputs(); + void doOprf(); + void initMatrixParams(); + void constructMatrices(uint32_t _offset, uint32_t _width); + void computeOprfOutputs(uint32_t _offset, uint32_t _width); + void negotiateMatrix(uint32_t _bucketIndex, uint32_t _matrixIndex); + void increaseOprfRound() { m_oprfRound++; } + void clearOprfMemory(); + + void doPsi(); + void computeHash(); + void tryComputeIntersection(); + void computeIntersection(uint32_t _round, bcos::bytesPointer _buffer); + + void finishPsi(); + void syncResults(uint32_t _count); + void saveResults(); + + void onReceiverException(const std::string& _module, const std::exception& e); + void onReceiverTaskDone(bcos::Error::Ptr _error); + + tools::Progress::Ptr progress() { return m_progress; } + +private: + CM2020PSIConfig::Ptr m_config; + TaskState::Ptr m_taskState; + crypto::SimplestOT::Ptr m_ot; + + std::string m_taskID; + TaskParams::Ptr m_params; + CM2020PSIResult::Ptr m_cm2020Result; + + ppc::io::DataBatch::Ptr m_originInputs; + uint32_t m_rInputSize; + uint32_t m_sInputSize; + bool m_ioByInterface{false}; + + std::pair m_otState; + std::vector> m_senderKeys; + + std::vector> m_originLocations; + std::vector> m_oprfOutputs; + + // width of per round processing + uint32_t m_handleWidth; + + // size of each bucket (bytes) + // the bucket size is also the height of matrix + uint32_t m_bucketSizeInBytes; + uint32_t m_mask; + + std::atomic m_oprfRound{0}; + uint32_t m_currentWidth; + std::vector m_matrixA; + std::vector m_matrixDelta; + + // key: the hash of OPRF output, value: the index of input + std::unordered_map m_hashes; + + std::atomic m_hashReady{false}; + uint32_t m_maxHashSeq; + mutable bcos::SharedMutex x_receivedHash; + std::unordered_map m_receivedHash; + + std::atomic m_resultCount; + std::shared_ptr> m_rResults; + std::shared_ptr> m_sResults; + + std::chrono::time_point m_startTimePoint; + std::vector m_costs; + + tools::Progress::Ptr m_progress; +}; +} // namespace ppc::psi diff --git a/cpp/wedpr-computing/ppc-psi/src/cm2020-psi/core/CM2020PSISender.cpp b/cpp/wedpr-computing/ppc-psi/src/cm2020-psi/core/CM2020PSISender.cpp new file mode 100644 index 00000000..f8a4b93b --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/cm2020-psi/core/CM2020PSISender.cpp @@ -0,0 +1,897 @@ +/** + * Copyright (C) 2022 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 CM2020PSISender.cpp + * @author: shawnhe + * @date 2022-12-7 + */ + +#include "CM2020PSISender.h" +#include "CM2020PSI.h" +#include "openssl/rand.h" +#include "ppc-crypto/src/prng/AESPRNG.h" +#include "ppc-tools/src/common/TransTools.h" +#include "wedpr-protocol/tars/TarsSerialize.h" +#include + +using namespace ppc::psi; +using namespace ppc::io; +using namespace ppc::protocol; +using namespace ppc::front; +using namespace ppc::crypto; +using namespace ppc::tools; + +CM2020PSISender::CM2020PSISender(CM2020PSIConfig::Ptr _config, TaskState::Ptr _taskState, + std::shared_ptr _ioService, SimplestOT::Ptr _ot, + std::shared_ptr _threadPool) + : m_config(std::move(_config)), m_taskState(std::move(_taskState)), m_ot(std::move(_ot)) +{ + auto task = m_taskState->task(); + m_taskID = task->id(); + m_params = std::make_shared(task->param()); + m_params->setSyncResults(task->syncResultToPeer()); + m_cm2020Result = std::make_shared(m_taskID); + m_channelManager = std::make_shared(std::move(_ioService), nullptr); + m_channelManager->setThreadPool(std::move(_threadPool)); + m_channel = m_channelManager->buildChannelForTask(m_taskID); + m_startTimePoint = std::chrono::high_resolution_clock::now(); + m_costs.resize(4); + m_matrixProgress = std::make_shared(m_config->threadPool()); + m_progress = std::make_shared(m_config->threadPool()); +} + + +void CM2020PSISender::asyncRunTask() +{ + CM2020_PSI_LOG(INFO) << LOG_DESC("asyncRunTask as sender") << LOG_KV("taskID", m_taskID); + + m_progress->reset(4, [self = weak_from_this()]() { + /** + * 1. prepare inputs done + * 2. run random OT done + * 3. receiver size received + * 4. handshake done + */ + auto sender = self.lock(); + if (!sender) + { + return; + } + sender->preprocessInputs(); + sender->doOprf(); + }); + + m_config->threadPool()->enqueue([self = weak_from_this()]() { + auto sender = self.lock(); + if (!sender) + { + return; + } + sender->runSender(); + }); +} + +void CM2020PSISender::runSender() +{ + CM2020_PSI_LOG(INFO) << LOG_BADGE("runSender") << LOG_KV("taskID", m_taskID) + << LOG_KV("syncResults", m_params->enableSyncResults()) + << LOG_KV("bucketNumber", m_params->bucketNumber()); + + try + { + auto message = m_config->ppcMsgFactory()->buildPPCMessage(uint8_t(protocol::TaskType::PSI), + uint8_t(protocol::TaskAlgorithmType::CM_PSI_2PC), m_taskID, + std::make_shared()); + message->setMessageType(uint8_t(CM2020PSIMessageType::HELLO_RECEIVER)); + + // shake hands with each other + m_config->front()->asyncSendMessage( + m_taskState->peerID(), message, m_config->networkTimeout(), + [self = weak_from_this()](bcos::Error::Ptr _error) { + auto sender = self.lock(); + if (!sender) + { + return; + } + if (_error && _error->errorCode()) + { + sender->onSenderTaskDone(std::move(_error)); + } + }, + nullptr); + + prepareInputs(); + } + catch (const std::exception& e) + { + onSenderException("runSender", e); + } +} + +void CM2020PSISender::onHandshakeDone(front::PPCMessageFace::Ptr _message) +{ + if (m_taskState->taskDone()) + { + return; + } + CM2020_PSI_LOG(INFO) << LOG_BADGE("onHandshakeDone") << LOG_KV("taskID", m_taskID); + m_startTimePoint = std::chrono::high_resolution_clock::now(); + ppctars::CM2020Params tarsParams; + ppctars::serialize::decode(*_message->data(), tarsParams); + m_params->setSyncResults(tarsParams.enableSyncResults); + m_params->setBucketNumber(uint16_t(tarsParams.bucketNumber)); + m_params->setSeed(tarsParams.seed); + m_params->setLowBandwidth(tarsParams.lowBandwidth); + + m_progress->mark("HANDSHAKE"); +} + +void CM2020PSISender::prepareInputs() +{ + CM2020_PSI_LOG(INFO) << LOG_BADGE("prepareInputs") << LOG_KV("taskID", m_taskID); + try + { + auto originData = m_taskState->task()->selfParty()->dataResource()->rawData(); + if (!originData.empty()) + { + m_ioByInterface = true; + } + + m_originInputs = m_taskState->loadAllData(); + if (!m_originInputs || m_originInputs->size() == 0) + { + BOOST_THROW_EXCEPTION(CM2020Exception() << bcos::errinfo_comment("data is empty")); + } + + m_sInputSize = m_originInputs->size(); + m_originLocations.reserve(m_sInputSize); + m_originLocations.resize(m_sInputSize); + m_oprfOutputs.reserve(m_sInputSize); + m_oprfOutputs.resize(m_sInputSize); + + syncInputsSize(); + } + catch (const std::exception& e) + { + onSenderException("prepareInputs", e); + } +} + +void CM2020PSISender::syncInputsSize() +{ + CM2020_PSI_LOG(INFO) << LOG_BADGE("syncInputsSize") << LOG_KV("taskID", m_taskID); + + auto data = std::make_shared(); + encodeUnsignedNum(data, m_sInputSize); + auto message = m_config->ppcMsgFactory()->buildPPCMessage( + uint8_t(TaskType::PSI), uint8_t(TaskAlgorithmType::CM_PSI_2PC), m_taskID, data); + message->setMessageType(uint8_t(CM2020PSIMessageType::SENDER_SIZE)); + + m_config->front()->asyncSendMessage( + m_taskState->peerID(), message, m_config->networkTimeout(), + [self = weak_from_this()](bcos::Error::Ptr _error) { + auto sender = self.lock(); + if (!sender) + { + return; + } + if (_error && _error->errorCode()) + { + sender->onSenderTaskDone(std::move(_error)); + } + }, + nullptr); + + m_progress->mark("PREPARE_INPUTS"); +} + +void CM2020PSISender::onReceiverSizeReceived(front::PPCMessageFace::Ptr _message) +{ + if (m_taskState->taskDone()) + { + return; + } + + CM2020_PSI_LOG(INFO) << LOG_BADGE("onReceiverSizeReceived") << LOG_KV("taskID", m_taskID); + try + { + decodeUnsignedNum(m_rInputSize, _message->data()); + m_progress->mark("RECEIVE_SIZE"); + CM2020_PSI_LOG(INFO) << LOG_BADGE("onReceiverSizeReceived") << LOG_KV("taskID", m_taskID) + << LOG_KV("inputSize", m_rInputSize); + } + catch (const std::exception& e) + { + onSenderException("onReceiverSizeReceived", e); + } +} + +void CM2020PSISender::onPointAReceived(front::PPCMessageFace::Ptr _message) +{ + if (m_taskState->taskDone()) + { + return; + } + CM2020_PSI_LOG(INFO) << LOG_BADGE("onPointAReceived") << LOG_KV("taskID", m_taskID); + try + { + auto pointA = _message->data(); + + bcos::bytes seed(16); + if (RAND_bytes(seed.data(), 16) != 1) + { + BOOST_THROW_EXCEPTION(CM2020Exception()); + } + AESPRNG::Ptr prng = std::make_shared(seed); + m_otChoices = std::make_shared(); + m_otChoices->randomize(prng, (m_params->bucketNumber() + 7) / 8); + + auto retPair = m_ot->receiverGeneratePointsB(m_otChoices, pointA); + + CM2020_PSI_LOG(INFO) << LOG_BADGE("onPointAReceived and send pointB") + << LOG_KV("taskID", m_taskID) + << LOG_KV("dataSize", retPair.first->size()) + << LOG_KV("otNumber", m_otChoices->size()); + // send batch point B to ot sender + auto message = m_config->ppcMsgFactory()->buildPPCMessage(uint8_t(TaskType::PSI), + uint8_t(TaskAlgorithmType::CM_PSI_2PC), m_taskID, retPair.first); + message->setMessageType(uint8_t(CM2020PSIMessageType::POINT_B_ARRAY)); + + m_config->front()->asyncSendMessage( + m_taskState->peerID(), message, m_config->networkTimeout(), + [self = weak_from_this()](bcos::Error::Ptr _error) { + auto sender = self.lock(); + if (!sender) + { + return; + } + if (_error && _error->errorCode()) + { + sender->onSenderTaskDone(std::move(_error)); + } + }, + nullptr); + + // finish ot receiver + m_receiverKeys = m_ot->finishReceiver(pointA, retPair.second); + m_progress->mark("RANDOM_OT"); + } + catch (const std::exception& e) + { + onSenderException("onPointAReceived", e); + } +} + +void CM2020PSISender::preprocessInputs() +{ + if (m_taskState->taskDone()) + { + return; + } + CM2020_PSI_LOG(INFO) << LOG_BADGE("preprocessInputs") << LOG_KV("taskID", m_taskID); + try + { + bcos::bytesConstRef seed(m_taskID); + auto hash = m_config->hash(); + tbb::parallel_for(tbb::blocked_range(0U, m_sInputSize), [&](auto const& range) { + for (auto i = range.begin(); i < range.end(); i++) + { + auto state = hash->init(); + hash->update(state, seed); + auto data = m_originInputs->getBytes(i); + hash->update(state, bcos::ref(bcos::bytes(data.begin(), data.end()))); + auto res = hash->final(state); + memcpy((bcos::byte*)m_originLocations[i].data(), res.data(), 8 * sizeof(uint32_t)); + } + }); + } + catch (const std::exception& e) + { + onSenderException("preprocessInputs", e); + } +} + +void CM2020PSISender::doOprf() +{ + if (m_taskState->taskDone()) + { + return; + } + try + { + if (m_oprfRound == 0) + { + auto end = std::chrono::high_resolution_clock::now(); + // costs of rot and prepare inputs + m_costs[0] = + std::chrono::duration_cast(end - m_startTimePoint) + .count(); + + initMatrixParams(); + } + + CM2020_PSI_LOG(INFO) << LOG_BADGE("doOprf") << LOG_KV("taskID", m_taskID) + << LOG_KV("round", m_oprfRound); + + uint32_t offset = m_oprfRound * m_handleWidth; + if (offset >= m_params->bucketNumber()) + { + auto end = std::chrono::high_resolution_clock::now(); + // costs of oprf + m_costs[1] = + std::chrono::duration_cast(end - m_startTimePoint) + .count(); + + // after negotiating matrix and computing oprf, + // we can receive hash from sender and compute intersection + m_config->threadPool()->enqueue([self = weak_from_this()]() { + auto sender = self.lock(); + if (!sender) + { + return; + } + sender->doPsi(); + }); + } + else + { + uint32_t currentWidth = offset + m_handleWidth < m_params->bucketNumber() ? + m_handleWidth : + m_params->bucketNumber() - offset; + uint32_t totalRound = + (m_bucketSizeInBytes + MAX_SEND_BUFFER_LENGTH - 1) / MAX_SEND_BUFFER_LENGTH; + + constructMatrices(offset, currentWidth); + m_progress->reset( + currentWidth * totalRound, [self = weak_from_this(), offset, currentWidth]() { + auto sender = self.lock(); + if (!sender) + { + return; + } + sender->computeOprfOutputs(offset, currentWidth); + sender->increaseOprfRound(); + sender->doOprf(); + }); + + m_matrixProgress->reset(currentWidth * totalRound, [self = weak_from_this()]() { + auto sender = self.lock(); + if (!sender) + { + return; + } + sender->noticeReceiverDoNextRound(); + }); + + for (uint32_t col = 0; col < currentWidth; col++) + { + for (uint32_t round = 0; round < totalRound; round++) + { + m_channel->asyncReceiveMessage(uint8_t(CM2020PSIMessageType::MATRIX), + (offset + col) * totalRound + round, 30 * 60, + [self = weak_from_this(), offset, col, totalRound, round]( + bcos::Error::Ptr _error, front::PPCMessageFace::Ptr _message) { + auto sender = self.lock(); + if (!sender) + { + return; + } + if (_error && _error->errorCode()) + { + sender->onSenderTaskDone(std::move(_error)); + } + else + { + sender->matrixProgress()->mark( + (offset + col) * totalRound + round); + + sender->handleMatrixColumnReceived( + offset, col, round, _message->data()); + + sender->progress()->mark( + (offset + col) * totalRound + round); + } + }); + } + } + } + } + catch (const std::exception& e) + { + onSenderException("doOprf", e); + } +} + +void CM2020PSISender::noticeReceiverDoNextRound() +{ + CM2020_PSI_LOG(INFO) << LOG_BADGE("noticeReceiverDoNextRound") << LOG_KV("taskID", m_taskID) + << LOG_KV("round", m_oprfRound); + auto message = m_config->ppcMsgFactory()->buildPPCMessage(uint8_t(protocol::TaskType::PSI), + uint8_t(protocol::TaskAlgorithmType::CM_PSI_2PC), m_taskID, + std::make_shared()); + message->setMessageType(uint8_t(CM2020PSIMessageType::DO_NEXT_ROUND)); + m_config->front()->asyncSendMessage( + m_taskState->peerID(), message, m_config->networkTimeout(), + [self = weak_from_this()](bcos::Error::Ptr _error) { + auto sender = self.lock(); + if (!sender) + { + return; + } + if (_error && _error->errorCode()) + { + sender->onSenderTaskDone(std::move(_error)); + } + }, + nullptr); +} + +void CM2020PSISender::initMatrixParams() +{ + if (m_taskState->taskDone()) + { + return; + } + uint32_t maxInputSize = std::max(m_rInputSize, m_sInputSize); + + m_handleWidth = m_params->bucketNumber(); + + if (maxInputSize > (1 << DEFAULT_HANDLE_WIDTH_POWER)) + { + // while handling mass data, we do oprf block by block to prevent OOM + m_handleWidth = m_params->bucketNumber() / + (1 << int(std::ceil(log2(maxInputSize) - DEFAULT_HANDLE_WIDTH_POWER))); + m_handleWidth = std::max(m_handleWidth, (uint32_t)MIN_HANDLE_WIDTH); + } + + m_bucketSizeInBytes = std::max( + uint32_t(MIN_BUCKET_SIZE / 8), uint32_t(((long double)maxInputSize * ENCODE_RATE + 7) / 8)); + m_mask = m_bucketSizeInBytes * 8; + + CM2020_PSI_LOG(INFO) << LOG_BADGE("initMatrixParams") << LOG_KV("taskID", m_taskID) + << LOG_KV("sInputSize", m_sInputSize) + << LOG_KV("bucketNumber", m_params->bucketNumber()) + << LOG_KV("handleWidth", m_handleWidth) + << LOG_KV("bucketSizeInBytes", m_bucketSizeInBytes) + << LOG_KV("mask", m_mask); +} + +void CM2020PSISender::constructMatrices(uint32_t _offset, uint32_t _width) +{ + if (m_taskState->taskDone()) + { + return; + } + CM2020_PSI_LOG(INFO) << LOG_BADGE("constructMatrices") << LOG_KV("offset", _offset) + << LOG_KV("width", _width) << LOG_KV("taskID", m_taskID); + + if (_offset == 0) + { + m_matrixC.reserve(_width); + m_matrixC.resize(_width); + } + + tbb::parallel_for(tbb::blocked_range(0U, _width), [&](auto const& range) { + for (auto i = range.begin(); i < range.end(); i++) + { + // construct matrix A + if (_offset == 0) + { + m_matrixC[i].reserve(m_bucketSizeInBytes); + m_matrixC[i].resize(m_bucketSizeInBytes); + } + + AESPRNG prng(m_receiverKeys[_offset + i]); + prng.generate(m_matrixC[i].data(), m_bucketSizeInBytes); + } + }); +} + +void CM2020PSISender::onMatrixColumnReceived(PPCMessageFace::Ptr _message) +{ + if (m_taskState->taskDone()) + { + return; + } + CM2020_PSI_LOG(INFO) << LOG_BADGE("onMatrixColumnReceived") << LOG_KV("taskID", m_taskID) + << LOG_KV("seq", _message->seq()); + try + { + m_channel->onMessageArrived(uint8_t(CM2020PSIMessageType::MATRIX), _message); + } + catch (const std::exception& e) + { + onSenderException("onMatrixColumnReceived", e); + } +} + +void CM2020PSISender::handleMatrixColumnReceived( + uint32_t _offset, uint32_t _col, uint32_t _round, bcos::bytesPointer _buffer) +{ + if (m_taskState->taskDone()) + { + return; + } + CM2020_PSI_LOG(DEBUG) << LOG_BADGE("handleMatrixColumnReceived") << LOG_KV("taskID", m_taskID) + << LOG_KV("offset", _offset) << LOG_KV("col", _col) + << LOG_KV("round", _round); + try + { + if (m_otChoices->get(_offset + _col)) + { + uint32_t length = _buffer->size(); + uint32_t start = _round * MAX_SEND_BUFFER_LENGTH; + for (uint32_t i = 0; i < length; i++) + { + m_matrixC[_col][start + i] ^= _buffer->at(i); + } + } + } + catch (const std::exception& e) + { + onSenderException("handleMatrixColumnReceived", e); + } +} + +void CM2020PSISender::computeOprfOutputs(uint32_t _offset, uint32_t _width) +{ + if (m_taskState->taskDone()) + { + return; + } + CM2020_PSI_LOG(INFO) << LOG_BADGE("computeOprfOutputs") << LOG_KV("offset", _offset) + << LOG_KV("width", _width) << LOG_KV("taskID", m_taskID); + try + { + tbb::parallel_for(tbb::blocked_range(0U, m_sInputSize), [&](auto const& range) { + for (auto i = range.begin(); i < range.end(); i++) + { + auto newSize = (_offset + _width + 7) / 8; + m_oprfOutputs[i].reserve(newSize); + m_oprfOutputs[i].resize(newSize); + for (uint32_t j = 0; j < _width; j++) + { + uint32_t location = (m_originLocations[i][(_offset + j) % 4] * (_offset + j) + + m_originLocations[i][4 + (_offset + j) % 4]) % + m_mask; + + m_oprfOutputs[i][(_offset + j) >> 3] |= + (uint8_t)((bool)(m_matrixC[j][location >> 3] & (1 << (location & 7)))) + << ((_offset + j) & 7); + } + } + }); + } + catch (const std::exception& e) + { + onSenderException("computeOprfOutputs", e); + } +} + +void CM2020PSISender::clearOprfMemory() +{ + CM2020_PSI_LOG(INFO) << LOG_BADGE("clearOprfMemory") << LOG_KV("taskID", m_taskID); + std::vector>().swap(m_originLocations); + std::vector().swap(m_matrixC); + MallocExtension::instance()->ReleaseFreeMemory(); +} + +void CM2020PSISender::doPsi() +{ + if (m_taskState->taskDone()) + { + return; + } + CM2020_PSI_LOG(INFO) << LOG_BADGE("doPsi") << LOG_KV("taskID", m_taskID); + + try + { + m_progress->reset(-1, nullptr); + clearOprfMemory(); + if (m_params->enableSyncResults()) + { + m_sResults = std::make_shared>(m_sInputSize, 0); + } + computeAndSendHash(); + finishPsi(); + } + catch (const std::exception& e) + { + onSenderException("doPsi", e); + } +} + +void CM2020PSISender::computeAndSendHash() +{ + if (m_taskState->taskDone()) + { + return; + } + CM2020_PSI_LOG(INFO) << LOG_BADGE("computeAndSendHash") << LOG_KV("taskID", m_taskID); + + // send 2^18 hashes per round + uint32_t sendNum = MAX_SEND_BUFFER_LENGTH / RESULT_LEN_BYTE; + uint32_t totalRound = (m_sInputSize + sendNum - 1) / sendNum; + + auto hash = m_config->hash(); + + tbb::parallel_for(tbb::blocked_range(0U, totalRound), [&](auto const& range) { + for (auto round = range.begin(); round < range.end(); round++) + { + uint32_t currentLen = + sendNum * (round + 1) > m_sInputSize ? m_sInputSize - sendNum * round : sendNum; + auto buffer = std::make_shared(currentLen * RESULT_LEN_BYTE); + uint32_t offset = round * sendNum; + for (uint32_t i = 0; i < currentLen; i++) + { + auto res = hash->hash(bcos::ref(m_oprfOutputs[offset + i])); + memcpy(buffer->data() + i * RESULT_LEN_BYTE, res.data(), RESULT_LEN_BYTE); + } + + auto message = m_config->ppcMsgFactory()->buildPPCMessage( + uint8_t(TaskType::PSI), uint8_t(TaskAlgorithmType::CM_PSI_2PC), m_taskID, buffer); + message->setMessageType(uint8_t(CM2020PSIMessageType::HASHES)); + message->setSeq(round); + + if (m_params->lowBandwidth()) + { + auto error = m_config->sendMessage(m_taskState->peerID(), message); + if (error && error->errorCode()) + { + onSenderTaskDone(std::move(error)); + } + } + else + { + m_config->front()->asyncSendMessage( + m_taskState->peerID(), message, m_config->networkTimeout(), + [self = weak_from_this()](bcos::Error::Ptr _error) { + auto sender = self.lock(); + if (!sender) + { + return; + } + if (_error && _error->errorCode()) + { + sender->onSenderTaskDone(std::move(_error)); + } + }, + nullptr); + } + } + }); + + // clear oprf outputs + std::vector>().swap(m_oprfOutputs); + MallocExtension::instance()->ReleaseFreeMemory(); +} + +void CM2020PSISender::finishPsi() +{ + if (m_taskState->taskDone()) + { + return; + } + try + { + if (m_params->enableSyncResults()) + { + auto end = std::chrono::high_resolution_clock::now(); + // costs of psi + m_costs[2] = + std::chrono::duration_cast(end - m_startTimePoint) + .count(); + + CM2020_PSI_LOG(INFO) << LOG_BADGE("waiting results") << LOG_KV("taskID", m_taskID); + } + else + { + onSenderTaskDone(nullptr); + } + } + catch (const std::exception& e) + { + onSenderException("finishPsi", e); + } +} + +void CM2020PSISender::onResultCountReceived(PPCMessageFace::Ptr _message) +{ + if (m_taskState->taskDone()) + { + return; + } + try + { + decodeUnsignedNum(m_resultCount, _message->data()); + m_resultCountReceived.exchange(true); + + CM2020_PSI_LOG(INFO) << LOG_BADGE("onResultCountReceived") << LOG_KV("taskID", m_taskID) + << LOG_KV("count", m_resultCount); + + uint32_t number = MAX_SEND_BUFFER_LENGTH / sizeof(uint32_t); + uint32_t totalRound = (m_resultCount + number - 1) / number + 1; + + if (m_progress->mark(-1) == totalRound) + { + if (m_resultCount > 0) + { + saveResults(); + } + onSenderTaskDone(nullptr); + } + } + catch (const std::exception& e) + { + onSenderException("onResultCountReceived", e); + } +} + +void CM2020PSISender::onResultReceived(PPCMessageFace::Ptr _message) +{ + if (m_taskState->taskDone()) + { + return; + } + CM2020_PSI_LOG(DEBUG) << LOG_BADGE("onResultReceived") << LOG_KV("taskID", m_taskID) + << LOG_KV("seq", _message->seq()); + try + { + auto buffer = _message->data(); + uint32_t resultNum = buffer->size() / sizeof(uint32_t); + for (uint32_t i = 0; i < resultNum; i++) + { + uint32_t index; + decodeUnsignedNum(index, buffer->data() + i * sizeof(uint32_t)); + m_sResults->at(index) = 1; + } + + if (m_resultCountReceived) + { + // receive 2^20 index per round + uint32_t number = MAX_SEND_BUFFER_LENGTH / sizeof(uint32_t); + uint32_t totalRound = (m_resultCount + number - 1) / number + 1; + + if (m_progress->mark(_message->seq()) == totalRound) + { + if (m_resultCount > 0) + { + saveResults(); + } + + onSenderTaskDone(nullptr); + } + } + else + { + m_progress->mark(_message->seq()); + } + } + catch (const std::exception& e) + { + onSenderException("onResultReceived", e); + } +} + +void CM2020PSISender::saveResults() +{ + CM2020_PSI_LOG(INFO) << LOG_BADGE("saveResults") LOG_KV("taskID", m_taskID); + try + { + if (m_ioByInterface) + { + std::vector results; + for (uint32_t index = 0; index < m_sInputSize; index++) + { + if (m_sResults->at(index)) + { + auto line = m_originInputs->getBytes(index); + results.emplace_back(std::string(line.begin(), line.end())); + } + } + m_cm2020Result->m_outputs.emplace_back(std::move(results)); + } + else + { + DataBatch::Ptr finalResults = std::make_shared(); + for (uint32_t index = 0; index < m_sInputSize; index++) + { + if (m_sResults->at(index)) + { + finalResults->append(m_originInputs->getBytes(index)); + } + } + CM2020_PSI_LOG(INFO) << LOG_BADGE("before dedup") << LOG_KV("taskID", m_taskID) + << LOG_KV("originCount", finalResults->size()); + m_resultCount = dedupDataBatch(finalResults); + CM2020_PSI_LOG(INFO) << LOG_BADGE("after dedup") << LOG_KV("taskID", m_taskID) + << LOG_KV("resultCount", m_resultCount); + m_taskState->writeLines(finalResults, DataSchema::Bytes); + } + } + catch (const std::exception& e) + { + onSenderException("saveResults", e); + } +} + +void CM2020PSISender::onSenderException(const std::string& _message, const std::exception& e) +{ + CM2020_PSI_LOG(ERROR) << LOG_BADGE(_message) << LOG_KV("taskID", m_taskID) + << LOG_KV("exception", boost::diagnostic_information(e)); + auto error = std::make_shared( + (int)CM2020PSIRetCode::ON_EXCEPTION, boost::diagnostic_information(e)); + onSenderTaskDone(error); +} + +void CM2020PSISender::onSenderTaskDone(bcos::Error::Ptr _error) +{ + if (m_taskState->taskDone() && (!_error || _error->errorCode() == 0)) + { + return; + } + + CM2020_PSI_LOG(INFO) << LOG_BADGE("onSenderTaskDone") << LOG_KV("taskID", m_taskID); + m_channelManager->removeChannelByTask(m_taskID); + + std::string message; + + if (_error) + { + message = "\nStatus: FAIL\nMessage: " + _error->errorMessage(); + m_cm2020Result->setError(std::move(_error)); + } + else + { + auto end = std::chrono::high_resolution_clock::now(); + // costs of aftermath + m_costs[3] = + std::chrono::duration_cast(end - m_startTimePoint).count(); + + uint64_t communication = + (uint64_t)m_bucketSizeInBytes * (uint64_t)m_params->bucketNumber() + + (uint64_t)m_sInputSize * (uint64_t)sizeof(u128); + + if (m_resultCount) + { + communication += (uint64_t)m_resultCount * (uint64_t)sizeof(uint32_t); + } + + communication /= (uint64_t)(1024 * 1024); + + // message = "\nStatus: SUCCESS\nOrigin Inputs Number: " + + // std::to_string(m_sInputSize) + + // "\nCounterparty Inputs Number: " + std::to_string(m_rInputSize) + + // "\nIntersections Number: " + std::to_string(m_resultCount) + + // "\nCommunication: " + std::to_string(communication) + + // "MB\nTotal Costs: " + std::to_string(m_costs[3]) + "ms\n"; + message = "\nStatus: SUCCESS\nOrigin Inputs Number: " + std::to_string(m_sInputSize) + + "\nIntersections Number: " + std::to_string(m_resultCount) + + "\nCommunication: " + std::to_string(communication) + + "MB\nTotal Costs: " + std::to_string(m_costs[3]) + "ms\n"; + + m_cm2020Result->m_enableSyncResults = m_params->enableSyncResults(); + m_cm2020Result->m_bucketNumber = m_params->bucketNumber(); + m_cm2020Result->m_communication = std::to_string(communication) + "MB"; + m_cm2020Result->m_intersections = m_resultCount; + m_cm2020Result->m_party0Size = m_rInputSize; + m_cm2020Result->m_party1Size = m_sInputSize; + } + + m_taskState->onTaskFinished(m_cm2020Result, true); + + CM2020_PSI_LOG(INFO) << LOG_BADGE("onSenderTaskDone") << LOG_KV("taskID", m_taskID) + << LOG_KV("result", message); +} diff --git a/cpp/wedpr-computing/ppc-psi/src/cm2020-psi/core/CM2020PSISender.h b/cpp/wedpr-computing/ppc-psi/src/cm2020-psi/core/CM2020PSISender.h new file mode 100644 index 00000000..71f5bb40 --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/cm2020-psi/core/CM2020PSISender.h @@ -0,0 +1,152 @@ +/** + * Copyright (C) 2022 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 CM2020PSISender.h + * @author: shawnhe + * @date 2022-12-7 + */ + +#pragma once +#include "../../psi-framework/TaskState.h" +#include "../protocol/CM2020PSIResult.h" +#include "TaskParams.h" +#include "ppc-crypto/src/randomot/SimplestOT.h" +#include "ppc-framework/task/TaskFrameworkInterface.h" +#include "ppc-front/ppc-front/PPCChannelManager.h" +#include "ppc-psi/src/cm2020-psi/CM2020PSIConfig.h" +#include "ppc-tools/src/common/Progress.h" +#include +#include + + +namespace ppc::psi +{ +class CM2020PSISender : public std::enable_shared_from_this +{ +public: + using Ptr = std::shared_ptr; + CM2020PSISender(CM2020PSIConfig::Ptr _config, TaskState::Ptr _taskState, + std::shared_ptr _ioService, crypto::SimplestOT::Ptr _ot, + std::shared_ptr _threadPool); + + ~CM2020PSISender() + { + if (m_originInputs) + { + m_originInputs->setData(std::vector()); + } + std::vector>().swap(m_originLocations); + std::vector>().swap(m_oprfOutputs); + std::vector().swap(m_matrixC); + std::shared_ptr>().swap(m_sResults); + // release the memory to os + MallocExtension::instance()->ReleaseFreeMemory(); + CM2020_PSI_LOG(INFO) << LOG_DESC("the sender destroyed") << LOG_KV("taskID", m_taskID); + } + + void asyncRunTask(); + + void onHandshakeDone(front::PPCMessageFace::Ptr _message); + + void onReceiverSizeReceived(front::PPCMessageFace::Ptr _message); + + void onPointAReceived(front::PPCMessageFace::Ptr _message); + + void onMatrixColumnReceived(front::PPCMessageFace::Ptr _message); + + void onResultCountReceived(front::PPCMessageFace::Ptr _message); + + void onResultReceived(front::PPCMessageFace::Ptr _message); + + const std::string& taskID() const { return m_taskID; } + TaskParams::Ptr params() { return m_params; } + +protected: + void runSender(); + void prepareInputs(); + void syncInputsSize(); + void preprocessInputs(); + + void doOprf(); + void initMatrixParams(); + void constructMatrices(uint32_t _offset, uint32_t _width); + + void handleMatrixColumnReceived( + uint32_t _offset, uint32_t _col, uint32_t _round, bcos::bytesPointer _buffer); + void noticeReceiverDoNextRound(); + void computeOprfOutputs(uint32_t _offset, uint32_t _width); + void clearOprfMemory(); + + void doPsi(); + void computeAndSendHash(); + + void finishPsi(); + void saveResults(); + + void onSenderException(const std::string& _module, const std::exception& e); + void onSenderTaskDone(bcos::Error::Ptr _error); + + void increaseOprfRound() { m_oprfRound++; } + + tools::Progress::Ptr progress() { return m_progress; } + tools::Progress::Ptr matrixProgress() { return m_matrixProgress; } + +private: + CM2020PSIConfig::Ptr m_config; + TaskState::Ptr m_taskState; + crypto::SimplestOT::Ptr m_ot; + + std::string m_taskID; + TaskParams::Ptr m_params; + CM2020PSIResult::Ptr m_cm2020Result; + + ppc::io::DataBatch::Ptr m_originInputs; + uint32_t m_rInputSize; + uint32_t m_sInputSize; + bool m_ioByInterface{false}; + + // width of per round processing + uint32_t m_handleWidth; + + // size of each bucket (bytes) + // the bucket size is also the height of matrix + uint32_t m_bucketSizeInBytes; + uint32_t m_mask; + + crypto::BitVector::Ptr m_otChoices; + std::vector m_receiverKeys; + + std::vector> m_originLocations; + std::vector> m_oprfOutputs; + + front::PPCChannelManager::Ptr m_channelManager; + front::Channel::Ptr m_channel; + + std::vector m_matrixC; + + std::shared_ptr> m_sResults; + std::atomic m_resultCountReceived{false}; + uint32_t m_resultCount{0}; + + uint32_t m_oprfRound{0}; + + std::chrono::time_point m_startTimePoint; + + std::vector m_costs; + + tools::Progress::Ptr m_progress; + tools::Progress::Ptr m_matrixProgress; +}; +} // namespace ppc::psi diff --git a/cpp/wedpr-computing/ppc-psi/src/cm2020-psi/core/TaskParams.h b/cpp/wedpr-computing/ppc-psi/src/cm2020-psi/core/TaskParams.h new file mode 100644 index 00000000..efa62ddb --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/cm2020-psi/core/TaskParams.h @@ -0,0 +1,95 @@ +/** + * Copyright (C) 2022 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 TaskParams.h + * @author: shawnhe + * @date 2022-12-9 + */ + +#pragma once +#include "../Common.h" +#include +#include + +namespace ppc::psi +{ +class TaskParams +{ +public: + using Ptr = std::shared_ptr; + TaskParams(std::string_view _param) + { + if (_param.empty()) + { + return; + } + + Json::Reader reader; + Json::Value result; + if (!reader.parse(_param.begin(), _param.end(), result)) + { + BOOST_THROW_EXCEPTION(BCOS_ERROR( + (int)CM2020PSIRetCode::INVALID_TASK_PARAM, "invalid task param: invalid json")); + } + if (!result.isArray()) + { + BOOST_THROW_EXCEPTION(BCOS_ERROR((int)CM2020PSIRetCode::INVALID_TASK_PARAM, + "invalid task param:: the param must be array")); + } + if (!result.empty()) + { + int enableHighPerformance = result[0].asInt(); + m_enableHighPerformance = enableHighPerformance > 0; + m_bucketNumber = HIGH_PERFORMANCE_BUCKET_NUMBER; + } + if (result.size() > 1) + { + uint16_t bucketNumber = result[1].asInt(); + if (bucketNumber >= HIGH_PERFORMANCE_BUCKET_NUMBER && bucketNumber <= MAX_BUCKET_NUMBER) + { + m_bucketNumber = bucketNumber; + } + } + } + + void setSyncResults(bool _syncResults) { m_enableSyncResults = _syncResults; } + [[nodiscard]] bool enableSyncResults() const { return m_enableSyncResults; } + + void setBucketNumber(uint16_t _bucketNumber) { m_bucketNumber = _bucketNumber; } + [[nodiscard]] uint16_t bucketNumber() const { return m_bucketNumber; } + + void setSeed(bcos::bytes _seed) { m_seed = std::move(_seed); } + [[nodiscard]] bcos::bytes const& seed() const { return m_seed; } + + void setLowBandwidth(bool _lowBandwidth) { m_lowBandwidth = _lowBandwidth; } + [[nodiscard]] bool lowBandwidth() const { return m_lowBandwidth; } + +private: + // whether the results need to be synchronized to the counterparty + bool m_enableSyncResults{false}; + + // we can also run oprf with high performance just reducing the width of matrix + // note that: it may cause oprf outputs conflict with very small probability + bool m_enableHighPerformance{false}; + + // one input will be mapped to multiple buckets + // the number of buckets is also the width of matrix + uint16_t m_bucketNumber{DEFAULT_BUCKET_NUMBER}; + + bcos::bytes m_seed; + + bool m_lowBandwidth; +}; +} // namespace ppc::psi diff --git a/cpp/wedpr-computing/ppc-psi/src/cm2020-psi/protocol/CM2020PSI.tars b/cpp/wedpr-computing/ppc-psi/src/cm2020-psi/protocol/CM2020PSI.tars new file mode 100644 index 00000000..840fb78d --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/cm2020-psi/protocol/CM2020PSI.tars @@ -0,0 +1,8 @@ +module ppctars { + struct CM2020Params { + 1 require bool enableSyncResults; + 2 require unsigned int bucketNumber; + 3 require vector seed; + 4 require bool lowBandwidth; + }; +}; diff --git a/cpp/wedpr-computing/ppc-psi/src/cm2020-psi/protocol/CM2020PSIResult.h b/cpp/wedpr-computing/ppc-psi/src/cm2020-psi/protocol/CM2020PSIResult.h new file mode 100644 index 00000000..a17934a5 --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/cm2020-psi/protocol/CM2020PSIResult.h @@ -0,0 +1,112 @@ +/** + * Copyright (C) 2022 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 CM2020PSIResult.h + * @author: shawnhe + * @date 2022-12-13 + */ +#pragma once + +#include +#include +#include +#include +#include +#include + +#include "ppc-framework/protocol/Task.h" + +namespace ppc::psi +{ +// Note: can extend on demand +class CM2020PSIResult : public protocol::TaskResult +{ +public: + using Ptr = std::shared_ptr; + CM2020PSIResult(std::string const& _taskID) : TaskResult(_taskID) {} + ~CM2020PSIResult() override = default; + + void setOutputs(std::vector>&& _outputs) + { + m_outputs = std::move(_outputs); + } + + // serialize the taskResult to json + [[nodiscard]] Json::Value serializeToJson() override + { + Json::Value response; + response["taskID"] = taskID(); + if (m_timeCost) + { + response["timeCost"] = std::to_string(m_timeCost) + "ms"; + } + if (m_fileInfo && !m_fileInfo->bizSeqNo.empty()) + { + response["bizSeqNo"] = m_fileInfo->bizSeqNo; + response["fileID"] = m_fileInfo->fileID; + response["fileMd5"] = m_fileInfo->fileMd5; + } + + if (m_error && error()->errorCode()) + { + response["code"] = error()->errorCode(); + response["message"] = error()->errorMessage(); + response["status"] = protocol::toString(protocol::TaskStatus::FAILED); + } + else + { + response["code"] = 0; + response["message"] = "success"; + response["status"] = protocol::toString(protocol::TaskStatus::COMPLETED); + + Json::Value jsonData; + jsonData["bucketNumber"] = m_bucketNumber; + jsonData["communication"] = m_communication; + jsonData["syncResult"] = m_enableSyncResults; + jsonData["intersections"] = m_intersections; + // jsonData["party0Size"] = m_party0Size; + // jsonData["party1Size"] = m_party1Size; + + if (!m_outputs.empty()) + { + Json::Value jsonOutputs; + for (auto& outputVector : m_outputs) + { + Json::Value jsonOutput; + for (auto& output : outputVector) + { + jsonOutput.append(output); + } + jsonOutputs.append(jsonOutput); + } + jsonData["outputs"] = jsonOutputs; + } + + response["data"] = jsonData; + } + return response; + } + + + std::vector> m_outputs; + uint16_t m_bucketNumber; + std::string m_communication; + bool m_enableSyncResults; + uint32_t m_intersections; + uint32_t m_party0Size; + uint32_t m_party1Size; +}; + +} // namespace ppc::psi diff --git a/cpp/wedpr-computing/ppc-psi/src/ecdh-conn-psi/CMakeLists.txt b/cpp/wedpr-computing/ppc-psi/src/ecdh-conn-psi/CMakeLists.txt new file mode 100644 index 00000000..2affec1b --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/ecdh-conn-psi/CMakeLists.txt @@ -0,0 +1,31 @@ +set(TARS_HEADER_DIR ${CMAKE_BINARY_DIR}/generated/ppc-psi/ecdh-conn-psi/tars) +find_program(TARS_TARS2CPP tars2cpp REQUIRED) + +file(GLOB_RECURSE TARS_INPUT "*.tars") + +# generate tars +if (TARS_INPUT) + foreach (TARS_FILE ${TARS_INPUT}) + get_filename_component(TARS_NAME ${TARS_FILE} NAME_WE) + get_filename_component(TARS_PATH ${TARS_FILE} PATH) + add_custom_command( + OUTPUT ${TARS_HEADER_DIR}/${TARS_NAME}.h + WORKING_DIRECTORY ${TARS_PATH} + COMMAND ${TARS_TARS2CPP} ${TARS_FILE} --unjson --without-trace --dir=${TARS_HEADER_DIR} + COMMENT "generating ${TARS_FILE} to ${TARS_HEADER_DIR}" + VERBATIM + ) + + list(APPEND OUT_TARS_H_LIST ${TARS_HEADER_DIR}/${TARS_NAME}.h) + endforeach () +endif () + +set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${OUT_TARS_H_LIST}") +include_directories(${TARS_HEADER_DIR}) + +file(GLOB_RECURSE SRCS *.cpp) +add_library(${ECDH_CONN_PSI_TARGET} ${SRCS} ${OUT_TARS_H_LIST}) +target_include_directories(${ECDH_CONN_PSI_TARGET} PUBLIC + $) + +target_link_libraries(${ECDH_CONN_PSI_TARGET} PUBLIC ${PSI_FRAMEWORK_TARGET} ${CRYPTO_TARGET} ${TOOLS_TARGET} ${PROTOBUF_TARGET} TBB::tbb) \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-psi/src/ecdh-conn-psi/Common.h b/cpp/wedpr-computing/ppc-psi/src/ecdh-conn-psi/Common.h new file mode 100644 index 00000000..0bdc1768 --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/ecdh-conn-psi/Common.h @@ -0,0 +1,84 @@ +/** + * Copyright (C) 2022 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 Common.h + * @author: zachma + * @date 2023-8-28 + */ + +#pragma once +#include "ppc-framework/Common.h" +#include + +namespace ppc::psi +{ +#define ECDH_CONN_LOG(LEVEL) BCOS_LOG(LEVEL) << LOG_BADGE("ECDH-CONN-PSI") +DERIVE_PPC_EXCEPTION(ECDHCONNException); + +enum class EcdhConnProcess : int8_t +{ + HandShakeProcess = 1, + CipherProcess = 2, + END = 3, +}; + +enum class EcdhConnSubProcess : int8_t +{ + CipherSecondProcess = 1 +}; + +const std::string VERSION_HEAD = "x-ptp-version"; +const std::string TECH_PROVIDER_CODE_HEAD = "x-ptp-tech-provider-code"; +const std::string TRACE_ID_HEAD = "x-ptp-trace-id"; +const std::string TOKEN_HEAD = "x-ptp-token"; +const std::string SESSION_ID_HEAD = "x-ptp-session-id"; +const std::string TOPIC_HEAD = "x-ptp-topic"; + +const std::string SOURCE_NODE_HEAD = "x-ptp-source-node-id"; +const std::string SOURCE_INST_HEAD = "x-ptp-source-inst-id"; +const std::string TARGET_NODE_HEAD = "x-ptp-target-node-id"; +const std::string TARGET_INST_HEAD = "x-ptp-target-inst-id"; + +inline std::ostream& operator<<(std::ostream& _out, EcdhConnProcess const& _type) +{ + switch (_type) + { + case EcdhConnProcess::HandShakeProcess: + _out << "HandShakeProcess"; + break; + case EcdhConnProcess::CipherProcess: + _out << "CipherProcess"; + break; + default: + _out << "UnknownTaskType"; + break; + } + return _out; +} + +inline std::ostream& operator<<(std::ostream& _out, EcdhConnSubProcess const& _type) +{ + switch (_type) + { + case EcdhConnSubProcess::CipherSecondProcess: + _out << "CipherSecondProcess"; + break; + default: + _out << "UnknownTaskType"; + break; + } + return _out; +} +} // namespace ppc::psi \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-psi/src/ecdh-conn-psi/EcdhConnPSIConfig.h b/cpp/wedpr-computing/ppc-psi/src/ecdh-conn-psi/EcdhConnPSIConfig.h new file mode 100644 index 00000000..75dbe36d --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/ecdh-conn-psi/EcdhConnPSIConfig.h @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2022 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 EcdhConnPSIConfig.h + * @author: zachma + * @date 2023-7-17 + */ +#pragma once +#include "../PSIConfig.h" +#include "EcdhConnPSIMessageFactory.h" +#include "ppc-framework/crypto/ECDHCrypto.h" +#include "ppc-framework/io/DataResourceLoader.h" +#include "ppc-framework/protocol/Protocol.h" +#include "ppc-tools/src/config/PPCConfig.h" +#include "protocol/src/PPCMessage.h" +#include +#include + +namespace ppc::psi +{ +class EcdhConnPSIConfig : public PSIConfig +{ +public: + using Ptr = std::shared_ptr; + EcdhConnPSIConfig(ppc::tools::PPCConfig::Ptr const& _ppcConfig, + ppc::crypto::ECDHCryptoFactory::Ptr const& _ecdhCryptoFactory, + ppc::front::FrontInterface::Ptr _front, + ppc::front::PPCMessageFaceFactory::Ptr _ppcMsgFactory, + EcdhConnPSIMessageFactory::Ptr _psiMsgFactory, + ppc::io::DataResourceLoader::Ptr const& _dataResourceLoader, + bcos::ThreadPool::Ptr _threadPool) + : PSIConfig(ppc::protocol::TaskAlgorithmType::ECDH_PSI_CONN, _ppcConfig->agencyID(), _front, + _ppcMsgFactory, _dataResourceLoader, _ppcConfig->holdingMessageMinutes(), + _ppcConfig->minNeededMemoryGB()), + m_msgFactory(_psiMsgFactory), + m_threadPool(_threadPool), + m_ecdhCryptoFactory(_ecdhCryptoFactory), + m_dataBatchSize(_ppcConfig->ecdhConnPSIConfig().dataBatchSize), + m_config(_ppcConfig) + {} + + virtual ~EcdhConnPSIConfig() = default; + + EcdhConnPSIMessageFactory::Ptr const& msgFactory() { return m_msgFactory; } + ppc::crypto::ECDHCryptoFactory::Ptr const& ecdhCryptoFactory() const + { + return m_ecdhCryptoFactory; + } + + ppc::tools::PPCConfig::Ptr const ppcConfig() { return m_config; } + bcos::ThreadPool::Ptr const& threadPool() const { return m_threadPool; } + + uint32_t dataBatchSize() const { return m_dataBatchSize; } + +private: + EcdhConnPSIMessageFactory::Ptr m_msgFactory; + bcos::ThreadPool::Ptr m_threadPool; + ppc::crypto::ECDHCryptoFactory::Ptr m_ecdhCryptoFactory; + ppc::tools::PPCConfig::Ptr m_config; + + uint32_t m_dataBatchSize = 10000; +}; +} // namespace ppc::psi \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-psi/src/ecdh-conn-psi/EcdhConnPSIFactory.h b/cpp/wedpr-computing/ppc-psi/src/ecdh-conn-psi/EcdhConnPSIFactory.h new file mode 100644 index 00000000..5b991fa7 --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/ecdh-conn-psi/EcdhConnPSIFactory.h @@ -0,0 +1,50 @@ +/** + * Copyright (C) 2022 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 EcdhConnPSIFactory.h + * @author: zachma + * @date 2023-7-18 + */ + +#pragma once +#include "EcdhConnPSIConfig.h" +#include "EcdhConnPSIImpl.h" +#include "EcdhConnPSIMessageFactory.h" +#include "ppc-framework/io/DataResourceLoader.h" +#include "ppc-tools/src/config/PPCConfig.h" +#include + +namespace ppc::psi +{ +class EcdhConnPSIFactory +{ +public: + using Ptr = std::shared_ptr; + EcdhConnPSIFactory() = default; + virtual ~EcdhConnPSIFactory() = default; + + virtual EcdhConnPSIImpl::Ptr createEcdhConnPSI(ppc::tools::PPCConfig::Ptr const& _ppcConfig, + ppc::crypto::ECDHCryptoFactory::Ptr const& _ecdhCryptoFactory, + ppc::front::FrontInterface::Ptr _front, + ppc::front::PPCMessageFaceFactory::Ptr _ppcMsgFactory, bcos::ThreadPool::Ptr _threadPool, + ppc::io::DataResourceLoader::Ptr const& _dataResourceLoader) + { + auto psiMsgFactory = std::make_shared(); + auto config = std::make_shared(_ppcConfig, _ecdhCryptoFactory, _front, + _ppcMsgFactory, psiMsgFactory, _dataResourceLoader, _threadPool); + return std::make_shared(config); + } +}; +} // namespace ppc::psi \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-psi/src/ecdh-conn-psi/EcdhConnPSIImpl.cpp b/cpp/wedpr-computing/ppc-psi/src/ecdh-conn-psi/EcdhConnPSIImpl.cpp new file mode 100644 index 00000000..6e7a3717 --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/ecdh-conn-psi/EcdhConnPSIImpl.cpp @@ -0,0 +1,312 @@ +/** + * Copyright (C) 2022 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 EcdhConnPSIImpl.cpp + * @author: zachma + * @date 2023-8-28 + */ + +#include "EcdhConnPSIImpl.h" +#include + +using namespace ppc::psi; +using namespace ppc::protocol; +using namespace ppc::front; +using namespace ppc::tools; +using namespace ppc::crypto; +using namespace ppc::io; +using namespace bcos; +using namespace ppc::task; + +EcdhConnPSIImpl::EcdhConnPSIImpl(const EcdhConnPSIConfig::Ptr& _config, unsigned _idleTimeMs) + : m_config(std::move(_config)), + m_msgPool(std::make_shared()), + TaskGuarder(_config, TaskAlgorithmType::ECDH_PSI_CONN, "ECDH-CONN-PSI-Timer"), + m_ecdhConnTaskStateFactory(std::make_shared()) +{} + +void EcdhConnPSIImpl::asyncRunTask( + ppc::protocol::Task::ConstPtr _task, ppc::task::TaskResponseCallback&& _onTaskFinished) +{ + ECDH_CONN_LOG(INFO) << LOG_DESC("Start a Conn asyncRunTask"); + auto ecdhTaskState = m_ecdhConnTaskStateFactory->createConnTaskState( + _task, std::move(_onTaskFinished), true, m_config); + auto dataResource = _task->selfParty()->dataResource(); + auto reader = loadReader(_task->id(), dataResource, DataSchema::Bytes); + ecdhTaskState->setReader(reader, -1); + auto role = _task->selfParty()->partyIndex(); + checkAndSetPeerInfo(ecdhTaskState); + // init process + triggleProcess((uint8_t)EcdhConnProcess::HandShakeProcess, -1); + // notify the taskInfo to the front + m_config->front()->notifyTaskInfo(_task->id()); + if (role == uint16_t(PartyType::Client)) + { + ECDH_CONN_LOG(INFO) << LOG_DESC("Client do the Task") << LOG_KV("taskID", _task->id()); + auto writer = loadWriter(_task->id(), dataResource, _task->enableOutputExists()); + ecdhTaskState->setWriter(writer); + auto client = std::make_shared(m_config, ecdhTaskState); + addClient(client); + client->asyncStartRunTask(_task); + } + else if (role == uint16_t(PartyType::Server)) + { + ECDH_CONN_LOG(INFO) << LOG_DESC("Server do the Task") << LOG_KV("taskID", _task->id()); + if (_task->syncResultToPeer()) + { + auto writer = loadWriter(_task->id(), dataResource, _task->enableOutputExists()); + ecdhTaskState->setWriter(writer); + } + auto server = std::make_shared(m_config, ecdhTaskState); + addServer(server); + server->asyncStartRunTask(_task); + } + else + { + auto taskResult = std::make_shared(_task->id()); + auto error = BCOS_ERROR_PTR((int)TaskParamsError, + "The party index of the ecdh-conn-psi must be client(0) or server(1)"); + ECDH_CONN_LOG(WARNING) << LOG_DESC("response task result") << LOG_KV("task", _task) + << LOG_KV("code", error->errorCode()) + << LOG_KV("msg", error->errorMessage()); + taskResult->setError(std::move(error)); + _onTaskFinished(std::move(taskResult)); + return; + } +} + +void EcdhConnPSIImpl::onReceiveMessage(ppc::front::PPCMessageFace::Ptr _msg) +{ + try + { + auto payLoad = _msg->data(); + auto psiConnMsg = m_config->msgFactory()->decodePSIConnMessage(*payLoad); + if (psiConnMsg == nullptr) + { + return; + } + psiConnMsg->setTaskID(_msg->taskID()); + auto type = typeProcess(psiConnMsg->mainProcess(), psiConnMsg->subProcess()); + m_msgPool->insert(type, psiConnMsg); + wakeupWorker(); + } + catch (std::exception const& e) + { + ECDH_CONN_LOG(WARNING) << LOG_DESC("onReceiveMessage exception") << printPPCMsg(_msg) + << LOG_KV("error", boost::diagnostic_information(e)); + } +} + + +void EcdhConnPSIImpl::start() +{ + startWorking(); +} + +void EcdhConnPSIImpl::stop() +{ + if (m_config->threadPool()) + { + m_config->threadPool()->stop(); + } + + finishWorker(); + if (isWorking()) + { + // stop the worker thread + stopWorking(); + terminate(); + } +} + +void EcdhConnPSIImpl::onReceivedErrorNotification(ppc::front::PPCMessageFace::Ptr const&) {} + +void EcdhConnPSIImpl::onSelfError( + const std::string& _taskID, bcos::Error::Ptr _error, bool _noticePeer) +{} + +void EcdhConnPSIImpl::checkAndSetPeerInfo(TaskState::Ptr const& _taskState) +{ + auto task = _taskState->task(); + // check the peer + auto peerParties = task->getAllPeerParties(); + if (peerParties.size() == 1) + { + auto peerParty = peerParties.begin()->second; + _taskState->setPeerID(peerParty->id()); + ECDH_CONN_LOG(INFO) << LOG_DESC("checkAndSetPeerInfo success"); + } +} + +void EcdhConnPSIImpl::executeWorker() +{ + // auto _msg = m_msgQueue->tryPop(c_popWaitMs); + auto _msg = m_msgPool->tryPop(process(), c_popWaitMs); + while (_msg.first && process() != typeProcess((uint8_t)EcdhConnProcess::END, -2)) + { + try + { + handlerPSIReceiveMessage(_msg.second); + _msg = m_msgPool->tryPop(process(), c_popWaitMs); + } + catch (std::exception const& e) + { + ECDH_CONN_LOG(WARNING) << LOG_DESC("executeWorker exception") + << LOG_KV("error", boost::diagnostic_information(e)); + } + waitSignal(); + } +} + +void EcdhConnPSIImpl::handlerPSIReceiveMessage(PSIConnMessage::Ptr _msg) +{ + auto self = weak_from_this(); + m_config->threadPool()->enqueue([self, _msg]() { + auto psi = self.lock(); + if (!psi) + { + return; + } + try + { + auto mainProcess = _msg->mainProcess(); + auto subProcess = _msg->subProcess(); + auto receiver = _msg->receiver(); + auto _taskId = _msg->taskID(); + if (mainProcess == int(EcdhConnProcess::HandShakeProcess) && subProcess == uint8_t(-1)) + { + if (receiver == int(PartyType::Client)) // PART2 : server -> client handshake + { + ECDH_CONN_LOG(INFO) << LOG_DESC(" PART2 : server -> client handshake ") + << LOG_KV("PartyType::Client ", _msg->value().data()); + psi->onHandShakeResponseHandler(_taskId, _msg->value()); + } + else if (receiver == int(PartyType::Server)) // PART1 : client -> server handshake + { + ECDH_CONN_LOG(INFO) << LOG_DESC(" PART1 : client -> server handshake ") + << LOG_KV("PartyType::Server ", _msg->value().data()); + psi->onHandShakeRequestHandler(_taskId, _msg->value()); + } + psi->triggleProcess((uint8_t)EcdhConnProcess::CipherProcess, -1); + } + else if (mainProcess == int(EcdhConnProcess::CipherProcess) && + subProcess == uint8_t(-1)) + { + if (receiver == int(PartyType::Client)) // PART3 : server -> client cipher + { + ECDH_CONN_LOG(INFO) << LOG_DESC(" PART3 : server -> client cipher ") + << LOG_KV("PartyType::Client ", _msg->value().data()); + psi->onCipherServerToClient(_taskId, _msg->value()); + } + else if (receiver == int(PartyType::Server)) // PART4 : client -> server cipher + { + ECDH_CONN_LOG(INFO) << LOG_DESC(" PART4 : client -> server cipher ") + << LOG_KV("PartyType::Server ", _msg->value().data()); + psi->onCipherClientToServer(_taskId, _msg->value()); + } + psi->triggleProcess((uint8_t)EcdhConnSubProcess::CipherSecondProcess, 0); + } + else if (mainProcess == int(EcdhConnSubProcess::CipherSecondProcess) && + subProcess == uint8_t(0)) + { + if (receiver == int(PartyType::Client)) // PART6 : server -> client cipher second + { + ECDH_CONN_LOG(INFO) + << LOG_DESC(" PART5 : server -> client cipher second ") + << LOG_KV("PartyType::Client ", *toHexString(_msg->value())); + psi->onSecondCipherServerToClient(_taskId, _msg->value()); + } + else if (receiver == int(PartyType::Server)) // PART5 : client -> server cipher + // second + { + ECDH_CONN_LOG(INFO) + << LOG_DESC(" PART6 : client -> server cipher second ") + << LOG_KV("PartyType::Server ", *toHexString(_msg->value())); + psi->onSecondCipherClientToServer(_taskId, _msg->value()); + } + psi->triggleProcess((uint8_t)EcdhConnProcess::END, -2); + } + } + catch (std::exception const& e) + { + ECDH_CONN_LOG(WARNING) + << LOG_DESC("handlePSIMsg exception") << LOG_KV("mainProcess", _msg->mainProcess()) + << printPSIConnMessage(_msg) << LOG_KV("error", boost::diagnostic_information(e)); + } + }); +} + +// Http PART1: client -> server : handshake request +void EcdhConnPSIImpl::onHandShakeRequestHandler(const std::string& _taskId, const bcos::bytes& _msg) +{ + auto server = findServer(_taskId); + if (server) + { + server->onHandShakeRequestHandler(_msg); + } +} + +// Http PART2: server -> client : handshake response +void EcdhConnPSIImpl::onHandShakeResponseHandler( + const std::string& _taskId, const bcos::bytes& _msg) +{ + auto client = findClient(_taskId); + if (client) + { + client->onHandShakeResponseHandler(_msg); + } +} + +// Http Part3: client -> server : cipher +void EcdhConnPSIImpl::onCipherClientToServer(const std::string& _taskId, const bcos::bytes& _msg) +{ + auto server = findServer(_taskId); + if (server) + { + server->onCipherClientToServer(_msg); + } +} + +// Http Part4: server -> client : cipher +void EcdhConnPSIImpl::onCipherServerToClient(const std::string& _taskId, const bcos::bytes& _msg) +{ + auto client = findClient(_taskId); + if (client) + { + client->onCipherServerToClient(_msg); + } +} + +// Http Part5: client -> server : cipher second +void EcdhConnPSIImpl::onSecondCipherClientToServer( + const std::string& _taskId, const bcos::bytes& _msg) +{ + auto server = findServer(_taskId); + if (server) + { + server->onSecondCipherClientToServer(_msg); + } +} + +// Http Part6: server -> client : cipher second +void EcdhConnPSIImpl::onSecondCipherServerToClient( + const std::string& _taskId, const bcos::bytes& _msg) +{ + auto client = findClient(_taskId); + if (client) + { + client->onSecondCipherServerToClient(_msg); + } +} diff --git a/cpp/wedpr-computing/ppc-psi/src/ecdh-conn-psi/EcdhConnPSIImpl.h b/cpp/wedpr-computing/ppc-psi/src/ecdh-conn-psi/EcdhConnPSIImpl.h new file mode 100644 index 00000000..bb34a6a8 --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/ecdh-conn-psi/EcdhConnPSIImpl.h @@ -0,0 +1,157 @@ +/** + * Copyright (C) 2022 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 EcdhConnPSIImpl.h + * @author: zachma + * @date 2023-7-18 + */ + +#pragma once +#include "../psi-framework/TaskGuarder.h" +#include "Common.h" +#include "EcdhConnPSIConfig.h" +#include "EcdhConnTaskState.h" +#include "core/EcdhConnPSIClient.h" +#include "core/EcdhConnPSIServer.h" +#include "ppc-framework/rpc/RpcInterface.h" +#include "ppc-framework/task/TaskFrameworkInterface.h" +#include "ppc-rpc/src/RpcFactory.h" +#include "ppc-tools/src/common/ConcurrentPool.h" +#include "protocol/src/PPCMessage.h" +#include +#include +#include + +#include +#include + +namespace ppc::psi +{ +class EcdhConnPSIImpl : public std::enable_shared_from_this, + public ppc::task::TaskFrameworkInterface, + public TaskGuarder, + public bcos::Worker +{ +public: + using Ptr = std::shared_ptr; + using EcdhConnPSIMsgPool = ppc::tools::ConcurrentPool; + using EcdhConnPSIMsgPoolPtr = std::shared_ptr; + + EcdhConnPSIImpl(const EcdhConnPSIConfig::Ptr& _config, unsigned _idleTimeMs = 0); + virtual ~EcdhConnPSIImpl() = default; + + void asyncRunTask(ppc::protocol::Task::ConstPtr _task, + ppc::task::TaskResponseCallback&& _onTaskFinished) override; + + void onReceiveMessage(ppc::front::PPCMessageFace::Ptr _message) override; + + + void start() override; + void stop() override; + + void onReceivedErrorNotification(ppc::front::PPCMessageFace::Ptr const& _message) override; + void onSelfError( + const std::string& _taskID, bcos::Error::Ptr _error, bool _noticePeer) override; + void executeWorker() override; + + void handlerPSIReceiveMessage(PSIConnMessage::Ptr _msg); + void onHandShakeRequestHandler(const std::string& _taskId, const bcos::bytes& _msg); + void onHandShakeResponseHandler(const std::string& _taskId, const bcos::bytes& _msg); + void onCipherClientToServer(const std::string& _taskId, const bcos::bytes& _msg); + void onCipherServerToClient(const std::string& _taskId, const bcos::bytes& _msg); + void onSecondCipherClientToServer(const std::string& _taskId, const bcos::bytes& _msg); + void onSecondCipherServerToClient(const std::string& _taskId, const bcos::bytes& _msg); + + void checkAndSetPeerInfo(TaskState::Ptr const& _taskState); + + void addClient(EcdhConnPSIClient::Ptr _client) + { + bcos::WriteGuard l(x_clients); + m_clients[_client->taskID()] = _client; + } + + EcdhConnPSIClient::Ptr findClient(const std::string& _taskID) + { + bcos::ReadGuard l(x_clients); + auto it = m_clients.find(_taskID); + if (it != m_clients.end()) + { + return it->second; + } + return nullptr; + } + + void addServer(EcdhConnPSIServer::Ptr _server) + { + bcos::WriteGuard l(x_servers); + m_servers[_server->taskID()] = _server; + } + + EcdhConnPSIServer::Ptr findServer(const std::string& _taskID) + { + bcos::ReadGuard l(x_servers); + auto it = m_servers.find(_taskID); + if (it != m_servers.end()) + { + return it->second; + } + return nullptr; + } + + void triggleProcess(uint8_t _mainProcess, uint8_t _subProcess) + { + bcos::WriteGuard l(x_process); + m_process = typeProcess(_mainProcess, _subProcess); + } + + uint16_t process() + { + bcos::ReadGuard l(x_process); + return m_process; + } + + uint16_t typeProcess(uint8_t _mainProcess, uint8_t _subProcess) + { + return (_subProcess << 8) | _mainProcess; + } + +private: + void waitSignal() + { + boost::unique_lock l(x_signal); + m_signal.wait_for(l, boost::chrono::milliseconds(5)); + } + + void wakeupWorker() { m_signal.notify_all(); } + + const int c_popWaitMs = 5; + uint16_t m_process; + mutable bcos::SharedMutex x_process; + + EcdhConnTaskStateFactory::Ptr m_ecdhConnTaskStateFactory; + EcdhConnPSIConfig::Ptr m_config; + EcdhConnTaskState::Ptr m_ecdhTaskState; + EcdhConnPSIMsgPoolPtr m_msgPool; + + boost::condition_variable m_signal; + boost::mutex x_signal; + + std::unordered_map m_clients; + mutable bcos::SharedMutex x_clients; + + std::unordered_map m_servers; + mutable bcos::SharedMutex x_servers; +}; +} // namespace ppc::psi \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-psi/src/ecdh-conn-psi/EcdhConnPSIMessageFactory.h b/cpp/wedpr-computing/ppc-psi/src/ecdh-conn-psi/EcdhConnPSIMessageFactory.h new file mode 100644 index 00000000..fd9123c8 --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/ecdh-conn-psi/EcdhConnPSIMessageFactory.h @@ -0,0 +1,109 @@ +/* + * 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 EcdhConnPSIMessageFactory.h + * @author: zachma + * @date 2023-8-23 + */ + +#pragma once +#include "Common.h" +#include "protocol/PSIConnMessage.h" +#include "protocol/transport.pb.h" + +namespace ppc::psi +{ +class EcdhConnPSIMessageFactory +{ +public: + using Ptr = std::shared_ptr; + EcdhConnPSIMessageFactory() = default; + ~EcdhConnPSIMessageFactory() = default; + + PSIConnMessage::Ptr decodePSIConnMessage(bcos::bytes _data) + { + std::string _msgStr = ""; + _msgStr.assign(_data.begin(), _data.end()); + + // parse PushRequest + org::interconnection::link::PushRequest* pushRequest = + new org::interconnection::link::PushRequest(); + pushRequest->ParseFromString(_msgStr); + auto key = pushRequest->key(); + int sender = 0; + int mainProcess = 0; + int subProcess = -1; + int receiver = 0; + if (parseKey(key, &sender, &receiver, &mainProcess, &subProcess)) + { + auto value = pushRequest->value(); + + ECDH_CONN_LOG(INFO) << LOG_DESC("decodePSIConnMessage start") + << LOG_KV("sender", sender) << LOG_KV("receiver", receiver) + << LOG_KV("mainProcess", mainProcess) + << LOG_KV("subProcess", subProcess) + << LOG_KV("value: ", value.size()); + auto _psiConn = std::make_shared(key); + _psiConn->setValue(bcos::bytes(value.begin(), value.end())); + _psiConn->setSender(sender); + _psiConn->setReceiver(receiver); + _psiConn->setMainProcess(mainProcess); + _psiConn->setSubProcess(subProcess); + return _psiConn; + } + + return nullptr; + } + +protected: + // main: root:P2P-1:1->0{'\x01', '\x02'}[1] + // sub: root-0:P2P-1:1->0{'\x01', '\x02'}[1] + bool parseKey( + const std::string& _key, int* _from, int* _to, int* _mainProcess, int* _subProcess) + { + if (NULL == _to || NULL == _mainProcess || NULL == _subProcess || NULL == _from) + { + return false; + } + + std::vector fieldNames; + boost::split(fieldNames, _key, boost::is_any_of(":")); + if (fieldNames.size() < 3) + { + return false; + } + // root-0 + std::string _sub_process_p2p = fieldNames.at(0); + *_subProcess = _sub_process_p2p.back() - 48; + if (*_subProcess < 0 || *_subProcess > 9) + { + *_subProcess = -1; + } + // P2P-1 + std::string _process_p2p = fieldNames.at(1); + *_mainProcess = _process_p2p.back() - 48; + + // 1->0{'\x01', '\x02'}[1] + std::string _to_p2p = fieldNames.at(2); + std::vector fieldNames2; + boost::split(fieldNames2, _to_p2p, boost::is_any_of(std::string{'\x01', '\x02'})); + // *_to = fieldNames2.at(0).back() - 48; + // *_from = fieldNames2.at(0).front() - 48; + *_to = 49 - fieldNames2.at(0).back(); + *_from = 49 - fieldNames2.at(0).front(); + return true; + } +}; +} // namespace ppc::psi \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-psi/src/ecdh-conn-psi/EcdhConnTaskState.h b/cpp/wedpr-computing/ppc-psi/src/ecdh-conn-psi/EcdhConnTaskState.h new file mode 100644 index 00000000..01ee4303 --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/ecdh-conn-psi/EcdhConnTaskState.h @@ -0,0 +1,87 @@ +/* + * 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 EcdhConnTaskState.h + * @author: zachma + * @date 2023-7-20 + */ + +#pragma once +#include "../psi-framework/TaskState.h" +#include "ppc-framework/crypto/CryptoBox.h" +#include "ppc-framework/crypto/ECDHCrypto.h" + +namespace ppc::psi +{ +class EcdhConnTaskState : public TaskState +{ +public: + using Ptr = std::shared_ptr; + EcdhConnTaskState(ppc::protocol::Task::ConstPtr const& _task, + ppc::task::TaskResponseCallback&& _callback, bool _onlySelfRun = false) + : TaskState(_task, std::move(_callback), _onlySelfRun) + {} + ~EcdhConnTaskState() = default; + + ppc::crypto::CryptoBox::Ptr cryptoBox() const + { + // bcos::ReadGuard l(x_cryptoBox); + return m_cryptoBox; + } + + void setCryptoBox(ppc::crypto::CryptoBox::Ptr const& _cryptoBox) + { + // bcos::WriteGuard l(x_cryptoBox); + m_cryptoBox = _cryptoBox; + } + + // return copy here to ensure thread-safe + ppc::crypto::ECDHCrypto::Ptr ecdhCrypto() const + { + // bcos::ReadGuard l(x_ecdhCrypto); + return m_ecdhCrypto; + } + // Note: here must lock, in-case of multiple tasks with the same task-id processed at almost the + // same time + void setEcdhCrypto(ppc::crypto::ECDHCrypto::Ptr const& _ecdhCrypto) + { + // bcos::WriteGuard l(x_ecdhCrypto); + m_ecdhCrypto = _ecdhCrypto; + } + +private: + ppc::crypto::ECDHCrypto::Ptr m_ecdhCrypto; + // mutable bcos::SharedMutex x_ecdhCrypto; + + ppc::crypto::CryptoBox::Ptr m_cryptoBox; + // mutable bcos::SharedMutex x_cryptoBox; +}; + +class EcdhConnTaskStateFactory : public TaskStateFactory +{ +public: + using Ptr = std::shared_ptr; + EcdhConnTaskStateFactory() : TaskStateFactory() {} + ~EcdhConnTaskStateFactory() override = default; + + EcdhConnTaskState::Ptr createConnTaskState(ppc::protocol::Task::ConstPtr const& _task, + ppc::task::TaskResponseCallback&& _callback, bool _onlySelfRun = false, + PSIConfig::Ptr _config = nullptr) + { + return std::make_shared(_task, std::move(_callback), false); + } +}; + +} // namespace ppc::psi \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-psi/src/ecdh-conn-psi/core/EcdhConnPSIClient.cpp b/cpp/wedpr-computing/ppc-psi/src/ecdh-conn-psi/core/EcdhConnPSIClient.cpp new file mode 100644 index 00000000..7c21878c --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/ecdh-conn-psi/core/EcdhConnPSIClient.cpp @@ -0,0 +1,325 @@ +/** + * Copyright (C) 2022 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 EcdhConnPSIClient.cpp + * @author: zachma + * @date 2023-7-18 + */ +#include "EcdhConnPSIClient.h" +#include "ppc-framework/protocol/Protocol.h" +#include + +using namespace ppc::psi; +using namespace ppc::io; +using namespace ppc::protocol; +using namespace ppc::front; +using namespace bcos; + +EcdhConnPSIClient::EcdhConnPSIClient( + EcdhConnPSIConfig::Ptr _config, EcdhConnTaskState::Ptr _taskState) + : m_config(_config), m_taskState(_taskState), m_send_count(0) +{ + auto task = m_taskState->task(); + m_taskID = task->id(); + m_msgFactory = std::make_shared(); +} + +void EcdhConnPSIClient::asyncStartRunTask(ppc::protocol::Task::ConstPtr _task) +{ + ECDH_CONN_LOG(INFO) << LOG_DESC("asyncStartRunTask: ") << printTaskInfo(_task); + m_header = initHeader(_task->id()); + sendHandshakeRequest(m_taskState); +} + +void EcdhConnPSIClient::onSecondCipherServerToClient(const bcos::bytes& _msg) +{ + // 接收Server发来的M_Q2 + auto cipherExVo = m_msgFactory->parseCipherExchange(_msg); + m_Q2 = cipherExVo->cipherText(); + + auto intersectionVec = tryIntersection(m_Q2, m_P2_Client); + m_taskState->storePSIResult(m_config->dataResourceLoader(), intersectionVec); + + // 把m_P2_Client发送到Server + // create CipherExchange + auto cipherBatchVo = std::make_shared("dual.enc", 1, true); + cipherBatchVo->setCount(m_P2_Client.size()); + cipherBatchVo->setCipherText(m_P2_Client); + auto cipherBytes = m_msgFactory->createCipherExchange(cipherBatchVo); + auto requestBytes = m_msgFactory->createPSIConnMessageRequest( + cipherBytes, generateKey((int)EcdhConnSubProcess::CipherSecondProcess, 0)); + + auto message = m_config->ppcMsgFactory()->buildPPCMessage(m_taskState->task()->type(), + m_taskState->task()->algorithm(), m_taskID, std::make_shared(requestBytes)); + message->setSender(m_taskState->task()->selfParty()->id()); + message->setHeader(m_header); + m_config->front()->asyncSendMessage( + m_taskState->peerID(), message, m_config->networkTimeout(), + [this, self = weak_from_this()](bcos::Error::Ptr _error) { + auto psi = self.lock(); + if (!psi) + { + return; + } + if (!_error) + { + m_taskState->onTaskFinished(); + return; + } + }, + nullptr); +} + +void EcdhConnPSIClient::onCipherServerToClient(const bcos::bytes& _msg) +{ + // parse EcdhPsiCipherBatch to vector + auto cipherExVo = m_msgFactory->parseCipherExchange(_msg); + m_P1_Client = cipherExVo->cipherText(); + ECDH_CONN_LOG(INFO) << LOG_DESC("onCipherServerToClient: ") + << LOG_KV("m_P1_Client SIZE: ", m_P1_Client.size()); + + computeAndEncryptSetSecond(m_P1_Client, std::make_shared(m_randomA)); + + + auto cipherBatchVo = std::make_shared("enc", 0, true); + + cipherBatchVo->setCount(m_Q1.size()); + cipherBatchVo->setCipherText(m_Q1); + auto cipherBytes = m_msgFactory->createCipherExchange(cipherBatchVo); + auto requestBytes = m_msgFactory->createPSIConnMessageRequest( + cipherBytes, generateKey((int)EcdhConnProcess::CipherProcess, -1)); + + + auto message = m_config->ppcMsgFactory()->buildPPCMessage(m_taskState->task()->type(), + m_taskState->task()->algorithm(), m_taskID, std::make_shared(requestBytes)); + message->setSender(m_taskState->task()->selfParty()->id()); + message->setHeader(m_header); + + m_config->front()->asyncSendMessage( + m_taskState->peerID(), message, m_config->networkTimeout(), + [this, self = weak_from_this()](bcos::Error::Ptr _error) { + auto psi = self.lock(); + if (!psi) + { + return; + } + if (!_error) + { + return; + } + }, + nullptr); +} + +void EcdhConnPSIClient::onHandShakeResponseHandler(const bcos::bytes& _msg) +{ + ECDH_CONN_LOG(INFO) << LOG_DESC("onHandShakeResponseHandler start"); + auto handShakeResponseVo = m_msgFactory->parseHandshakeResponse(_msg); + auto errCode = handShakeResponseVo->GetErrorCode(); + auto errMsg = handShakeResponseVo->GetErrorMsg(); + + if (errCode) + { + auto errorMsg = "onHandShakeResponseHandler failed for no errCode/errMsg selected"; + ECDH_CONN_LOG(WARNING) << LOG_DESC(errorMsg) << LOG_KV("errCode", errCode) + << LOG_KV("errMsg", errMsg); + auto result = std::make_shared(m_taskState->task()->id()); + auto error = BCOS_ERROR_PTR((int)PSIRetCode::HandshakeFailed, errorMsg); + result->setError(std::move(error)); + m_taskState->onTaskFinished(result, false); + return; + } + + auto curve = handShakeResponseVo->GetCurve(); + auto hashType = handShakeResponseVo->GetHash(); +#ifdef ENABLE_CONN + auto cryptoBox = m_config->ecdhCryptoFactory()->createCryptoBox( + (int)ppc::protocol::ECCCurve::SM2, (int)ppc::protocol::HashImplName::SHA256); +#else + auto cryptoBox = + m_config->ecdhCryptoFactory()->createCryptoBox((int8_t)curve, (int8_t)hashType); +#endif + m_taskState->setCryptoBox(cryptoBox); + ECDH_CONN_LOG(INFO) << LOG_DESC("onHandShakeResponseHandler success"); + // CREATE RANDOM + m_randomA = m_taskState->cryptoBox()->eccCrypto()->generateRandomScalar(); + computeAndEncryptSet(std::make_shared(m_randomA)); +} + +void EcdhConnPSIClient::computeAndEncryptSet(bcos::bytesPointer _randA) +{ + auto inputSize = m_originInputs->size(); + if (!m_originInputs || inputSize == 0) + { + ECDH_CONN_LOG(ERROR) << LOG_DESC("Client computeAndEncryptSet") + << LOG_DESC("data size is empty!"); + auto result = std::make_shared(m_taskState->task()->id()); + auto err = std::make_shared(-12222, "canceled by other peer"); + result->setError(std::move(err)); + m_taskState->onTaskFinished(result, false); + } + std::vector _res_vectors; + auto hash = m_taskState->cryptoBox()->hashImpl(); + for (int i = 0; i < inputSize; i++) + { + auto data = m_originInputs->getBytes(i); + auto hashData = hash->hash(bcos::bytesConstRef(data.data(), data.size())); + auto point = m_taskState->cryptoBox()->eccCrypto()->hashToCurve(hashData); + auto hashSet = m_taskState->cryptoBox()->eccCrypto()->ecMultiply(point, *_randA); + _res_vectors.push_back(hashSet); + } + + m_Q1 = _res_vectors; + ECDH_CONN_LOG(INFO) << LOG_DESC("computeAndEncryptSet success") + << LOG_KV("m_Q1 size: ", m_Q1.size()); +} + +void EcdhConnPSIClient::computeAndEncryptSetSecond( + const std::vector& _input, bcos::bytesPointer _randA) +{ + std::vector _res_vectors; + auto inputSize = _input.size(); + for (int i = 0; i < inputSize; i++) + { + auto inputData = _input.at(i); + auto encryptSet = m_taskState->cryptoBox()->eccCrypto()->ecMultiply(inputData, *_randA); + _res_vectors.push_back(encryptSet); + } + + ECDH_CONN_LOG(INFO) << LOG_DESC("onCipherServerToClient: computeAndEncryptSetSecond: ") + << LOG_KV("m_P1_Client SIZE: ", m_P2_Client.size()); + + m_P2_Client = _res_vectors; +} + + +void EcdhConnPSIClient::sendHandshakeRequest(TaskState::Ptr _taskState) +{ + if (_taskState->peerID().empty()) + { + return; + } + ECDH_CONN_LOG(TRACE) << LOG_DESC("sendHandshakeRequest start"); + m_originInputs = _taskState->loadAllData(); + auto item_count = m_originInputs->size(); + auto ecdhConnPSIConfig = m_config->ppcConfig(); + auto handReqVo = std::make_shared(); + std::set _curve{(int32_t)ECCCurve::P256}; + std::set _hash{(int32_t)HashImplName::SHA256}; + handReqVo->SetCurve(_curve); + handReqVo->SetHash(_hash); + handReqVo->SetItemCount(item_count); + auto handshakeBytes = m_msgFactory->createHandshakeRequest(handReqVo); + auto key = generateKey((int)EcdhConnProcess::HandShakeProcess, -1); + auto requestBytes = m_msgFactory->createPSIConnMessageRequest(handshakeBytes, key); + + auto message = m_config->ppcMsgFactory()->buildPPCMessage(_taskState->task()->type(), + _taskState->task()->algorithm(), m_taskID, std::make_shared(requestBytes)); + message->setSender(_taskState->task()->selfParty()->id()); + message->setHeader(m_header); + m_config->front()->asyncSendMessage( + m_taskState->peerID(), message, m_config->networkTimeout(), + [self = weak_from_this()](bcos::Error::Ptr _error) { + if (!_error) + { + return; + } + auto psi = self.lock(); + if (!psi) + { + return; + } + }, + nullptr); +} + +// input1 ∩ input2 -> +std::vector EcdhConnPSIClient::tryIntersection(const std::vector& _input1, + const std::vector& _input2, int _compareSuffixBitSize) +{ + std::vector input1; + for (auto const& _in : _input1) + { + bcos::bytes::const_iterator head = _in.begin() + _in.size() - _compareSuffixBitSize; + bcos::bytes input_temp(head, _in.end()); + input1.push_back(input_temp); + ECDH_CONN_LOG(TRACE) << LOG_KV("input_temp VALUE:", *toHexString(input_temp)) + << LOG_KV("input_temp size:", input_temp.size()); + } + + std::vector input2; + for (auto const& _in : _input2) + { + bcos::bytes::const_iterator head = _in.begin() + _in.size() - _compareSuffixBitSize; + bcos::bytes input_temp(head, _in.end()); + input2.push_back(input_temp); + ECDH_CONN_LOG(TRACE) << LOG_KV("input_temp VALUE:", *toHexString(input_temp)) + << LOG_KV("input_temp size:", input_temp.size()); + } + + int index = 0; + std::set result_set; + for (auto const& _in : input1) + { + if (std::find(input2.begin(), input2.end(), _in) != input2.end()) + { + result_set.insert(m_originInputs->getBytes(index)); + } + index++; + } + std::vector vec; + vec.assign(result_set.begin(), result_set.end()); + return vec; +} + +std::string EcdhConnPSIClient::generateKey(int _mainProcess, int _subProcess) +{ + m_send_count++; + std::string keys = ""; + if (_subProcess == -1) + { + // main process + keys = "root:P2P-" + std::to_string(_mainProcess) + ":" + + std::to_string(1 - (int)PartyType::Client) + "->" + + std::to_string(1 - (int)PartyType::Server) + std::string{'\x01', '\x02'} + + std::to_string(m_send_count); + } + else + { + keys = "root-" + std::to_string(_subProcess) + ":P2P-" + std::to_string(_mainProcess) + + ":" + std::to_string(1 - (int)PartyType::Client) + "->" + + std::to_string(1 - (int)PartyType::Server) + std::string{'\x01', '\x02'} + + std::to_string(m_send_count); + } + return keys; +} + +std::map EcdhConnPSIClient::initHeader(const std::string& _taskId) +{ + std::map header; + header[SESSION_ID_HEAD] = _taskId; + header[VERSION_HEAD] = "v1.0"; + header[TRACE_ID_HEAD] = "trace_" + _taskId; + header[TOKEN_HEAD] = "token_" + _taskId; + + header[SOURCE_NODE_HEAD] = "HOST"; + header[TARGET_NODE_HEAD] = "GUEST"; + header[SOURCE_INST_HEAD] = "HOST"; + header[TARGET_INST_HEAD] = "GUEST"; + header[TECH_PROVIDER_CODE_HEAD] = "WEBANK"; + header[TOPIC_HEAD] = "host.0-guest.0"; + + return header; +} \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-psi/src/ecdh-conn-psi/core/EcdhConnPSIClient.h b/cpp/wedpr-computing/ppc-psi/src/ecdh-conn-psi/core/EcdhConnPSIClient.h new file mode 100644 index 00000000..35b40fef --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/ecdh-conn-psi/core/EcdhConnPSIClient.h @@ -0,0 +1,76 @@ +/** + * Copyright (C) 2022 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 EcdhConnPSIClient.h + * @author: zachma + * @date 2023-7-18 + */ + +#pragma once +#include "../../psi-framework/TaskState.h" +#include "../EcdhConnPSIConfig.h" +#include "../EcdhConnTaskState.h" +#include "../protocol/PSIConnMessageFactory.h" +#include +#include + +namespace ppc::psi +{ +class EcdhConnPSIClient : public std::enable_shared_from_this +{ +public: + using Ptr = std::shared_ptr; + EcdhConnPSIClient(EcdhConnPSIConfig::Ptr _config, EcdhConnTaskState::Ptr _taskState); + virtual ~EcdhConnPSIClient() = default; + const std::string& taskID() const { return m_taskID; } + + + virtual void asyncStartRunTask(ppc::protocol::Task::ConstPtr _task); + + virtual void sendHandshakeRequest(TaskState::Ptr _taskState); + virtual void onSecondCipherServerToClient(const bcos::bytes& _msg); + virtual void onCipherServerToClient(const bcos::bytes& _msg); + virtual void onHandShakeResponseHandler(const bcos::bytes& _msg); + +protected: + virtual void computeAndEncryptSet(bcos::bytesPointer _randA); + virtual void computeAndEncryptSetSecond( + const std::vector& _input, bcos::bytesPointer _randA); + virtual std::vector tryIntersection(const std::vector& _input1, + const std::vector& _input2, int _compareSuffixBitSize = 12); + +private: + int m_send_count = 0; + ppc::io::DataBatch::Ptr m_originInputs; + PSIConnMessageFactory::Ptr m_connMsgFactory; + EcdhConnPSIConfig::Ptr m_config; + std::string m_taskID; + EcdhConnTaskState::Ptr m_taskState; + PSIConnMessageFactory::Ptr m_msgFactory; + + std::map m_header; + // 保存最终结果 + bcos::bytes m_randomA; + + std::vector m_Q2; + std::vector m_Q1; + std::vector m_P2_Client; + std::vector m_P1_Client; + +private: + virtual std::map initHeader(const std::string& _taskId); + virtual std::string generateKey(int _mainProcess, int _subProcess); +}; +} // namespace ppc::psi diff --git a/cpp/wedpr-computing/ppc-psi/src/ecdh-conn-psi/core/EcdhConnPSIServer.cpp b/cpp/wedpr-computing/ppc-psi/src/ecdh-conn-psi/core/EcdhConnPSIServer.cpp new file mode 100644 index 00000000..d615cdc5 --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/ecdh-conn-psi/core/EcdhConnPSIServer.cpp @@ -0,0 +1,349 @@ +/** + * Copyright (C) 2022 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 EcdhConnPSIServer.cpp + * @author: zachma + * @date 2023-7-18 + */ +#include "EcdhConnPSIServer.h" +#include "ppc-framework/protocol/GlobalConfig.h" +#include + +using namespace ppc::psi; +using namespace ppc::io; +using namespace ppc::protocol; +using namespace ppc::front; +using namespace ppc::crypto; +using namespace bcos; + +EcdhConnPSIServer::EcdhConnPSIServer( + EcdhConnPSIConfig::Ptr _config, EcdhConnTaskState::Ptr _taskState) + : m_config(_config), m_taskState(_taskState) +{ + auto task = m_taskState->task(); + m_taskID = task->id(); + m_msgFactory = std::make_shared(); +} + +void EcdhConnPSIServer::asyncStartRunTask(ppc::protocol::Task::ConstPtr _task) +{ + ECDH_CONN_LOG(INFO) << LOG_DESC("asyncStartRunTask: ") << printTaskInfo(_task); + m_header = initHeader(_task->id()); +} + + +void EcdhConnPSIServer::onHandShakeRequestHandler(const bcos::bytes& _msg) +{ + auto handRequestVo = m_msgFactory->parseHandshakeRequest(_msg); + auto clientCurves = handRequestVo->GetCurve(); + auto clientHashList = handRequestVo->GetHash(); + auto supportedCurves = g_PPCConfig.supportedCurves( + (uint8_t)TaskType::PSI, (uint8_t)TaskAlgorithmType::ECDH_PSI_2PC); + auto supportedHashList = g_PPCConfig.supportedHashList( + (uint8_t)TaskType::PSI, (uint8_t)TaskAlgorithmType::ECDH_PSI_2PC); + std::set localCurves(supportedCurves.begin(), supportedCurves.end()); + std::set localHashTypes(supportedHashList.begin(), supportedHashList.end()); + bool curveSelected = false; + bool hashTypeSelected = false; + // sm-crypto enabled + auto handShakeResponse = std::make_shared(); + if (g_PPCConfig.smCrypto()) + { + // try to select SM2 + if (clientCurves.count((int32_t)ppc::protocol::ECCCurve::SM2) && + localCurves.count((int32_t)ppc::protocol::ECCCurve::SM2)) + { + handShakeResponse->SetCurve((int32_t)ppc::protocol::ECCCurve::SM2); + curveSelected = true; + } + // try to select SM3 + if (clientHashList.count((int32_t)ppc::protocol::HashImplName::SM3) && + localHashTypes.count((int32_t)ppc::protocol::HashImplName::SM3)) + { + handShakeResponse->SetHash((int32_t)ppc::protocol::HashImplName::SM3); + hashTypeSelected = true; + } + } + + if (!curveSelected) + { +#ifdef ENABLE_CONN + handShakeResponse->SetCurve((int32_t)ppc::protocol::ECCCurve::SM2); +#else + handShakeResponse->SetCurve(selectCryptoAlgorithm(clientCurves, localCurves)); +#endif + } + if (!hashTypeSelected) + { +#ifdef ENABLE_CONN + handShakeResponse->SetHash((int32_t)ppc::protocol::HashImplName::SHA256); +#else + handShakeResponse->SetHash(selectCryptoAlgorithm(clientHashList, localHashTypes)); +#endif + } + + auto SelectedCurve = handShakeResponse->GetCurve(); + auto SelectedHashType = handShakeResponse->GetHash(); + if (SelectedCurve != int32_t(-1) && SelectedHashType != int32_t(-1)) + { + auto cryptoBox = + m_config->ecdhCryptoFactory()->createCryptoBox(SelectedCurve, SelectedHashType); + m_taskState->setCryptoBox(cryptoBox); + m_randomB = m_taskState->cryptoBox()->eccCrypto()->generateRandomScalar(); + } + else + { + auto errorMsg = "onHandshakeRequest failed for no curve/hashType selected"; + ECDH_CONN_LOG(WARNING) << LOG_DESC(errorMsg) << LOG_KV("selectedCurve", SelectedCurve) + << LOG_KV("selectedHashType", SelectedHashType); + auto result = std::make_shared(m_taskID); + auto error = BCOS_ERROR_PTR((int)PSIRetCode::HandshakeFailed, errorMsg); + result->setError(std::move(error)); + m_taskState->onTaskFinished(result, false); + return; + } + + // send message to response + auto handshakeResponseBytes = m_msgFactory->createHandshakeResponse(handShakeResponse); + auto requestBytes = m_msgFactory->createPSIConnMessageRequest( + handshakeResponseBytes, generateKey((int)EcdhConnProcess::HandShakeProcess, -1)); + + auto message = m_config->ppcMsgFactory()->buildPPCMessage(m_taskState->task()->type(), + m_taskState->task()->algorithm(), m_taskID, std::make_shared(requestBytes)); + message->setSender(m_taskState->task()->selfParty()->id()); + message->setHeader(m_header); + m_config->front()->asyncSendMessage( + m_taskState->peerID(), message, m_config->networkTimeout(), + [this, self = weak_from_this()](bcos::Error::Ptr _error) { + auto psi = self.lock(); + if (!psi) + { + return; + } + if (!_error) + { + psi->computeAndEncryptSet(std::make_shared(m_randomB)); + } + }, + nullptr); +} +void EcdhConnPSIServer::onCipherClientToServer(const bcos::bytes& _msg) +{ + auto cipherExVo = m_msgFactory->parseCipherExchange(_msg); + m_Q1_server = cipherExVo->cipherText(); + // 收到Q1 计算 Q2 + computeAndEncryptSetSecond(m_Q1_server, std::make_shared(m_randomB)); +} +void EcdhConnPSIServer::onSecondCipherClientToServer(const bcos::bytes& _msg) +{ + // 接收client发来的m_P2 + auto cipherExPb = m_msgFactory->parseCipherExchange(_msg); + m_P2 = cipherExPb->cipherText(); + auto intersectionVec = tryIntersection(m_P2, m_Q2_server); + bool synced = m_taskState->task()->syncResultToPeer(); + if (synced) + { + m_taskState->storePSIResult(m_config->dataResourceLoader(), intersectionVec); + } + m_taskState->onTaskFinished(); +} + +void EcdhConnPSIServer::computeAndEncryptSet(bcos::bytesPointer _randB) +{ + m_originInputs = m_taskState->loadAllData(); + if (!m_originInputs || m_originInputs->size() == 0) + { + ECDH_CONN_LOG(INFO) << LOG_DESC("Server computeAndEncryptSet") + << LOG_DESC("data size is empty!"); + auto result = std::make_shared(m_taskState->task()->id()); + auto err = std::make_shared(-12222, "canceled by other peer"); + result->setError(std::move(err)); + m_taskState->onTaskFinished(result, false); + } + auto inputSize = m_originInputs->size(); + std::vector _res_vectors; + auto hash = m_taskState->cryptoBox()->hashImpl(); + for (int i = 0; i < inputSize; i++) + { + auto data = m_originInputs->getBytes(i); + auto hashData = hash->hash(bcos::bytesConstRef(data.data(), data.size())); + auto point = m_taskState->cryptoBox()->eccCrypto()->hashToCurve(hashData); + auto hashSet = m_taskState->cryptoBox()->eccCrypto()->ecMultiply(point, *_randB); + _res_vectors.push_back(hashSet); + } + + m_P1 = _res_vectors; + + auto cipherBatchVo = std::make_shared("enc", 0, true); + cipherBatchVo->setCount(m_P1.size()); + cipherBatchVo->setCipherText(m_P1); + auto cipherBytes = m_msgFactory->createCipherExchange(cipherBatchVo); + auto requestBytes = m_msgFactory->createPSIConnMessageRequest( + cipherBytes, generateKey((int)EcdhConnProcess::CipherProcess, -1)); + + auto message = m_config->ppcMsgFactory()->buildPPCMessage(m_taskState->task()->type(), + m_taskState->task()->algorithm(), m_taskID, std::make_shared(requestBytes)); + message->setSender(m_taskState->task()->selfParty()->id()); + message->setHeader(m_header); + // shake hands with each other + m_config->front()->asyncSendMessage( + m_taskState->peerID(), message, m_config->networkTimeout(), + [this, self = weak_from_this()](bcos::Error::Ptr _error) { + auto psi = self.lock(); + if (!psi) + { + return; + } + if (!_error) + { + return; + } + }, + nullptr); +} + +void EcdhConnPSIServer::computeAndEncryptSetSecond( + const std::vector& _input, bcos::bytesPointer _randB) +{ + std::vector _res_vectors; + auto inputSize = _input.size(); + for (int i = 0; i < inputSize; i++) + { + auto inputData = _input.at(i); + auto encryptSet = m_taskState->cryptoBox()->eccCrypto()->ecMultiply(inputData, *_randB); + _res_vectors.push_back(encryptSet); + } + m_Q2_server = _res_vectors; + + auto cipherBatchVo = std::make_shared("dual.enc", 1, true); + cipherBatchVo->setCount(m_Q2_server.size()); + cipherBatchVo->setCipherText(m_Q2_server); + auto cipherBytes = m_msgFactory->createCipherExchange(cipherBatchVo); + auto requestBytes = m_msgFactory->createPSIConnMessageRequest( + cipherBytes, generateKey((int)EcdhConnSubProcess::CipherSecondProcess, 0)); + + auto message = m_config->ppcMsgFactory()->buildPPCMessage(m_taskState->task()->type(), + m_taskState->task()->algorithm(), m_taskID, std::make_shared(requestBytes)); + message->setSender(m_taskState->task()->selfParty()->id()); + message->setHeader(m_header); + + m_config->front()->asyncSendMessage( + m_taskState->peerID(), message, m_config->networkTimeout(), + [this, self = weak_from_this()](bcos::Error::Ptr _error) { + auto psi = self.lock(); + if (!psi) + { + return; + } + if (!_error) + { + return; + } + }, + nullptr); +} + +// input1 ∩ input2 -> +std::vector EcdhConnPSIServer::tryIntersection(const std::vector& _input1, + const std::vector& _input2, int _compareSuffixBitSize) +{ + std::vector input1; + for (auto const& _in : _input1) + { + bcos::bytes::const_iterator head = _in.begin() + _in.size() - _compareSuffixBitSize; + bcos::bytes input_temp(head, _in.end()); + input1.push_back(input_temp); + ECDH_CONN_LOG(TRACE) << LOG_KV("input_temp VALUE:", *toHexString(input_temp)) + << LOG_KV("input_temp size:", input_temp.size()); + } + + std::vector input2; + for (auto const& _in : _input2) + { + bcos::bytes::const_iterator head = _in.begin() + _in.size() - _compareSuffixBitSize; + bcos::bytes input_temp(head, _in.end()); + input2.push_back(input_temp); + ECDH_CONN_LOG(TRACE) << LOG_KV("input_temp VALUE:", *toHexString(input_temp)) + << LOG_KV("input_temp size:", input_temp.size()); + } + + int index = 0; + std::set result_set; + for (auto const& _in : input1) + { + if (std::find(input2.begin(), input2.end(), _in) != input2.end()) + { + result_set.insert(m_originInputs->getBytes(index)); + } + index++; + } + std::vector vec; + vec.assign(result_set.begin(), result_set.end()); + return vec; +} + +std::string EcdhConnPSIServer::generateKey(int _mainProcess, int _subProcess) +{ + m_send_count++; + std::string keys = ""; + if (_subProcess == -1) + { + // main process + keys = "root:P2P-" + std::to_string(_mainProcess) + ":" + + std::to_string(1 - (int)PartyType::Server) + "->" + + std::to_string(1 - (int)PartyType::Client) + std::string{'\x01', '\x02'} + + std::to_string(m_send_count); + } + else + { + keys = "root-" + std::to_string(_subProcess) + ":P2P-" + std::to_string(_mainProcess) + + ":" + std::to_string(1 - (int)PartyType::Server) + "->" + + std::to_string(1 - (int)PartyType::Client) + std::string{'\x01', '\x02'} + + std::to_string(m_send_count); + } + return keys; +} + +int32_t EcdhConnPSIServer::selectCryptoAlgorithm( + std::set _clientSupportedAlgorithms, std::set _localSupportedAlgorithms) +{ + for (auto const& algorithm : _clientSupportedAlgorithms) + { + if (_localSupportedAlgorithms.count(algorithm)) + { + return algorithm; + } + } + // Note: -1 means select algorithm failed + return int32_t(-1); +} + +std::map EcdhConnPSIServer::initHeader(const std::string& _taskId) +{ + std::map header; + header[SESSION_ID_HEAD] = _taskId; + header[VERSION_HEAD] = "v1.0"; + header[TRACE_ID_HEAD] = "trace_" + _taskId; + header[TOKEN_HEAD] = "token_" + _taskId; + + header[SOURCE_NODE_HEAD] = "GUEST"; + header[TARGET_NODE_HEAD] = "HOST"; + header[SOURCE_INST_HEAD] = "GUEST"; + header[TARGET_INST_HEAD] = "HOST"; + header[TECH_PROVIDER_CODE_HEAD] = "WEBANK"; + header[TOPIC_HEAD] = "host.0-guest.0"; + + return header; +} \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-psi/src/ecdh-conn-psi/core/EcdhConnPSIServer.h b/cpp/wedpr-computing/ppc-psi/src/ecdh-conn-psi/core/EcdhConnPSIServer.h new file mode 100644 index 00000000..cbc6de12 --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/ecdh-conn-psi/core/EcdhConnPSIServer.h @@ -0,0 +1,77 @@ +/** + * Copyright (C) 2022 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 EcdhConnPSIServer.h + * @author: zachma + * @date 2023-7-18 + */ + +#pragma once +#include "../../psi-framework/TaskState.h" +#include "../EcdhConnPSIConfig.h" +#include "../EcdhConnTaskState.h" +#include "../protocol/PSIConnMessageFactory.h" +#include +#include + +namespace ppc::psi +{ +class EcdhConnPSIServer : public std::enable_shared_from_this +{ +public: + using Ptr = std::shared_ptr; + EcdhConnPSIServer(EcdhConnPSIConfig::Ptr _config, EcdhConnTaskState::Ptr _taskState); + virtual ~EcdhConnPSIServer() = default; + const std::string& taskID() const { return m_taskID; } + + virtual void asyncStartRunTask(ppc::protocol::Task::ConstPtr _task); + + virtual void onHandShakeRequestHandler(const bcos::bytes& _msg); + virtual void onCipherClientToServer(const bcos::bytes& _msg); + virtual void onSecondCipherClientToServer(const bcos::bytes& _msg); + +protected: + virtual void computeAndEncryptSet(bcos::bytesPointer _randB); + virtual void computeAndEncryptSetSecond( + const std::vector& _input, bcos::bytesPointer _randB); + virtual std::vector tryIntersection(const std::vector& _input1, + const std::vector& _input2, int _compareSuffixBitSize = 12); + virtual int32_t selectCryptoAlgorithm( + std::set _clientSupportedAlgorithms, std::set _localSupportedAlgorithms); + +private: + int m_send_count = 0; + bcos::bytes m_randomB; + ppc::io::DataBatch::Ptr m_originInputs; + EcdhConnPSIConfig::Ptr m_config; + std::string m_taskID; + EcdhConnTaskState::Ptr m_taskState; + PSIConnMessageFactory::Ptr m_msgFactory; + + std::map m_header; + + + // 保存最终结果 + std::vector m_Q1_server; + std::vector m_Q2_server; + + std::vector m_P2; + std::vector m_P1; + +private: + virtual std::string generateKey(int _mainProcess, int _subProcess); + virtual std::map initHeader(const std::string& _taskId); +}; +} // namespace ppc::psi diff --git a/cpp/wedpr-computing/ppc-psi/src/ecdh-conn-psi/protocol/PSIConnMessage.h b/cpp/wedpr-computing/ppc-psi/src/ecdh-conn-psi/protocol/PSIConnMessage.h new file mode 100644 index 00000000..bef1b62c --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/ecdh-conn-psi/protocol/PSIConnMessage.h @@ -0,0 +1,202 @@ +/* + * 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 PSIConnMessage.h + * @author: zachma + * @date 2023-8-23 + */ +#pragma once +#include "ppc-framework/io/DataBatch.h" +#include +#include + +namespace ppc::psi +{ +class PSIConnMessage +{ +public: + using Ptr = std::shared_ptr; + PSIConnMessage(const std::string& _key) : m_key(_key){}; + ~PSIConnMessage() = default; + + // the key + std::string const& key() const { return m_key; } + void setKey(const std::string& _key) { m_key = _key; } + + // the value + bcos::bytes value() { return m_value; } + void setValue(bcos::bytes _value) { m_value = _value; } + + // the packetType + uint8_t packetType() { return m_packetType; } + void setPacketType(uint8_t _packetType) { m_packetType = _packetType; } + + // the sender + uint16_t sender() { return m_sender; } + void setSender(uint16_t _sender) { m_sender = _sender; } + + // the receiver + uint16_t receiver() { return m_receiver; } + void setReceiver(uint16_t _receiver) { m_receiver = _receiver; } + + // the MainProcess + uint8_t mainProcess() { return m_mainProcess; } + void setMainProcess(uint8_t _mainProcess) { m_mainProcess = _mainProcess; } + + // the SubProcess + uint8_t subProcess() { return m_subProcess; } + void setSubProcess(uint8_t _subProcess) { m_subProcess = _subProcess; } + + // the TaskId + std::string const& taskID() const { return m_taskId; } + void setTaskID(const std::string& _taskId) { m_taskId = _taskId; } + +private: + std::string m_key; + std::string m_taskId; + bcos::bytes m_value; + uint8_t m_packetType; + uint16_t m_sender; + uint16_t m_receiver; + uint8_t m_subProcess; + uint8_t m_mainProcess; +}; + +class HandShakeRequestVo +{ +public: + using Ptr = std::shared_ptr; + HandShakeRequestVo() = default; + HandShakeRequestVo(std::set curve, std::set hash, int32_t protocol_families, + int32_t item_count) + : m_curve(curve), + m_hash(hash), + m_protocol_families(protocol_families), + m_item_count(item_count) + {} + + ~HandShakeRequestVo() = default; + void SetCurve(const std::set& curve) { m_curve = curve; } + + void SetHash(const std::set& hash) { m_hash = hash; } + + void SetProtocolFamilies(int32_t protocol_families) { m_protocol_families = protocol_families; } + + void SetItemCount(int32_t item_count) { m_item_count = item_count; } + + std::set GetCurve() const { return m_curve; } + + std::set GetHash() const { return m_hash; } + + int32_t GetProtocolFamilies() const { return m_protocol_families; } + + int32_t GetItemCount() const { return m_item_count; } + +private: + std::set m_curve; + std::set m_hash; + int32_t m_protocol_families; + int32_t m_item_count; +}; + +class HandShakeResponseVo +{ +public: + using Ptr = std::shared_ptr; + HandShakeResponseVo() = default; + HandShakeResponseVo(int32_t protocol_families, int32_t curve, int32_t hash) + : m_protocol_families(protocol_families), m_curve(curve), m_hash(hash) + {} + + virtual ~HandShakeResponseVo() = default; + + void SetCurve(int32_t curve) { m_curve = curve; } + + void SetHash(int32_t hash) { m_hash = hash; } + + void SetProtocolFamilies(int32_t protocol_families) { m_protocol_families = protocol_families; } + + void SetErrorCode(int32_t error_code) { m_error_code = error_code; } + + void SetErrorMessage(const std::string& msg) { m_error_msg = msg; } + + int32_t GetCurve() const { return m_curve; } + + int32_t GetHash() const { return m_hash; } + + int32_t GetProtocolFamilies() const { return m_protocol_families; } + + int32_t GetErrorCode() const { return m_error_code; } + + std::string GetErrorMsg() const { return m_error_msg; } + +private: + int32_t m_curve; + int32_t m_hash; + int32_t m_protocol_families; + int32_t m_error_code; + std::string m_error_msg; +}; + +class CipherBatchVo +{ +public: + using Ptr = std::shared_ptr; + CipherBatchVo() = default; + CipherBatchVo(std::string _type, int32_t _batch_index, bool _is_last_batch) + : m_type(_type), m_batch_index(_batch_index), m_is_last_batch(_is_last_batch) + {} + virtual ~CipherBatchVo() = default; + + void setType(const std::string& _type) { m_type = _type; } + + void setBatchIndex(int32_t _batch_index) { m_batch_index = _batch_index; } + + void setIsLastBatch(bool _is_last_batch) { m_is_last_batch = _is_last_batch; } + + void setCount(int32_t _count) { m_count = _count; } + + void setCipherText(const std::vector& _cipherText) { m_ciphertext = _cipherText; } + + std::string type() const { return m_type; } + + int32_t batch_index() const { return m_batch_index; } + + bool is_last_batch() const { return m_is_last_batch; } + + int32_t count() const { return m_count; } + + std::vector cipherText() const { return m_ciphertext; } + +private: + std::string m_type; + int32_t m_batch_index; + bool m_is_last_batch; + int32_t m_count; + std::vector m_ciphertext; +}; + + +inline std::string printPSIConnMessage(PSIConnMessage::Ptr _msg) +{ + std::ostringstream stringstream; + stringstream << LOG_KV("sender", _msg->sender()) << LOG_KV("key", _msg->key()) + << LOG_KV("receive", _msg->receiver()) << LOG_KV("taskId", _msg->taskID()) + << LOG_KV("message type", _msg->packetType()) + << LOG_KV("main process", _msg->mainProcess()) + << LOG_KV("sub process", _msg->subProcess()); + return stringstream.str(); +} +} // namespace ppc::psi \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-psi/src/ecdh-conn-psi/protocol/PSIConnMessageFactory.cpp b/cpp/wedpr-computing/ppc-psi/src/ecdh-conn-psi/protocol/PSIConnMessageFactory.cpp new file mode 100644 index 00000000..783cd4fb --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/ecdh-conn-psi/protocol/PSIConnMessageFactory.cpp @@ -0,0 +1,253 @@ +/* + * 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 PSIConnMessageFactory.cpp + * @author: zachma + * @date 2023-8-23 + */ + +#pragma once +#include "PSIConnMessageFactory.h" +#include "ecc.pb.h" +#include "ecdh_psi.pb.h" +#include "entry.pb.h" +#include "header.pb.h" +#include "psi.pb.h" +#include "transport.pb.h" +#include + +using namespace ppc::psi; + +bcos::bytes PSIConnMessageFactory::createHandshakeRequest( + HandShakeRequestVo::Ptr handShakeRequestVo) +{ + org::interconnection::v2::HandshakeRequest handShakeRequest; + handShakeRequest.set_version(2); + handShakeRequest.set_requester_rank((int32_t)EcdhConnProcess::HandShakeProcess); + handShakeRequest.add_supported_algos(org::interconnection::v2::AlgoType::ALGO_TYPE_ECDH_PSI); + handShakeRequest.add_protocol_families( + org::interconnection::v2::ProtocolFamily::PROTOCOL_FAMILY_ECC); + + // create eccProtocol + org::interconnection::v2::protocol::EccProtocolProposal eccProtocol; + eccProtocol.add_supported_versions(2); + eccProtocol.add_point_octet_formats( + org::interconnection::v2::protocol::PointOctetFormat::POINT_OCTET_FORMAT_X962_COMPRESSED); + eccProtocol.set_support_point_truncation(false); + + // create eccSuit + org::interconnection::v2::protocol::EcSuit* eccSuit = eccProtocol.add_ec_suits(); + auto _curve = handShakeRequestVo->GetCurve().cbegin(); + auto _hash = handShakeRequestVo->GetHash().cbegin(); + +#ifdef ENABLE_CONN + eccSuit->set_curve(2); // SM2 + eccSuit->set_hash(11); // SHA256 +#else + eccSuit->set_curve(*_curve); + eccSuit->set_hash(*_hash); +#endif + + eccSuit->set_hash2curve_strategy(org::interconnection::v2::protocol::HashToCurveStrategy:: + HASH_TO_CURVE_STRATEGY_TRY_AND_REHASH); + + // google::protobuf::Any protocol_families_params_any; + handShakeRequest.add_protocol_family_params()->PackFrom(eccProtocol); + + // create PsiDataIoProposal + org::interconnection::v2::algos::PsiDataIoProposal psiDataIo; + psiDataIo.add_supported_versions(2); + psiDataIo.set_result_to_rank(-1); + psiDataIo.set_item_num(handShakeRequestVo->GetItemCount()); + + handShakeRequest.mutable_io_param()->PackFrom(psiDataIo); + bcos::bytes result; + result.resize(handShakeRequest.ByteSize()); + handShakeRequest.SerializeToArray(result.data(), handShakeRequest.ByteSize()); + return result; +} + +HandShakeRequestVo::Ptr PSIConnMessageFactory::parseHandshakeRequest(const bcos::bytes& _value) +{ + std::string msgStr = ""; + msgStr.assign(_value.begin(), _value.end()); + + // parse HandshakeRequest + org::interconnection::v2::HandshakeRequest handShakeRequest; + handShakeRequest.ParseFromString(msgStr); + + auto supported_algos = handShakeRequest.supported_algos(0); + auto protocol_families = handShakeRequest.protocol_families(0); + auto protocol_family_params = handShakeRequest.protocol_family_params(0); + std::set curves; + std::set hashes; + int32_t item_num = -1; + if (protocol_family_params.Is()) + { + org::interconnection::v2::protocol::EccProtocolProposal eccProtocol; + protocol_family_params.UnpackTo(&eccProtocol); + auto ecc_suits = eccProtocol.ec_suits(); + for (auto const& suit : ecc_suits) + { + curves.insert(suit.curve()); + hashes.insert(suit.hash()); + } + } + + auto io_param = handShakeRequest.io_param(); + if (io_param.Is()) + { + org::interconnection::v2::algos::PsiDataIoProposal psiDataIo; + io_param.UnpackTo(&psiDataIo); + item_num = psiDataIo.item_num(); + } + + return std::make_shared(curves, hashes, protocol_families, item_num); +} + +bcos::bytes PSIConnMessageFactory::createHandshakeResponse( + HandShakeResponseVo::Ptr _handShakeResponseVo) +{ + std::string result; + + // create response header + org::interconnection::ResponseHeader* responseHeader = + new org::interconnection::ResponseHeader(); + responseHeader->set_error_code(_handShakeResponseVo->GetErrorCode()); + responseHeader->set_allocated_error_msg(new std::string(_handShakeResponseVo->GetErrorMsg())); + + // create handShakeResponse + org::interconnection::v2::HandshakeResponse handShakeResponse; + handShakeResponse.set_allocated_header(responseHeader); + handShakeResponse.set_algo(org::interconnection::v2::AlgoType::ALGO_TYPE_ECDH_PSI); + handShakeResponse.add_protocol_families( + org::interconnection::v2::ProtocolFamily::PROTOCOL_FAMILY_ECC); + + // create eccSuit + org::interconnection::v2::protocol::EcSuit* eccSuit = + new org::interconnection::v2::protocol::EcSuit(); + eccSuit->set_curve(_handShakeResponseVo->GetCurve()); + eccSuit->set_hash(_handShakeResponseVo->GetHash()); + eccSuit->set_hash2curve_strategy(3); + + // create EccProtocolResult + org::interconnection::v2::protocol::EccProtocolResult eccProtocol; + eccProtocol.set_version(1); + eccProtocol.set_point_octet_format(1); + eccProtocol.set_bit_length_after_truncated(-1); + eccProtocol.set_allocated_ec_suit(eccSuit); + + google::protobuf::Any protocol_families_params_any; + protocol_families_params_any.PackFrom(eccProtocol); + handShakeResponse.add_protocol_family_params()->CopyFrom(protocol_families_params_any); + + // create PsiDataIoResult + org::interconnection::v2::algos::PsiDataIoResult psiDataIo; + psiDataIo.set_version(1); + psiDataIo.set_result_to_rank(-1); + + + google::protobuf::Any* io_param_any = new google::protobuf::Any(); + io_param_any->PackFrom(psiDataIo); + handShakeResponse.set_allocated_io_param(io_param_any); + + handShakeResponse.SerializeToString(&result); + return bcos::bytes(result.begin(), result.end()); +} + +HandShakeResponseVo::Ptr PSIConnMessageFactory::parseHandshakeResponse(const bcos::bytes& _value) +{ + std::string msgStr = ""; + msgStr.assign(_value.begin(), _value.end()); + + org::interconnection::v2::HandshakeResponse handShakeResponse; + handShakeResponse.ParseFromString(msgStr); + + auto responseHeader = handShakeResponse.header(); + + auto errCode = responseHeader.error_code(); + auto errMsg = responseHeader.error_msg(); + auto algo = handShakeResponse.algo(); + auto protocol_families = handShakeResponse.protocol_families(0); + auto protocol_family_params = handShakeResponse.protocol_family_params(0); + int32_t curve; + int32_t hashtype; + if (protocol_family_params.Is()) + { + org::interconnection::v2::protocol::EccProtocolResult eccProtocol; + protocol_family_params.UnpackTo(&eccProtocol); + auto ecc_suit = eccProtocol.ec_suit(); + curve = ecc_suit.curve(); + hashtype = ecc_suit.hash(); + } + auto handRespVo = std::make_shared(); + handRespVo->SetCurve(curve); + handRespVo->SetHash(hashtype); + handRespVo->SetErrorCode(errCode); + handRespVo->SetErrorMessage(errMsg); + handRespVo->SetProtocolFamilies(protocol_families); + + return handRespVo; +} + +bcos::bytes PSIConnMessageFactory::createCipherExchange(CipherBatchVo::Ptr _cipherBatchVo) +{ + org::interconnection::v2::runtime::EcdhPsiCipherBatch ecdhPsiCipherBatch; + ecdhPsiCipherBatch.set_allocated_type(new std::string(_cipherBatchVo->type())); + ecdhPsiCipherBatch.set_is_last_batch(_cipherBatchVo->is_last_batch()); + ecdhPsiCipherBatch.set_batch_index(_cipherBatchVo->batch_index()); + ecdhPsiCipherBatch.set_count(_cipherBatchVo->count()); + ecdhPsiCipherBatch.set_allocated_ciphertext( + new std::string(encodeVectorBytesToString(_cipherBatchVo->cipherText()))); + + std::string result; + ecdhPsiCipherBatch.SerializeToString(&result); + + return bcos::bytes(result.begin(), result.end()); +} + +CipherBatchVo::Ptr PSIConnMessageFactory::parseCipherExchange(const bcos::bytes& _value) +{ + std::string msgStr = ""; + msgStr.assign(_value.begin(), _value.end()); + + org::interconnection::v2::runtime::EcdhPsiCipherBatch ecdhPsiCipherBatch; + ecdhPsiCipherBatch.ParseFromString(msgStr); + + auto cipherBatchVo = std::make_shared(); + cipherBatchVo->setType(ecdhPsiCipherBatch.type()); + cipherBatchVo->setBatchIndex(ecdhPsiCipherBatch.batch_index()); + cipherBatchVo->setIsLastBatch(ecdhPsiCipherBatch.is_last_batch()); + cipherBatchVo->setCount(ecdhPsiCipherBatch.count()); + cipherBatchVo->setCipherText( + decodeStringToVectorBytes(ecdhPsiCipherBatch.ciphertext(), ecdhPsiCipherBatch.count())); + return cipherBatchVo; +} + +bcos::bytes PSIConnMessageFactory::createPSIConnMessageRequest( + const bcos::bytes& _value, const std::string& _key) +{ + org::interconnection::link::PushRequest pushRequest; + pushRequest.set_sender_rank(1); + pushRequest.set_key(_key); + pushRequest.set_trans_type(org::interconnection::link::TransType::MONO); + pushRequest.set_value(_value.data(), _value.size()); + + bcos::bytes result; + result.resize(pushRequest.ByteSize()); + pushRequest.SerializeToArray(result.data(), pushRequest.ByteSize()); + + return result; +} \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-psi/src/ecdh-conn-psi/protocol/PSIConnMessageFactory.h b/cpp/wedpr-computing/ppc-psi/src/ecdh-conn-psi/protocol/PSIConnMessageFactory.h new file mode 100644 index 00000000..91718051 --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/ecdh-conn-psi/protocol/PSIConnMessageFactory.h @@ -0,0 +1,78 @@ +/* + * 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 PSIConnMessageFactory.h + * @author: zachma + * @date 2023-8-23 + */ + +#pragma once +#include "../Common.h" +#include "PSIConnMessage.h" +#include "ppc-framework/Common.h" + +namespace ppc::psi +{ +#define ECDH_CONN_PB_LOG(LEVEL) BCOS_LOG(LEVEL) << LOG_BADGE("ECDH-CONN-PSI-PB") +class PSIConnMessageFactory +{ +public: + using Ptr = std::shared_ptr; + PSIConnMessageFactory() = default; + virtual ~PSIConnMessageFactory() = default; + + bcos::bytes createHandshakeRequest(HandShakeRequestVo::Ptr handShakeRequestVo); + HandShakeRequestVo::Ptr parseHandshakeRequest(const bcos::bytes& _value); + + bcos::bytes createHandshakeResponse(HandShakeResponseVo::Ptr _handShakeResponseVo); + HandShakeResponseVo::Ptr parseHandshakeResponse(const bcos::bytes& _value); + + bcos::bytes createCipherExchange(CipherBatchVo::Ptr _cipherBatchVo); + CipherBatchVo::Ptr parseCipherExchange(const bcos::bytes& _value); + + bcos::bytes createPSIConnMessageRequest(const bcos::bytes& _value, const std::string& _key); + +protected: + std::string encodeVectorBytesToString(const std::vector& _cipherBytes) + { + std::string _temp = ""; + for (auto const& _cipher_byte : _cipherBytes) + { + _temp += std::string(_cipher_byte.begin(), _cipher_byte.end()); + } + return _temp; + } + + std::vector decodeStringToVectorBytes(const std::string& _cipherStr, int count) + { + std::vector result; + if (count == 0 || _cipherStr == "") + { + return result; + } + auto _size = _cipherStr.length(); + auto batch = _size / count; + int start = 0; + for (int i = 0; i < count; i++) + { + std::string temp = _cipherStr.substr(start, batch); + bcos::bytes temp_bytes(temp.begin(), temp.end()); + result.push_back(temp_bytes); + start += batch; + } + return result; + } +}; +} // namespace ppc::psi \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-psi/src/ecdh-multi-psi/CMakeLists.txt b/cpp/wedpr-computing/ppc-psi/src/ecdh-multi-psi/CMakeLists.txt new file mode 100644 index 00000000..a1097acd --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/ecdh-multi-psi/CMakeLists.txt @@ -0,0 +1,31 @@ +set(TARS_HEADER_DIR ${CMAKE_BINARY_DIR}/generated/ppc-psi/ecdh-multi-psi/tars) +find_program(TARS_TARS2CPP tars2cpp REQUIRED) + +file(GLOB_RECURSE TARS_INPUT "*.tars") + +# generate tars +if (TARS_INPUT) + foreach (TARS_FILE ${TARS_INPUT}) + get_filename_component(TARS_NAME ${TARS_FILE} NAME_WE) + get_filename_component(TARS_PATH ${TARS_FILE} PATH) + add_custom_command( + OUTPUT ${TARS_HEADER_DIR}/${TARS_NAME}.h + WORKING_DIRECTORY ${TARS_PATH} + COMMAND ${TARS_TARS2CPP} ${TARS_FILE} --unjson --without-trace --dir=${TARS_HEADER_DIR} + COMMENT "generating ${TARS_FILE} to ${TARS_HEADER_DIR}" + VERBATIM + ) + + list(APPEND OUT_TARS_H_LIST ${TARS_HEADER_DIR}/${TARS_NAME}.h) + endforeach () +endif () + +set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${OUT_TARS_H_LIST}") +include_directories(${TARS_HEADER_DIR}) + +file(GLOB_RECURSE SRCS *.cpp) +add_library(${ECDH_MULTI_PSI_TARGET} ${SRCS} ${OUT_TARS_H_LIST}) +target_include_directories(${ECDH_MULTI_PSI_TARGET} PUBLIC + $) + +target_link_libraries(${ECDH_MULTI_PSI_TARGET} PUBLIC ${PSI_FRAMEWORK_TARGET} ${CRYPTO_TARGET} TBB::tbb) \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-psi/src/ecdh-multi-psi/Common.h b/cpp/wedpr-computing/ppc-psi/src/ecdh-multi-psi/Common.h new file mode 100644 index 00000000..1654f33b --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/ecdh-multi-psi/Common.h @@ -0,0 +1,23 @@ +#pragma once +#include "ppc-framework/Common.h" +#include + +namespace ppc::psi +{ +#define ECDH_MULTI_LOG(LEVEL) BCOS_LOG(LEVEL) << LOG_BADGE("ECDH-MULTI-PSI") +#define ECDH_MASTER_LOG(LEVEL) BCOS_LOG(LEVEL) << LOG_BADGE("ECDH-MULTI-PSI-MASTER") +#define ECDH_PARTNER_LOG(LEVEL) BCOS_LOG(LEVEL) << LOG_BADGE("ECDH-MULTI-PSI-PARTNER") +#define ECDH_CAL_LOG(LEVEL) BCOS_LOG(LEVEL) << LOG_BADGE("ECDH-MULTI-PSI-CALCULATOR") + +DERIVE_PPC_EXCEPTION(ECDHMULTIException); +enum class EcdhMultiPSIMessageType : uint8_t +{ + GENERATE_RANDOM_TO_PARTNER = 0x01, + SEND_ENCRYPTED_SET_TO_MASTER_FROM_CALCULATOR = 0x02, + SEND_ENCRYPTED_SET_TO_MASTER_FROM_PARTNER = 0x03, + SEND_ENCRYPTED_SET_TO_CALCULATOR = 0x04, + SEND_ENCRYPTED_INTERSECTION_SET_TO_CALCULATOR = 0x05, + RETURN_ENCRYPTED_INTERSECTION_SET_FROM_CALCULATOR_TO_MASTER = 0x06, + SYNC_FINAL_RESULT_TO_ALL = 0x07, +}; +} // namespace ppc::psi diff --git a/cpp/wedpr-computing/ppc-psi/src/ecdh-multi-psi/EcdhMultiCache.cpp b/cpp/wedpr-computing/ppc-psi/src/ecdh-multi-psi/EcdhMultiCache.cpp new file mode 100644 index 00000000..52c4e083 --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/ecdh-multi-psi/EcdhMultiCache.cpp @@ -0,0 +1,511 @@ +/* + * Copyright (C) 2022 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 EcdhCache.h + * @author: zachma + * @date 2023-5-28 + */ +#include "EcdhMultiCache.h" +#include +#include + +using namespace ppc::psi; +using namespace ppc::protocol; +using namespace bcos; + +void MasterCache::addCalculatorCipher(std::string _peerId, std::vector&& _cipherData, + std::vector const& dataIndex, uint32_t seq, uint32_t dataBatchCount) +{ + auto peerIndex = getPeerIndex(_peerId); + if (peerIndex == -1) + { + ECDH_MULTI_LOG(WARNING) << LOG_DESC("Invalid calculator") << LOG_KV("peer", _peerId); + return; + } + bcos::Guard l(m_mutex); + m_calculatorCipherSeqs.insert(seq); + if (dataBatchCount) + { + m_calculatorDataBatchCount = dataBatchCount; + } + uint64_t i = 0; + for (auto&& it : _cipherData) + { + updateMasterDataRef(peerIndex, std::move(it), dataIndex[i]); + i++; + } + // try to merge the + if (m_calculatorDataBatchCount > 0 && + m_calculatorCipherSeqs.size() == m_calculatorDataBatchCount) + { + ECDH_MULTI_LOG(INFO) << LOG_DESC("The master receive all cipher data from the calculator") + << LOG_KV("seq", seq) << LOG_KV("calculator", _peerId) + << LOG_KV("masterData", m_masterDataRef.size()) << printCacheState(); + m_finishedPartners.insert(_peerId); + // try to merge + mergeMasterCipher(_peerId, peerIndex); + } + ECDH_MULTI_LOG(INFO) << LOG_DESC( + "addCalculatorCipher: master receive cipher data from calculator") + << LOG_KV("calculator", _peerId) << printCacheState() << LOG_KV("seq", seq) + << LOG_KV("receivedSize", _cipherData.size()) + << LOG_KV("masterData", m_masterDataRef.size()) + << LOG_KV("dataBatchCount", m_calculatorDataBatchCount); + // release the cipherData + _cipherData.clear(); + std::vector().swap(_cipherData); + MallocExtension::instance()->ReleaseFreeMemory(); +} + +void MasterCache::updateMasterDataRef( + unsigned short _peerIndex, bcos::bytes&& data, int32_t dataIndex) +{ + // not merged case + if (!m_peerMerged) + { + // new data case + if (!m_masterDataRef.count(data)) + { + MasterCipherRef ref; + ref.refInfo |= (1 << _peerIndex); + ref.updateDataIndex(dataIndex); + m_masterDataRef.insert(std::make_pair(std::move(data), ref)); + return; + } + // existed data case + m_masterDataRef[data].refInfo |= (1 << _peerIndex); + m_masterDataRef[data].updateDataIndex(dataIndex); + return; + } + + // merged case, only record the intersection case, increase the refCount + if (m_masterDataRef.count(data)) + { + m_masterDataRef[data].refCount += 1; + m_masterDataRef[data].updateDataIndex(dataIndex); + } +} + + +void MasterCache::addPartnerCipher(std::string _peerId, std::vector&& _cipherData, + uint32_t seq, uint32_t parternerDataCount) +{ + auto peerIndex = getPeerIndex(_peerId); + if (peerIndex == -1) + { + ECDH_MULTI_LOG(WARNING) << LOG_DESC("Invalid peerId") << LOG_KV("peer", _peerId); + return; + } + bcos::Guard lock(m_mutex); + // record the data-ref-count + for (auto&& data : _cipherData) + { + updateMasterDataRef(peerIndex, std::move(data), -1); + } + m_partnerCipherSeqs[_peerId].insert(seq); + ECDH_MULTI_LOG(INFO) << LOG_DESC("addPartnerCipher") << LOG_KV("partner", _peerId) + << LOG_KV("seq", seq) + << LOG_KV("receivedBatch", m_partnerCipherSeqs.at(_peerId).size()) + << LOG_KV("cipherDataSize", _cipherData.size()) + << LOG_KV("masterDataSize", m_masterDataRef.size()) + << LOG_KV("parternerDataCount", parternerDataCount) << printCacheState(); + _cipherData.clear(); + std::vector().swap(_cipherData); + MallocExtension::instance()->ReleaseFreeMemory(); + if (parternerDataCount > 0) + { + m_parternerDataCount.insert(std::make_pair(_peerId, parternerDataCount)); + } + if (!m_parternerDataCount.count(_peerId)) + { + return; + } + auto expectedCount = m_parternerDataCount.at(_peerId); + if (m_partnerCipherSeqs[_peerId].size() == expectedCount) + { + m_finishedPartners.insert(_peerId); + // merge when find the send-finished peer + mergeMasterCipher(_peerId, peerIndex); + } +} + +void MasterCache::mergeMasterCipher(std::string const& peerId, unsigned short peerIndex) +{ + if (m_peerMerged) + { + return; + } + // no need to merge when partnerCount is 1 + if (m_peerCount == 1) + { + return; + } + ECDH_MULTI_LOG(INFO) << LOG_DESC("Receive whole data from peer, mergeMasterCipher") + << LOG_KV("distinct-masterDataSize-before-merge", m_masterDataRef.size()) + << LOG_KV("finishedPeer", peerId) << LOG_KV("partnerCount", m_peerCount); + auto startT = utcSteadyTime(); + for (auto it = m_masterDataRef.begin(); it != m_masterDataRef.end();) + { + // not has intersect-element with the finished peer + if (!(it->second.refInfo & (1 << peerIndex))) + { + it = m_masterDataRef.erase(it); + continue; + } + // reset the refCount + it->second.resetRefCount(); + it++; + } + m_peerMerged = true; + // release the free memory after merged + MallocExtension::instance()->ReleaseFreeMemory(); + ECDH_MULTI_LOG(INFO) << LOG_DESC("mergeMasterCipher finished") + << LOG_KV("distinct-masterDataSize-after-merge", m_masterDataRef.size()) + << LOG_KV("finishedPeer", peerId) << LOG_KV("peerIndex", peerIndex) + << LOG_KV("timecost", (utcSteadyTime() - startT)); +} + +// get the cipher-data intersection: h(x)^a && h(Y)^a +bool MasterCache::tryToIntersection() +{ + if (!shouldIntersection()) + { + return false; + } + m_cacheState = CacheState::IntersectionProgressing; + + ECDH_MULTI_LOG(INFO) << LOG_DESC("* tryToIntersection ") << printCacheState() + << LOG_KV("* masterData", m_masterDataRef.size()); + auto startT = utcSteadyTime(); + // iterator the masterDataRef to obtain intersection + for (auto&& it : m_masterDataRef) + { + if (!m_masterDataRef.count(it.first)) + { + continue; + } + if (m_masterDataRef.at(it.first).refCount != m_peerCount) + { + continue; + } + if (m_masterDataRef.at(it.first).dataIndex == -1) + { + continue; + } + // intersection case + m_intersecCipher.emplace_back(std::move(it.first)); + m_intersecCipherIndex.emplace_back(it.second.dataIndex); + } + releaseCache(); + m_cacheState = CacheState::Intersectioned; + ECDH_MULTI_LOG(INFO) << LOG_DESC("* tryToIntersection success") << printCacheState() + << LOG_KV("* intersectionSize", m_intersecCipher.size()) + << LOG_KV("* timecost", (utcSteadyTime() - startT)); + return true; +} + +void MasterCache::encryptAndSendIntersection(uint64_t dataBatchIdx, bcos::bytes const& randomKey, + std::map const& calculators) +{ + auto startT = utcSteadyTime(); + auto message = m_config->psiMsgFactory()->createPSIMessage( + uint32_t(EcdhMultiPSIMessageType::SEND_ENCRYPTED_INTERSECTION_SET_TO_CALCULATOR)); + message->setFrom(m_taskState->task()->selfParty()->id()); + size_t startIndex = dataBatchIdx * m_config->dataBatchSize(); + size_t endIndex = std::min(startIndex + m_config->dataBatchSize(), m_intersecCipher.size()); + ECDH_MULTI_LOG(INFO) << LOG_DESC("encryptAndSendIntersection") + << LOG_KV("cipherCount", m_intersecCipher.size()) + << LOG_KV("dataBatchIdx", dataBatchIdx) << LOG_KV("start", startIndex) + << LOG_KV("end", endIndex) << printCacheState(); + message->resizeData(endIndex - startIndex); + if (endIndex >= m_intersecCipher.size()) + { + message->setDataBatchCount(dataBatchIdx + 1); + } + tbb::parallel_for(tbb::blocked_range(startIndex, endIndex), [&](auto const& range) { + for (auto i = range.begin(); i < range.end(); i++) + { + auto cipherValue = m_config->eccCrypto()->ecMultiply(m_intersecCipher[i], randomKey); + message->setDataPair( + i - startIndex, m_intersecCipherIndex[i - startIndex], cipherValue); + } + }); + auto taskID = m_taskState->task()->id(); + auto self = weak_from_this(); + for (auto const& calculator : calculators) + { + m_config->generateAndSendPPCMessage( + calculator.first, taskID, message, + [self, calculator](bcos::Error::Ptr&& _error) { + if (!_error || _error->errorCode() == 0) + { + return; + } + auto cache = self.lock(); + if (!cache) + { + return; + } + ECDH_MULTI_LOG(WARNING) + << LOG_DESC("encryptAndSendIntersection: send message to calcultor failed") + << LOG_KV("task", cache->m_taskState->task()->id()) + << LOG_KV("calculator", calculator.first) << LOG_KV("code", _error->errorCode()) + << LOG_KV("msg", _error->errorMessage()); + cache->m_taskState->onTaskException(_error->errorMessage()); + }, + dataBatchIdx); + } + ECDH_MULTI_LOG(INFO) << LOG_DESC("encryptAndSendIntersection success") + << LOG_KV("cipherCount", m_intersecCipher.size()) + << LOG_KV("dataBatchIdx", dataBatchIdx) + << LOG_KV("timecost", utcSteadyTime() - startT) << printCacheState(); +} + +void MasterCache::encryptIntersection( + bcos::bytes const& randomKey, std::map const& calculators) +{ + auto dataBatchCount = + std::max((uint64_t)(m_intersecCipher.size() + m_config->dataBatchSize() - 1) / + (uint64_t)m_config->dataBatchSize(), + (uint64_t)1); + ECDH_MULTI_LOG(INFO) << LOG_DESC("encryptIntersection") + << LOG_KV("cipherCount", m_intersecCipher.size()) + << LOG_KV("dataBatchCount", dataBatchCount) << printCacheState(); + auto startT = utcSteadyTime(); + for (uint64_t i = 0; i < dataBatchCount; i++) + { + encryptAndSendIntersection(i, randomKey, calculators); + } + ECDH_MULTI_LOG(INFO) << LOG_DESC("encryptIntersection success") + << LOG_KV("timecost", (utcSteadyTime() - startT)) + << LOG_KV("cipherCount", m_intersecCipher.size()) << printCacheState(); + // Note: release the m_intersecCipher, make share it not been used after released + releaseIntersection(); +} + +bcos::bytes CalculatorCache::getPlainDataByIndex(uint64_t index) +{ + uint64_t startIndex = 0; + uint64_t endIndex = 0; + for (auto const& it : m_plainData) + { + endIndex += it->size(); + if (index >= startIndex && index < endIndex) + { + return it->getBytes((index - startIndex)); + } + startIndex += it->size(); + } + return bcos::bytes(); +} + +bool CalculatorCache::tryToFinalize() +{ + if (!shouldFinalize()) + { + return false; + } + auto startT = utcSteadyTime(); + ECDH_MULTI_LOG(INFO) << LOG_DESC("* tryToFinalize: compute intersection") + << LOG_KV("* cipherRef", m_cipherRef.size()) << printCacheState(); + m_cacheState = CacheState::Finalizing; + // find the intersection + for (auto const& it : m_cipherRef) + { + if (it.second.refCount < 2) + { + continue; + } + auto data = getPlainDataByIndex(it.second.plainDataIndex); + if (it.second.plainDataIndex > 0) + { + m_intersectionResult.emplace_back(data); + } + if (it.second.plainDataIndex == 0) + { + // means the header field, swap with the first element + if (m_intersectionResult.size() > 0) + { + m_intersectionResult.emplace_back(m_intersectionResult[0]); + m_intersectionResult[0] = data; + } + else + { + m_intersectionResult.emplace_back(data); + } + } + } + m_cacheState = CacheState::Finalized; + ECDH_MULTI_LOG(INFO) << LOG_DESC("* tryToFinalize: compute intersection success") + << printCacheState() << LOG_KV("* cipherRef", m_cipherRef.size()) + << LOG_KV("* intersectionSize", m_intersectionResult.size()) + << LOG_KV("* timecost", (utcSteadyTime() - startT)); + + releaseCipherCache(); + ECDH_MULTI_LOG(INFO) << LOG_DESC("* tryToFinalize: syncIntersections") << printCacheState(); + m_cacheState = CacheState::Syncing; + syncIntersections(); + m_cacheState = CacheState::Synced; + + m_cacheState = CacheState::StoreProgressing; + m_taskState->storePSIResult(m_config->dataResourceLoader(), m_intersectionResult); + m_cacheState = CacheState::Stored; + ECDH_MULTI_LOG(INFO) << LOG_DESC("* tryToFinalize: syncIntersections and store success") + << printCacheState(); + return true; +} + +void CalculatorCache::syncIntersections() +{ + ECDH_MULTI_LOG(INFO) << LOG_DESC("*** syncIntersections **") << printCacheState(); + auto peers = m_taskState->task()->getAllPeerParties(); + auto taskID = m_taskState->task()->id(); + // notify task result + if (!m_syncResult) + { + auto message = m_config->psiMsgFactory()->createPSIMessage( + uint32_t(EcdhMultiPSIMessageType::SYNC_FINAL_RESULT_TO_ALL)); + message->setFrom(m_taskState->task()->selfParty()->id()); + message->setVersion(-1); + for (auto& peer : peers) + { + // Note: sync task failed will not change the task status + m_config->generateAndSendPPCMessage( + peer.first, taskID, message, + [taskID, peer](bcos::Error::Ptr&& _error) { + if (_error && _error->errorCode() != 0) + { + ECDH_MULTI_LOG(WARNING) + << LOG_DESC("sync task result to peer failed") + << LOG_KV("peer", peer.first) << LOG_KV("taskID", taskID) + << LOG_KV("code", _error->errorCode()) + << LOG_KV("msg", _error->errorMessage()); + return; + } + }, + 0); + } + return; + } + // sync intersectionResult to all peers + auto message = m_config->psiMsgFactory()->createPSIMessage( + uint32_t(EcdhMultiPSIMessageType::SYNC_FINAL_RESULT_TO_ALL)); + message->setData(m_intersectionResult); + message->setFrom(m_taskState->task()->selfParty()->id()); + message->setVersion(0); + for (auto& peer : peers) + { + // Note: sync task failed will not change the task status + m_config->generateAndSendPPCMessage( + peer.first, taskID, message, + [taskID, peer](bcos::Error::Ptr&& _error) { + if (_error && _error->errorCode() != 0) + { + ECDH_MULTI_LOG(WARNING) + << LOG_DESC("sync psi result to peer failed") << LOG_KV("peer", peer.first) + << LOG_KV("taskID", taskID) << LOG_KV("code", _error->errorCode()) + << LOG_KV("msg", _error->errorMessage()); + return; + } + }, + 0); + } +} + +void CalculatorCache::updateCipherRef(bcos::bytes&& data, int32_t index) +{ + // case that receive at least one completed data, only record the intersection data + if (m_receiveAllMasterCipher || m_receiveAllIntersection) + { + if (!m_cipherRef.count(data)) + { + return; + } + } + // new data case + if (!m_cipherRef.count(data)) + { + CipherRefDetail cipherRef; + cipherRef.refCount = 1; + cipherRef.updatePlainIndex(index); + m_cipherRef.insert(std::make_pair(std::move(data), std::move(cipherRef))); + return; + } + // existed data case + m_cipherRef[data].refCount += 1; + m_cipherRef[data].updatePlainIndex(index); +} + + +bool CalculatorCache::appendMasterCipher( + std::vector&& _cipherData, uint32_t seq, uint32_t dataBatchSize) +{ + bcos::Guard lock(m_mutex); + m_receivedMasterCipher.insert(seq); + for (auto&& it : _cipherData) + { + updateCipherRef(std::move(it), -1); + } + if (m_masterDataBatchSize == 0 && dataBatchSize > 0) + { + m_masterDataBatchSize = dataBatchSize; + } + if (!m_receiveAllMasterCipher && m_receivedMasterCipher.size() == m_masterDataBatchSize) + { + m_receiveAllMasterCipher = true; + } + ECDH_MULTI_LOG(INFO) << LOG_DESC("appendMasterCipher") << LOG_KV("dataSize", _cipherData.size()) + << LOG_KV("cipherRefSize", m_cipherRef.size()) << printCacheState(); + // release the cipherData + _cipherData.clear(); + std::vector().swap(_cipherData); + MallocExtension::instance()->ReleaseFreeMemory(); + return m_receiveAllMasterCipher; +} + +void CalculatorCache::addIntersectionCipher(std::vector&& _cipherData, + std::vector const& dataIndex, uint32_t seq, uint64_t dataBatchCount) +{ + auto startT = utcSteadyTime(); + ECDH_MULTI_LOG(INFO) << LOG_DESC("addIntersectionCipher") << LOG_KV("seq", seq) + << LOG_KV("dataSize", _cipherData.size()) + << LOG_KV("cipherRefSize", m_cipherRef.size()) << printCacheState() + << LOG_KV("dataBatchCount", dataBatchCount); + bcos::Guard lock(m_mutex); + uint64_t i = 0; + for (auto&& it : _cipherData) + { + updateCipherRef(std::move(it), dataIndex[i]); + i++; + } + m_receivedIntersections.insert(seq); + if (dataBatchCount > 0) + { + m_intersectionBatchCount = dataBatchCount; + } + if (m_intersectionBatchCount > 0 && m_receivedIntersections.size() >= m_intersectionBatchCount) + { + m_receiveAllIntersection = true; + } + ECDH_MULTI_LOG(INFO) << LOG_DESC("addIntersectionCipher success") + << LOG_KV("timecost", utcSteadyTime() - startT) << LOG_KV("seq", seq) + << LOG_KV("dataSize", _cipherData.size()) + << LOG_KV("receiveAll", m_receiveAllIntersection) + << LOG_KV("cipherRefSize", m_cipherRef.size()) << printCacheState(); + // release the cipherData + _cipherData.clear(); + std::vector().swap(_cipherData); + MallocExtension::instance()->ReleaseFreeMemory(); +} \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-psi/src/ecdh-multi-psi/EcdhMultiCache.h b/cpp/wedpr-computing/ppc-psi/src/ecdh-multi-psi/EcdhMultiCache.h new file mode 100644 index 00000000..a4fc1f60 --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/ecdh-multi-psi/EcdhMultiCache.h @@ -0,0 +1,320 @@ +/* + * Copyright (C) 2022 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 EcdhCache.h + * @author: zachma + * @date 2023-5-28 + */ +#pragma once +#include "Common.h" +#include "EcdhMultiPSIConfig.h" +#include "ppc-psi/src/Common.h" +#include "ppc-psi/src/psi-framework/TaskState.h" +#include +#include +#include + +namespace ppc::psi +{ +struct MasterCipherRef +{ + // support at least 63 peers + uint64_t refInfo = 0; + unsigned short refCount = 0; + int32_t dataIndex = -1; + + void resetRefCount() + { + auto ref = refInfo; + do + { + if (ref & 0x1) + { + refCount++; + } + ref >>= 1; + } while (ref > 0); + } + void updateDataIndex(int32_t index) + { + if (index == -1) + { + return; + } + dataIndex = index; + } +}; +/// the master data-cache +class MasterCache : public std::enable_shared_from_this +{ +public: + using Ptr = std::shared_ptr; + MasterCache(TaskState::Ptr const& taskState, EcdhMultiPSIConfig::Ptr const& config) + : m_taskState(taskState), + m_config(config), + m_peerCount(m_taskState->task()->getAllPeerParties().size()) + { + for (auto const& it : m_taskState->task()->getAllPeerParties()) + { + m_peers.emplace_back(it.first); + } + } + + virtual ~MasterCache() + { + releaseCache(); + releaseIntersection(); + ECDH_MULTI_LOG(INFO) << LOG_DESC("the master cipher datacache destroyed ") + << LOG_KV("taskID", m_taskState->task()->id()); + } + + void addCalculatorCipher(std::string _peerId, std::vector&& _cipherData, + std::vector const& dataIndex, uint32_t seq, uint32_t dataBatchCount); + + void addPartnerCipher(std::string _peerId, std::vector&& _cipherData, uint32_t seq, + uint32_t parternerDataCount); + + bool tryToIntersection(); + + std::string printCacheState() + { + std::ostringstream stringstream; + stringstream << LOG_KV("taskID", m_taskState->task()->id()) + << LOG_KV("CacheState", m_cacheState); + return stringstream.str(); + } + + void encryptIntersection(bcos::bytes const& randomKey, + std::map const& calculators); + +private: + void encryptAndSendIntersection(uint64_t dataBatchIdx, bcos::bytes const& randomKey, + std::map const& calculators); + + bool shouldIntersection() + { + // only evaluating state should intersection + if (m_cacheState != CacheState::Evaluating) + { + return false; + } + auto allPeerParties = m_taskState->task()->getAllPeerParties(); + if (allPeerParties.size() == m_finishedPartners.size()) + { + for (auto const& it : allPeerParties) + { + if (!m_finishedPartners.contains(it.first)) + { + return false; + } + } + return true; + } + return false; + } + + void releaseIntersection() + { + m_intersecCipher.clear(); + m_intersecCipherIndex.clear(); + + // release the intersection information + std::vector().swap(m_intersecCipher); + std::vector().swap(m_intersecCipherIndex); + + MallocExtension::instance()->ReleaseFreeMemory(); + ECDH_MULTI_LOG(INFO) << LOG_DESC("releaseIntersection") + << LOG_KV("taskID", m_taskState->task()->id()); + } + + void releaseCache() + { + m_masterDataRef.clear(); + + // release the parterner cipher + std::map().swap(m_masterDataRef); + MallocExtension::instance()->ReleaseFreeMemory(); + ECDH_MULTI_LOG(INFO) << LOG_DESC("releaseCache") + << LOG_KV("taskID", m_taskState->task()->id()); + } + + void mergeMasterCipher(std::string const& peerId, unsigned short peerIndex); + void updateMasterDataRef(unsigned short _peerIndex, bcos::bytes&& data, int32_t dataIndex); + + signed short getPeerIndex(std::string const& peer) + { + for (unsigned short i = 0; i < m_peers.size(); i++) + { + if (m_peers[i] == peer) + { + return i; + } + } + return -1; + } + +private: + TaskState::Ptr m_taskState; + EcdhMultiPSIConfig::Ptr m_config; + unsigned short m_peerCount; + std::vector m_peers; + + CacheState m_cacheState = CacheState::Evaluating; + + // the intersection cipher data of the master + std::vector m_intersecCipher; + std::vector m_intersecCipherIndex; + + std::set m_calculatorCipherSeqs; + uint32_t m_calculatorDataBatchCount = 0; + + // data => refered peers + std::map m_masterDataRef; + + // partnerId=>received partner seqs + std::map> m_partnerCipherSeqs; + // peerId==>dataCount + std::map m_parternerDataCount; + std::set m_finishedPartners; + + bool m_peerMerged = false; + + bcos::Mutex m_mutex; +}; + +// the cipher ref count +// data ==> {ref count, plainData} +struct CipherRefDetail +{ + unsigned short refCount = 0; + int32_t plainDataIndex = -1; + + void updatePlainIndex(int32_t index) + { + if (index == -1) + { + return; + } + plainDataIndex = index; + } +}; + +class CalculatorCache : public std::enable_shared_from_this +{ +public: + using Ptr = std::shared_ptr; + CalculatorCache( + TaskState::Ptr const& taskState, bool syncResult, EcdhMultiPSIConfig::Ptr const& config) + : m_taskState(taskState), m_syncResult(syncResult), m_config(config) + {} + virtual ~CalculatorCache() + { + releaseCipherCache(); + + m_intersectionResult.clear(); + std::vector().swap(m_intersectionResult); + MallocExtension::instance()->ReleaseFreeMemory(); + ECDH_MULTI_LOG(INFO) << LOG_DESC("the calculator cipher datacache destroyed") + << LOG_KV("taskID", m_taskState->task()->id()); + } + + bool tryToFinalize(); + + bool appendMasterCipher( + std::vector&& _cipherData, uint32_t seq, uint32_t dataBatchSize); + + void addIntersectionCipher(std::vector&& _cipherData, + std::vector const& dataIndex, uint32_t seq, uint64_t dataBatchCount); + + void appendPlainData(ppc::io::DataBatch::Ptr const& data) + { + bcos::WriteGuard l(x_plainData); + m_plainData.emplace_back(data); + } + + std::string printCacheState() + { + std::ostringstream stringstream; + stringstream << LOG_KV("taskID", m_taskState->task()->id()) + << LOG_KV("CacheState", m_cacheState) + << LOG_KV("intersectionSize", m_intersectionResult.size()); + return stringstream.str(); + } + +private: + bcos::bytes getPlainDataByIndex(uint64_t index); + bool shouldFinalize() + { + // only can finalize in Evaluating state + if (m_cacheState != CacheState::Evaluating) + { + return false; + } + if (!m_receiveAllIntersection) + { + return false; + } + if (m_receivedMasterCipher.size() == 0) + { + return false; + } + return m_receivedMasterCipher.size() == m_masterDataBatchSize; + } + + void syncIntersections(); + + void releaseCipherCache() + { + for (auto const& it : m_plainData) + { + it->release(); + // free after release + MallocExtension::instance()->ReleaseFreeMemory(); + } + m_cipherRef.clear(); + std::map().swap(m_cipherRef); + MallocExtension::instance()->ReleaseFreeMemory(); + ECDH_MULTI_LOG(INFO) << LOG_DESC("releaseCipherCache") + << LOG_KV("taskID", m_taskState->task()->id()); + } + + void updateCipherRef(bcos::bytes&& data, int32_t index); + +private: + TaskState::Ptr m_taskState; + bool m_syncResult; + EcdhMultiPSIConfig::Ptr m_config; + CacheState m_cacheState = CacheState::Evaluating; + + std::vector m_plainData; + bcos::SharedMutex x_plainData; + + std::map m_cipherRef; + + // the seqs of the data received from master + std::set m_receivedMasterCipher; + uint32_t m_masterDataBatchSize = 0; + bool m_receiveAllMasterCipher = false; + mutable bcos::Mutex m_mutex; + + // the intersection cipher received from master + std::set m_receivedIntersections; + bool m_receiveAllIntersection = false; + uint32_t m_intersectionBatchCount = 0; + + // the final result + std::vector m_intersectionResult; +}; +} // namespace ppc::psi diff --git a/cpp/wedpr-computing/ppc-psi/src/ecdh-multi-psi/EcdhMultiPSIConfig.h b/cpp/wedpr-computing/ppc-psi/src/ecdh-multi-psi/EcdhMultiPSIConfig.h new file mode 100644 index 00000000..e4d3bb5f --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/ecdh-multi-psi/EcdhMultiPSIConfig.h @@ -0,0 +1,54 @@ +#pragma once +#include "EcdhMultiPSIMessageFactory.h" +#include "ppc-framework/crypto/CryptoBox.h" +#include "ppc-framework/protocol/Protocol.h" +#include "ppc-psi/src/PSIConfig.h" +#include "protocol/src/PPCMessage.h" +#include +#include +#include + +namespace ppc::psi +{ +class EcdhMultiPSIConfig : public PSIConfig +{ +public: + using Ptr = std::shared_ptr; + EcdhMultiPSIConfig(std::string const& _selfPartyID, ppc::front::FrontInterface::Ptr _front, + ppc::crypto::CryptoBox::Ptr _cryptoBox, bcos::ThreadPool::Ptr _threadPool, + ppc::io::DataResourceLoader::Ptr _dataResourceLoader, uint32_t _dataBatchSize, + int _holdingMessageMinutes, uint32_t minNeededMemoryGB, + EcdhMultiPSIMessageFactory::Ptr const& _psiMsgFactory, + const front::PPCMessageFactory::Ptr& _ppcMsgFactory = + std::make_shared()) + : PSIConfig(ppc::protocol::TaskAlgorithmType::ECDH_PSI_MULTI, _selfPartyID, std::move(_front), + _ppcMsgFactory, std::move(_dataResourceLoader), _holdingMessageMinutes, + minNeededMemoryGB), + m_threadPool(std::move(_threadPool)), + m_cryptoBox(std::move(_cryptoBox)), + m_psiMsgFactory(std::move(_psiMsgFactory)), + m_dataBatchSize(_dataBatchSize) + {} + + virtual ~EcdhMultiPSIConfig() + { + if (m_threadPool) + { + m_threadPool->stop(); + } + }; + + EcdhMultiPSIMessageFactory::Ptr const& psiMsgFactory() const { return m_psiMsgFactory; } + crypto::Hash::Ptr const& hash() const { return m_cryptoBox->hashImpl(); } + crypto::EccCrypto::Ptr const& eccCrypto() const { return m_cryptoBox->eccCrypto(); } + crypto::CryptoBox::Ptr const& cryptoBox() const { return m_cryptoBox; } + bcos::ThreadPool::Ptr const& threadPool() const { return m_threadPool; } + uint32_t dataBatchSize() const { return m_dataBatchSize; } + +private: + ppc::crypto::CryptoBox::Ptr m_cryptoBox; + bcos::ThreadPool::Ptr m_threadPool; + EcdhMultiPSIMessageFactory::Ptr m_psiMsgFactory; + uint32_t m_dataBatchSize = 10000; +}; +} // namespace ppc::psi \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-psi/src/ecdh-multi-psi/EcdhMultiPSIFactory.cpp b/cpp/wedpr-computing/ppc-psi/src/ecdh-multi-psi/EcdhMultiPSIFactory.cpp new file mode 100644 index 00000000..8f4329b3 --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/ecdh-multi-psi/EcdhMultiPSIFactory.cpp @@ -0,0 +1,41 @@ +/** + * Copyright (C) 2022 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 EcdhMultiPSIFactory.cpp + */ + +#include "EcdhMultiPSIFactory.h" +#include "EcdhMultiPSIMessageFactory.h" +#include "ppc-tools/src/config/PPCConfig.h" + +using namespace ppc::psi; +using namespace ppc::front; +using namespace ppc::tools; +using namespace ppc::io; +using namespace ppc::crypto; + +EcdhMultiPSIImpl::Ptr EcdhMultiPSIFactory::createEcdhMultiPSI(PPCConfig::Ptr const& _ppcConfig, + FrontInterface::Ptr _front, CryptoBox::Ptr _cryptoBox, bcos::ThreadPool::Ptr _threadPool, + DataResourceLoader::Ptr _dataResourceLoader, uint32_t minNeededMemoryGB) +{ + auto psiMsgFactory = std::make_shared(); + auto const& ecdhParam = _ppcConfig->ecdhMultiPSIConfig(); + auto _selfParty = _ppcConfig->agencyID(); + int _holdingMessageMinutes = _ppcConfig->holdingMessageMinutes(); + auto config = std::make_shared(_selfParty, std::move(_front), + std::move(_cryptoBox), std::move(_threadPool), std::move(_dataResourceLoader), + ecdhParam.dataBatchSize, _holdingMessageMinutes, minNeededMemoryGB, psiMsgFactory); + return std::make_shared(config); +} diff --git a/cpp/wedpr-computing/ppc-psi/src/ecdh-multi-psi/EcdhMultiPSIFactory.h b/cpp/wedpr-computing/ppc-psi/src/ecdh-multi-psi/EcdhMultiPSIFactory.h new file mode 100644 index 00000000..eaa7e505 --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/ecdh-multi-psi/EcdhMultiPSIFactory.h @@ -0,0 +1,43 @@ +/** + * Copyright (C) 2022 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 EcdhMultiPSIFactory.h + */ + +#pragma once +#include "EcdhMultiPSIImpl.h" +#include "ppc-framework/crypto/CryptoBox.h" +#include "ppc-framework/io/DataResourceLoader.h" + +namespace ppc::tools +{ +class PPCConfig; +} +namespace ppc::psi +{ +class EcdhMultiPSIFactory +{ +public: + using Ptr = std::shared_ptr; + EcdhMultiPSIFactory() = default; + virtual ~EcdhMultiPSIFactory() = default; + + virtual EcdhMultiPSIImpl::Ptr createEcdhMultiPSI( + std::shared_ptr const& _ppcConfig, + ppc::front::FrontInterface::Ptr _front, ppc::crypto::CryptoBox::Ptr _cryptoBox, + bcos::ThreadPool::Ptr _threadPool, ppc::io::DataResourceLoader::Ptr _dataResourceLoader, + uint32_t minNeededMemoryGB = 1); +}; +} // namespace ppc::psi \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-psi/src/ecdh-multi-psi/EcdhMultiPSIImpl.cpp b/cpp/wedpr-computing/ppc-psi/src/ecdh-multi-psi/EcdhMultiPSIImpl.cpp new file mode 100644 index 00000000..bb6d0d6d --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/ecdh-multi-psi/EcdhMultiPSIImpl.cpp @@ -0,0 +1,417 @@ +#include "EcdhMultiPSIImpl.h" +#include "Common.h" +#include "ppc-framework/protocol/Constant.h" +#include + +using namespace ppc::psi; +using namespace ppc::protocol; +using namespace ppc::front; +using namespace ppc::crypto; +using namespace ppc::io; +using namespace bcos; +using namespace ppc::task; + + +EcdhMultiPSIImpl::EcdhMultiPSIImpl(const EcdhMultiPSIConfig::Ptr& _config, unsigned _idleTimeMs) + : m_config(std::move(_config)), + m_msgQueue(std::make_shared()), + TaskGuarder(_config, TaskAlgorithmType::ECDH_PSI_MULTI, "ECDH-MULTI-PSI-Timer") +{} + +void EcdhMultiPSIImpl::onReceiveMessage(ppc::front::PPCMessageFace::Ptr _msg) +{ + try + { + m_msgQueue->push(_msg); + wakeupWorker(); + } + catch (std::exception const& e) + { + ECDH_MULTI_LOG(WARNING) << LOG_DESC("onReceiveMessage exception") << printPPCMsg(_msg) + << LOG_KV("error", boost::diagnostic_information(e)); + } +} + +void EcdhMultiPSIImpl::handlerPSIReceiveMessage(PSIMessageInterface::Ptr _msg) +{ + auto self = weak_from_this(); + m_config->threadPool()->enqueue([self, _msg]() { + auto psi = self.lock(); + if (!psi) + { + return; + } + try + { + switch (_msg->packetType()) + { + case (uint32_t)EcdhMultiPSIMessageType::GENERATE_RANDOM_TO_PARTNER: + { + // calculator -> partner (A) + psi->onReceiveRandomA(_msg); + break; + } + case (uint32_t)EcdhMultiPSIMessageType::SEND_ENCRYPTED_SET_TO_MASTER_FROM_CALCULATOR: + { + // calculator -> master H(X)*A + psi->onReceiveCalCipher(_msg); + break; + } + case (uint32_t)EcdhMultiPSIMessageType::SEND_ENCRYPTED_SET_TO_MASTER_FROM_PARTNER: + { + // patner -> master H(Y)*A + psi->onReceiveCipherFromPartner(_msg); + break; + } + case (uint32_t)EcdhMultiPSIMessageType::SEND_ENCRYPTED_INTERSECTION_SET_TO_CALCULATOR: + { + psi->onReceiveIntersecCipher(_msg); + break; + } + case (uint32_t)EcdhMultiPSIMessageType::SEND_ENCRYPTED_SET_TO_CALCULATOR: + { + psi->onReceiveMasterCipher(_msg); + break; + } + case (uint32_t)EcdhMultiPSIMessageType:: + RETURN_ENCRYPTED_INTERSECTION_SET_FROM_CALCULATOR_TO_MASTER: + { + break; + } + case (uint32_t)EcdhMultiPSIMessageType::SYNC_FINAL_RESULT_TO_ALL: + { + psi->onReceivePSIResult(_msg); + break; + } + default: + { + ECDH_MULTI_LOG(WARNING) + << LOG_DESC("Unsupported packetType ") << (int)_msg->packetType(); + break; + } + } + } + catch (std::exception const& e) + { + ECDH_MULTI_LOG(WARNING) + << LOG_DESC("handlePSIMsg exception") << LOG_KV("packetType", _msg->packetType()) + << printPSIMessage(_msg) << LOG_KV("error", boost::diagnostic_information(e)); + } + }); +} + + +void EcdhMultiPSIImpl::asyncRunTask( + ppc::protocol::Task::ConstPtr _task, ppc::task::TaskResponseCallback&& _onTaskFinished) +{ + try + { + auto taskID = _task->id(); + auto taskState = + m_taskStateFactory->createTaskState(_task, std::move(_onTaskFinished), false, m_config); + auto self = weak_from_this(); + taskState->registerNotifyPeerFinishHandler([self, _task]() { + auto psi = self.lock(); + if (!psi) + { + return; + } + psi->noticePeerToFinish(_task); + }); + taskState->registerFinalizeHandler([self, taskID]() { + auto psi = self.lock(); + if (!psi) + { + return; + } + // erase the taskInfo from the gateway + psi->m_config->front()->eraseTaskInfo(taskID); + psi->removeCalculator(taskID); + psi->removeMaster(taskID); + psi->removePartner(taskID); + psi->removePendingTask(taskID); + }); + addPendingTask(taskState); + // check the memory + checkHostResource(m_config->minNeededMemoryGB()); + // over the peer limit + if (_task->getAllPeerParties().size() > c_max_peer_size) + { + auto error = std::make_shared(-1, + "at most support " + std::to_string(c_max_peer_size) + " peers, over the limit!"); + ECDH_MULTI_LOG(WARNING) + << LOG_DESC("asyncRunTask failed") << LOG_KV("msg", error->errorMessage()); + onSelfError(_task->id(), error, true); + } + + auto dataResource = _task->selfParty()->dataResource(); + auto reader = loadReader(_task->id(), dataResource, DataSchema::Bytes); + auto sqlReader = (reader->type() == ppc::protocol::DataResourceType::MySQL); + auto nextParam = sqlReader ? 0 : m_config->dataBatchSize(); + taskState->setReader(reader, nextParam); + auto role = _task->selfParty()->partyIndex(); + auto receivers = _task->getReceiverLists(); + ECDH_MULTI_LOG(INFO) << LOG_DESC("Start a asyncRunTask ") << LOG_KV("taskID", _task->id()) + << LOG_KV("roleId", role); + if (role == uint16_t(PartiesType::Calculator)) + { + auto writer = loadWriter(_task->id(), dataResource, _task->enableOutputExists()); + taskState->setWriter(writer); + ECDH_MULTI_LOG(INFO) << LOG_DESC("Calculator do the Task") + << LOG_KV("taskID", _task->id()); + auto calculator = std::make_shared(m_config, taskState); + calculator->asyncStartRunTask(_task); + addCalculator(std::move(calculator)); + } + else if (role == uint16_t(PartiesType::Partner)) + { + ECDH_MULTI_LOG(INFO) << LOG_DESC("Partner do the Task") + << LOG_KV("taskID", _task->id()); + if (_task->syncResultToPeer() && std::find(receivers.begin(), receivers.end(), + m_config->selfParty()) != receivers.end()) + { + auto writer = loadWriter(_task->id(), dataResource, _task->enableOutputExists()); + taskState->setWriter(writer); + } + auto partner = std::make_shared(m_config, taskState); + partner->asyncStartRunTask(_task); + addPartner(std::move(partner)); + } + else if (role == uint16_t(PartiesType::Master)) + { + ECDH_MULTI_LOG(INFO) << LOG_DESC("Master do the Task") << LOG_KV("taskID", _task->id()); + if (_task->syncResultToPeer() && std::find(receivers.begin(), receivers.end(), + m_config->selfParty()) != receivers.end()) + { + auto writer = loadWriter(_task->id(), dataResource, _task->enableOutputExists()); + taskState->setWriter(writer); + } + auto master = std::make_shared(m_config, taskState); + master->asyncStartRunTask(_task); + addMaster(std::move(master)); + } + else + { + BOOST_THROW_EXCEPTION(ECDHMULTIException() << bcos::errinfo_comment( + "The party index of the ecdh-multi-psi must be calculator(0) " + "or partner(1) or master(2)!")); + } + + // notify the taskInfo to the front + m_config->front()->notifyTaskInfo(_task->id()); + } + catch (bcos::Error const& e) + { + ECDH_MULTI_LOG(ERROR) << LOG_DESC("asyncRunTask exception") << printTaskInfo(_task) + << LOG_KV("code", e.errorCode()) << LOG_KV("msg", e.errorMessage()); + onSelfError( + _task->id(), std::make_shared(e.errorCode(), e.errorMessage()), true); + } + catch (std::exception& e) + { + auto error = BCOS_ERROR_PTR((int)TaskParamsError, boost::diagnostic_information(e)); + onSelfError(_task->id(), error, true); + } +} + +void EcdhMultiPSIImpl::start() +{ + startWorking(); + startPingTimer(); +} + +void EcdhMultiPSIImpl::stop() +{ + if (m_config->threadPool()) + { + m_config->threadPool()->stop(); + } + + finishWorker(); + if (isWorking()) + { + // stop the worker thread + stopWorking(); + terminate(); + } + stopPingTimer(); +} + +void EcdhMultiPSIImpl::checkFinishedTask() +{ + std::set finishedTask; + { + bcos::WriteGuard l(x_pendingTasks); + if (m_pendingTasks.empty()) + { + return; + } + + for (auto it = m_pendingTasks.begin(); it != m_pendingTasks.end();) + { + auto task = it->second; + if (task->taskDone()) + { + finishedTask.insert(it->first); + } + it++; + } + } + for (auto& taskID : finishedTask) + { + removeCalculator(taskID); + removeMaster(taskID); + removePartner(taskID); + removePendingTask(taskID); + } +} + +void EcdhMultiPSIImpl::onReceivedErrorNotification(ppc::front::PPCMessageFace::Ptr const& _message) +{ + ECDH_MULTI_LOG(INFO) << LOG_DESC("onReceivedErrorNotification") << printPPCMsg(_message); + // finish the task while the peer is failed + auto taskState = findPendingTask(_message->taskID()); + if (taskState) + { + taskState->onPeerNotifyFinish(); + + wakeupWorker(); + } +} + +void EcdhMultiPSIImpl::onSelfError( + const std::string& _taskID, bcos::Error::Ptr _error, bool _noticePeer) +{ + auto taskState = findPendingTask(_taskID); + if (!taskState) + { + return; + } + + ECDH_MULTI_LOG(ERROR) << LOG_DESC("onSelfError") << LOG_KV("task", _taskID) + << LOG_KV("exception", _error->errorMessage()) + << LOG_KV("noticePeer", _noticePeer); + + auto result = std::make_shared(taskState->task()->id()); + result->setError(std::move(_error)); + taskState->onTaskFinished(result, _noticePeer); + + wakeupWorker(); +} + +void EcdhMultiPSIImpl::executeWorker() +{ + checkFinishedTask(); + auto _msg = m_msgQueue->tryPop(c_popWaitMs); + if (_msg.first) + { + auto pop_msg = _msg.second; + if (pop_msg->messageType() == uint8_t(CommonMessageType::ErrorNotification)) + { + onReceivedErrorNotification(pop_msg); + return; + } + else if (pop_msg->messageType() == uint8_t(CommonMessageType::PingPeer)) + { + return; + } + + // decode the psi message + auto payLoad = pop_msg->data(); + auto psiMsg = m_config->psiMsgFactory()->decodePSIMessage( + bcos::bytesConstRef(payLoad->data(), payLoad->size())); + psiMsg->setFrom(pop_msg->sender()); + psiMsg->setTaskID(pop_msg->taskID()); + psiMsg->setSeq(pop_msg->seq()); + psiMsg->setUUID(pop_msg->uuid()); + ECDH_MULTI_LOG(TRACE) << LOG_DESC("onReceiveMessage") << printPSIMessage(psiMsg) + << LOG_KV("uuid", psiMsg->uuid()); + // release the large payload immediately + if (payLoad && payLoad->size() >= ppc::protocol::LARGE_MSG_THRESHOLD) + { + ECDH_MULTI_LOG(INFO) << LOG_DESC("Release large message payload") + << LOG_KV("size", payLoad->size()); + pop_msg->releasePayload(); + MallocExtension::instance()->ReleaseFreeMemory(); + } + handlerPSIReceiveMessage(psiMsg); + return; + } + waitSignal(); +} + +void EcdhMultiPSIImpl::onReceiveRandomA(PSIMessageInterface::Ptr _msg) +{ + auto partner = findPartner(_msg->taskID()); + if (partner) + { + if (_msg->takeData().size() == 1) + { + auto msgData = _msg->getData(0); + partner->onReceiveRandomA( + std::make_shared(bcos::bytes(msgData.begin(), msgData.end()))); + } + } +} + +void EcdhMultiPSIImpl::onReceiveCalCipher(PSIMessageInterface::Ptr _msg) +{ + auto master = findMaster(_msg->taskID()); + if (master) + { + master->onReceiveCalCipher(_msg); + } +} + +void EcdhMultiPSIImpl::onReceiveCipherFromPartner(PSIMessageInterface::Ptr _msg) +{ + auto master = findMaster(_msg->taskID()); + if (master) + { + master->onReceiveCipherFromPartner(_msg); + } +} + +void EcdhMultiPSIImpl::onReceiveIntersecCipher(PSIMessageInterface::Ptr _msg) +{ + auto calculator = findCalculator(_msg->taskID()); + if (calculator) + { + calculator->onReceiveIntersecCipher(_msg); + } +} + +void EcdhMultiPSIImpl::onReceiveMasterCipher(PSIMessageInterface::Ptr _msg) +{ + auto calculator = findCalculator(_msg->taskID()); + if (calculator) + { + calculator->onReceiveMasterCipher(_msg); + } +} + + +void EcdhMultiPSIImpl::onReceivePSIResult(PSIMessageInterface::Ptr _msg) +{ + ECDH_MULTI_LOG(INFO) << LOG_DESC("onReceivePSIResult") << printPSIMessage(_msg); + auto startT = utcSteadyTime(); + auto master = findMaster(_msg->taskID()); + if (master) + { + master->onReceivePSIResult(_msg); + ECDH_MULTI_LOG(INFO) << LOG_DESC("Master onReceivePSIResult finished") + << printPSIMessage(_msg) + << LOG_KV("timecost", (utcSteadyTime() - startT)); + return; + } + + auto partner = findPartner(_msg->taskID()); + if (partner) + { + partner->onReceivePSIResult(_msg); + ECDH_MULTI_LOG(INFO) << LOG_DESC("Partner onReceivePSIResult finished") + << printPSIMessage(_msg) + << LOG_KV("timecost", (utcSteadyTime() - startT)); + return; + } +} diff --git a/cpp/wedpr-computing/ppc-psi/src/ecdh-multi-psi/EcdhMultiPSIImpl.h b/cpp/wedpr-computing/ppc-psi/src/ecdh-multi-psi/EcdhMultiPSIImpl.h new file mode 100644 index 00000000..3be24c7b --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/ecdh-multi-psi/EcdhMultiPSIImpl.h @@ -0,0 +1,168 @@ +#pragma once +#include "Common.h" +#include "EcdhMultiPSIConfig.h" +#include "core/EcdhMultiPSICalculator.h" +#include "core/EcdhMultiPSIMaster.h" +#include "core/EcdhMultiPSIPartner.h" +#include "ppc-framework/task/TaskFrameworkInterface.h" +#include "ppc-psi/src/psi-framework/TaskGuarder.h" +#include "protocol/src/PPCMessage.h" +#include +#include +#include + +#include +#include + + +namespace ppc::psi +{ +class EcdhMultiPSIImpl : public std::enable_shared_from_this, + public ppc::task::TaskFrameworkInterface, + public TaskGuarder, + public bcos::Worker +{ +public: + using Ptr = std::shared_ptr; + using EcdhMultiPSIMsgQueue = bcos::ConcurrentQueue; + using EcdhMultiPSIMsgQueuePtr = std::shared_ptr; + + EcdhMultiPSIImpl(const EcdhMultiPSIConfig::Ptr& _config, unsigned _idleTimeMs = 0); + + ~EcdhMultiPSIImpl() override = default; + + void asyncRunTask(ppc::protocol::Task::ConstPtr _task, + ppc::task::TaskResponseCallback&& _onTaskFinished) override; + + void onReceiveMessage(ppc::front::PPCMessageFace::Ptr _message) override; + + void start() override; + void stop() override; + + void checkFinishedTask(); + void onReceivedErrorNotification(ppc::front::PPCMessageFace::Ptr const& _message) override; + void onSelfError( + const std::string& _taskID, bcos::Error::Ptr _error, bool _noticePeer) override; + void executeWorker() override; + + +protected: + virtual void onReceiveRandomA(PSIMessageInterface::Ptr _msg); + virtual void onReceiveCalCipher(PSIMessageInterface::Ptr _msg); + virtual void handlerPSIReceiveMessage(PSIMessageInterface::Ptr _msg); + virtual void onReceiveIntersecCipher(PSIMessageInterface::Ptr _msg); + virtual void onReceiveMasterCipher(PSIMessageInterface::Ptr _msg); + virtual void onReceiveCipherFromPartner(PSIMessageInterface::Ptr _msg); + virtual void onReceivePSIResult(PSIMessageInterface::Ptr _msg); + + EcdhMultiPSICalculator::Ptr findCalculator(const std::string& _taskID) + { + bcos::ReadGuard l(x_calculators); + auto it = m_calculators.find(_taskID); + if (it != m_calculators.end()) + { + return it->second; + } + return nullptr; + } + + void addCalculator(EcdhMultiPSICalculator::Ptr _calculator) + { + bcos::WriteGuard l(x_calculators); + m_calculators[_calculator->taskID()] = _calculator; + } + + void removeCalculator(const std::string& _taskID) + { + bcos::WriteGuard l(x_calculators); + auto it = m_calculators.find(_taskID); + if (it != m_calculators.end()) + { + m_calculators.erase(it); + } + } + + EcdhMultiPSIPartner::Ptr findPartner(const std::string& _taskID) + { + bcos::ReadGuard l(x_partners); + auto it = m_partners.find(_taskID); + if (it != m_partners.end()) + { + return it->second; + } + return nullptr; + } + + void addPartner(EcdhMultiPSIPartner::Ptr _partner) + { + bcos::WriteGuard l(x_partners); + m_partners[_partner->taskID()] = _partner; + } + + void removePartner(const std::string& _taskID) + { + bcos::WriteGuard l(x_partners); + auto it = m_partners.find(_taskID); + if (it != m_partners.end()) + { + m_partners.erase(it); + } + } + + EcdhMultiPSIMaster::Ptr findMaster(const std::string& _taskID) + { + bcos::ReadGuard l(x_masters); + auto it = m_masters.find(_taskID); + if (it != m_masters.end()) + { + return it->second; + } + return nullptr; + } + + void addMaster(EcdhMultiPSIMaster::Ptr _master) + { + bcos::WriteGuard l(x_masters); + m_masters[_master->taskID()] = _master; + } + + void removeMaster(const std::string& _taskID) + { + bcos::WriteGuard l(x_partners); + auto it = m_masters.find(_taskID); + if (it != m_masters.end()) + { + m_masters.erase(it); + } + } + +private: + void waitSignal() + { + boost::unique_lock l(x_signal); + m_signal.wait_for(l, boost::chrono::milliseconds(5)); + } + + void wakeupWorker() { m_signal.notify_all(); } + + const int c_popWaitMs = 5; + + // at most support 63 peers + const int c_max_peer_size = 63; + + EcdhMultiPSIConfig::Ptr m_config; + TaskState::Ptr m_taskMultiState; + EcdhMultiPSIMsgQueuePtr m_msgQueue; + boost::condition_variable m_signal; + boost::mutex x_signal; + + std::unordered_map m_calculators; + mutable bcos::SharedMutex x_calculators; + + std::unordered_map m_partners; + mutable bcos::SharedMutex x_partners; + + std::unordered_map m_masters; + mutable bcos::SharedMutex x_masters; +}; +} // namespace ppc::psi \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-psi/src/ecdh-multi-psi/EcdhMultiPSIMessageFactory.h b/cpp/wedpr-computing/ppc-psi/src/ecdh-multi-psi/EcdhMultiPSIMessageFactory.h new file mode 100644 index 00000000..d4a8bde8 --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/ecdh-multi-psi/EcdhMultiPSIMessageFactory.h @@ -0,0 +1,35 @@ +#pragma once +#include "Common.h" +#include "ppc-psi/src/psi-framework/protocol/PSIMessage.h" +namespace ppc::psi +{ +class EcdhMultiPSIMessageFactory : public PSIMessageFactoryImpl +{ +public: + using Ptr = std::shared_ptr; + EcdhMultiPSIMessageFactory() = default; + ~EcdhMultiPSIMessageFactory() override = default; + + PSIMessageInterface::Ptr decodePSIMessage(bcos::bytesConstRef _data) override + { + auto inner = [inner = ppctars::PSIMessage()]() mutable { return &inner; }; + tars::TarsInputStream input; + input.setBuffer((const char*)_data.data(), _data.size()); + inner()->readFrom(input); + switch (inner()->packetType) + { + case (uint32_t)EcdhMultiPSIMessageType::GENERATE_RANDOM_TO_PARTNER: + case (uint32_t)EcdhMultiPSIMessageType::SEND_ENCRYPTED_SET_TO_MASTER_FROM_CALCULATOR: + case (uint32_t)EcdhMultiPSIMessageType::SEND_ENCRYPTED_SET_TO_MASTER_FROM_PARTNER: + case (uint32_t)EcdhMultiPSIMessageType::SEND_ENCRYPTED_SET_TO_CALCULATOR: + case (uint32_t)EcdhMultiPSIMessageType::SEND_ENCRYPTED_INTERSECTION_SET_TO_CALCULATOR: + case (uint32_t) + EcdhMultiPSIMessageType::RETURN_ENCRYPTED_INTERSECTION_SET_FROM_CALCULATOR_TO_MASTER: + case (uint32_t)EcdhMultiPSIMessageType::SYNC_FINAL_RESULT_TO_ALL: + return std::make_shared(inner); + default: + return decodePSIBaseMessage(inner); + } + } +}; +} // namespace ppc::psi diff --git a/cpp/wedpr-computing/ppc-psi/src/ecdh-multi-psi/core/EcdhMultiPSICalculator.cpp b/cpp/wedpr-computing/ppc-psi/src/ecdh-multi-psi/core/EcdhMultiPSICalculator.cpp new file mode 100644 index 00000000..47d65bce --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/ecdh-multi-psi/core/EcdhMultiPSICalculator.cpp @@ -0,0 +1,322 @@ +#include "EcdhMultiPSICalculator.h" +#include "ppc-psi/src/ecdh-multi-psi/Common.h" +#include +#include + +using namespace ppc::psi; +using namespace ppc::io; +using namespace ppc::protocol; +using namespace ppc::front; +using namespace ppc::crypto; +using namespace bcos; + +EcdhMultiPSICalculator::EcdhMultiPSICalculator( + EcdhMultiPSIConfig::Ptr _config, TaskState::Ptr _taskState) + : m_config(std::move(_config)), m_taskState(std::move(_taskState)) +{ + auto task = m_taskState->task(); + auto receivers = task->getReceiverLists(); + m_taskID = task->id(); + m_syncResult = (task->syncResultToPeer() && std::find(receivers.begin(), receivers.end(), + m_config->selfParty()) != receivers.end()); + m_calculatorCache = std::make_shared(m_taskState, m_syncResult, m_config); +} + +void EcdhMultiPSICalculator::asyncStartRunTask(ppc::protocol::Task::ConstPtr _task) +{ + initTask(_task); + auto randA = generateRandomA(_task->id()); + m_randomA = randA; + m_config->threadPool()->enqueue([self = weak_from_this(), _task, randA]() { + auto calculator = self.lock(); + if (!calculator) + { + return; + } + ECDH_CAL_LOG(INFO) << LOG_DESC("Calculator asyncStartRunTask as calculator"); + calculator->blindData(_task->id(), randA); + }); +} + +// PART1: Calculator -> Partners (randomValue) +bcos::bytes EcdhMultiPSICalculator::generateRandomA(std::string _taskID) +{ + ECDH_CAL_LOG(INFO) << LOG_KV("PART1: Calculator Start New Task :", _taskID); + auto randomValue = m_config->eccCrypto()->generateRandomScalar(); + // send to all partners + auto message = m_config->psiMsgFactory()->createPSIMessage( + uint32_t(EcdhMultiPSIMessageType::GENERATE_RANDOM_TO_PARTNER)); + message->setData(std::vector{randomValue}); + message->setDataBatchCount(randomValue.size()); + message->setFrom(m_taskState->task()->selfParty()->id()); + auto self = weak_from_this(); + for (auto const& partner : m_partnerParties) + { + ECDH_CAL_LOG(INFO) << LOG_DESC("send generateRandomA to partner") + << LOG_KV("partner", partner.first) + << LOG_KV(" Random: ", *toHexString(randomValue)); + m_config->generateAndSendPPCMessage( + partner.first, _taskID, message, + [self, _taskID, partner](bcos::Error::Ptr&& _error) { + if (!_error || _error->errorCode() == 0) + { + ECDH_CAL_LOG(INFO) + << LOG_DESC("send generated randomA to partner success") + << LOG_KV("task", _taskID) << LOG_KV("partner", partner.first); + return; + } + auto psi = self.lock(); + if (!psi) + { + return; + } + if (!psi->m_taskState) + { + return; + } + ECDH_CAL_LOG(WARNING) + << LOG_DESC("send generated randomA to partner failed") + << LOG_KV("task", _taskID) << LOG_KV("partner", partner.first) + << LOG_KV("code", _error->errorCode()) << LOG_KV("msg", _error->errorMessage()); + psi->m_taskState->onTaskException(_error->errorMessage()); + }, + 0); + } + return randomValue; +} + +// PART2: Calculator -> Master H(X)*A +void EcdhMultiPSICalculator::blindData(std::string _taskID, bcos::bytes _randA) +{ + try + { + ECDH_CAL_LOG(INFO) << LOG_DESC("blindData") << LOG_KV("task", _taskID); + auto reader = m_taskState->reader(); + uint64_t dataOffset = 0; + do + { + if (m_taskState->loadFinished() || m_taskState->taskDone()) + { + break; + } + DataBatch::Ptr dataBatch = nullptr; + uint32_t seq = 0; + { + bcos::Guard l(m_mutex); + // Note: next is not thread-safe + dataBatch = + m_taskState->reader()->next(m_taskState->readerParam(), DataSchema::Bytes); + if (!dataBatch) + { + ECDH_CAL_LOG(INFO) << LOG_DESC("blindData return for all data loaded") + << LOG_KV("task", _taskID); + m_taskState->setFinished(true); + break; + } + // allocate seq + seq = m_taskState->allocateSeq(); + if (m_taskState->sqlReader()) + { + m_taskState->setFinished(true); + } + } + m_calculatorCache->appendPlainData(dataBatch); + // encrypt + auto startT = utcSteadyTime(); + std::vector encryptedData(dataBatch->size()); + tbb::parallel_for( + tbb::blocked_range(0U, dataBatch->size()), [&](auto const& range) { + for (auto i = range.begin(); i < range.end(); i++) + { + auto const& data = dataBatch->get(i); + auto hashData = + m_config->hash()->hash(bcos::bytesConstRef(data.data(), data.size())); + auto point = m_config->eccCrypto()->hashToCurve(hashData); + encryptedData[i] = m_config->eccCrypto()->ecMultiply(point, _randA); + } + }); + ECDH_CAL_LOG(INFO) << LOG_DESC("blindData encrypt success") << LOG_KV("seq", seq) + << LOG_KV("dataSize", encryptedData.size()) + << LOG_KV("task", m_taskState->task()->id()) + << LOG_KV("timecost", (utcSteadyTime() - startT)); + ECDH_CAL_LOG(INFO) << LOG_DESC("blindData: send cipher to the master") + << LOG_KV("seq", seq) << LOG_KV("masterSize", m_masterParties.size()) + << LOG_KV("dataSize", encryptedData.size()) + << LOG_KV("task", m_taskState->task()->id()); + auto message = m_config->psiMsgFactory()->createPSIMessage( + uint32_t(EcdhMultiPSIMessageType::SEND_ENCRYPTED_SET_TO_MASTER_FROM_CALCULATOR)); + message->constructData(encryptedData, dataOffset); + // release the encryptedData + std::vector().swap(encryptedData); + message->setFrom(m_taskState->task()->selfParty()->id()); + if (reader->readFinished()) + { + message->setDataBatchCount(m_taskState->sendedDataBatchSize()); + } + else + { + // 0 means not finished + message->setDataBatchCount(0); + } + // send cipher + auto self = weak_from_this(); + for (auto const& master : m_masterParties) + { + m_config->generateAndSendPPCMessage( + master.first, _taskID, message, + [self, _taskID, master](bcos::Error::Ptr&& _error) { + if (!_error || _error->errorCode() == 0) + { + return; + } + auto psi = self.lock(); + if (!psi) + { + return; + } + ECDH_CAL_LOG(WARNING) + << LOG_DESC("send blindedData to master failed") + << LOG_KV("task", _taskID) << LOG_KV("master", master.first) + << LOG_KV("code", _error->errorCode()) + << LOG_KV("msg", _error->errorMessage()); + psi->m_taskState->onTaskException(_error->errorMessage()); + }, + seq); + dataOffset += dataBatch->size(); + } + } while (!m_taskState->sqlReader()); + } + catch (std::exception& e) + { + ECDH_CAL_LOG(WARNING) << LOG_DESC("Exception in blindData:") + << boost::diagnostic_information(e); + onTaskError(boost::diagnostic_information(e)); + } +} + + +void EcdhMultiPSICalculator::initTask(ppc::protocol::Task::ConstPtr _task) +{ + // Init all Roles from all Peers + auto peerParties = _task->getAllPeerParties(); + for (auto& party : peerParties) + { + auto partyId = party.first; + auto partySource = party.second; + if (partySource->partyIndex() == uint16_t(PartiesType::Calculator)) + { + m_calculatorParties[partyId] = partySource; + } + if (partySource->partyIndex() == uint16_t(PartiesType::Partner)) + { + m_partnerParties[partyId] = partySource; + } + if (partySource->partyIndex() == uint16_t(PartiesType::Master)) + { + m_masterParties[partyId] = partySource; + } + } +} + +// Part3: Calculator store Intersection_XY^b <- Master (response) +void EcdhMultiPSICalculator::onReceiveIntersecCipher(PSIMessageInterface::Ptr _msg) +{ + auto cipherData = _msg->takeData(); + auto const& dataIndex = _msg->dataIndex(); + ECDH_CAL_LOG(INFO) << LOG_DESC("onReceiveIntersecCipher") << printPSIMessage(_msg) + << LOG_KV("dataSize", cipherData.size()); + try + { + m_calculatorCache->addIntersectionCipher( + std::move(cipherData), dataIndex, _msg->seq(), _msg->dataBatchCount()); + auto message = m_config->psiMsgFactory()->createPSIMessage(uint32_t( + EcdhMultiPSIMessageType::RETURN_ENCRYPTED_INTERSECTION_SET_FROM_CALCULATOR_TO_MASTER)); + message->setFrom(m_taskState->task()->selfParty()->id()); + // try to finalize + auto ret = m_calculatorCache->tryToFinalize(); + auto taskID = m_taskID; + for (auto const& master : m_masterParties) + { + ECDH_CAL_LOG(INFO) << LOG_DESC("onReceiveIntersecCipher: send response to the master") + << LOG_KV("master", master.first) << printPSIMessage(_msg); + // no any bad influences when send response failed + m_config->generateAndSendPPCMessage( + master.first, taskID, message, + [taskID](bcos::Error::Ptr&& _error) { + if (!_error || _error->errorCode() == 0) + { + return; + } + ECDH_CAL_LOG(WARNING) + << LOG_DESC("onReceiveIntersecCipher: send response to the master failed") + << LOG_KV("task", taskID) << LOG_KV("code", _error->errorCode()) + << LOG_KV("msg", _error->errorMessage()); + }, + 0); + } + if (!ret) + { + return; + } + // return the rpc + m_taskState->setFinished(true); + m_taskState->onTaskFinished(); + } + catch (std::exception& e) + { + ECDH_CAL_LOG(WARNING) << LOG_DESC("Exception in onReceiveIntersecCipher:") + << boost::diagnostic_information(e); + onTaskError(boost::diagnostic_information(e)); + } +} + +// Part4 : Intersection_XY^b ∩ H(Z)^b^a +void EcdhMultiPSICalculator::onReceiveMasterCipher(PSIMessageInterface::Ptr _msg) +{ + try + { + auto cipher = _msg->takeData(); + ECDH_CAL_LOG(INFO) << LOG_DESC("onReceiveMasterCipher") << printPSIMessage(_msg) + << LOG_KV("cipher", cipher.size()); + std::vector encryptedCipher(cipher.size()); + tbb::parallel_for(tbb::blocked_range(0U, cipher.size()), [&](auto const& range) { + for (auto i = range.begin(); i < range.end(); i++) + { + encryptedCipher[i] = m_config->eccCrypto()->ecMultiply(cipher.at(i), m_randomA); + } + }); + // release the cipher + std::vector().swap(cipher); + + auto seq = _msg->seq(); + bool finished = m_calculatorCache->appendMasterCipher( + std::move(encryptedCipher), seq, _msg->dataBatchCount()); + if (finished == false) + { + return; + } + auto ret = m_calculatorCache->tryToFinalize(); + if (!ret) + { + return; + } + // return the rpc + m_taskState->setFinished(true); + m_taskState->onTaskFinished(); + } + catch (std::exception& e) + { + ECDH_CAL_LOG(WARNING) << LOG_DESC("Exception in onReceiveMasterCipher:") + << boost::diagnostic_information(e); + onTaskError(boost::diagnostic_information(e)); + } +} + + +void EcdhMultiPSICalculator::onTaskError(std::string&& _error) +{ + auto result = std::make_shared(m_taskState->task()->id()); + auto err = std::make_shared(-12222, _error); + result->setError(std::move(err)); + m_taskState->onTaskFinished(result, true); +} diff --git a/cpp/wedpr-computing/ppc-psi/src/ecdh-multi-psi/core/EcdhMultiPSICalculator.h b/cpp/wedpr-computing/ppc-psi/src/ecdh-multi-psi/core/EcdhMultiPSICalculator.h new file mode 100644 index 00000000..40250a17 --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/ecdh-multi-psi/core/EcdhMultiPSICalculator.h @@ -0,0 +1,78 @@ +#pragma once +#include "ppc-psi/src/ecdh-multi-psi/EcdhMultiCache.h" +#include "ppc-psi/src/ecdh-multi-psi/EcdhMultiPSIConfig.h" +#include "ppc-psi/src/psi-framework/TaskState.h" +#include + +namespace ppc::psi +{ +class EcdhMultiPSICalculator : public std::enable_shared_from_this +{ +public: + using Ptr = std::shared_ptr; + + EcdhMultiPSICalculator(EcdhMultiPSIConfig::Ptr _config, TaskState::Ptr _taskState); + + virtual ~EcdhMultiPSICalculator() + { + MallocExtension::instance()->ReleaseFreeMemory(); + ECDH_CAL_LOG(INFO) << LOG_DESC("the calculator destroyed") << LOG_KV("taskID", m_taskID); + } + + virtual void asyncStartRunTask(ppc::protocol::Task::ConstPtr _task); + virtual void onReceiveIntersecCipher(PSIMessageInterface::Ptr _msg); + virtual void onReceiveMasterCipher(PSIMessageInterface::Ptr _msg); + + const std::string& taskID() const { return m_taskID; } + +protected: + virtual bcos::bytes generateRandomA(std::string _taskID); + virtual void initTask(ppc::protocol::Task::ConstPtr _task); + virtual void blindData(std::string _taskID, bcos::bytes _randA); + virtual void onTaskError(std::string&& _error); + void ConcurrentSTLToCommon( + tbb::concurrent_map _cMap, std::map& result) + { + ConcurrentSTLToCommon(_cMap, 0, _cMap.size(), result); + }; + + void ConcurrentSTLToCommon(tbb::concurrent_map _cMap, + uint32_t _startIndex, uint32_t _endIndex, std::map& result) + { + std::mutex mutex; + tbb::concurrent_map::const_iterator iter; + uint32_t index = 0; + for (iter = _cMap.begin(); iter != _cMap.end(); iter++) + { + std::lock_guard lock(mutex); + if (index < _startIndex) + { + index++; + continue; + } + else if (index >= _endIndex) + { + break; + } + result.emplace(std::make_pair(iter->first, iter->second)); + // result.insert(std::make_pair(iter->first, iter->second)); + index++; + } + }; + + +private: + bool m_syncResult{false}; + EcdhMultiPSIConfig::Ptr m_config; + bcos::bytes m_randomA; + std::string m_taskID; + TaskState::Ptr m_taskState; + std::map m_calculatorParties; + std::map m_partnerParties; + std::map m_masterParties; + std::vector m_finalResults; + CalculatorCache::Ptr m_calculatorCache; + + mutable bcos::Mutex m_mutex; +}; +} // namespace ppc::psi \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-psi/src/ecdh-multi-psi/core/EcdhMultiPSIMaster.cpp b/cpp/wedpr-computing/ppc-psi/src/ecdh-multi-psi/core/EcdhMultiPSIMaster.cpp new file mode 100644 index 00000000..52632e4a --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/ecdh-multi-psi/core/EcdhMultiPSIMaster.cpp @@ -0,0 +1,251 @@ +#include "EcdhMultiPSIMaster.h" +#include "ppc-psi/src/ecdh-multi-psi/Common.h" +#include +#include + + +using namespace ppc::psi; +using namespace ppc::io; +using namespace ppc::protocol; +using namespace ppc::front; +using namespace ppc::crypto; +using namespace bcos; + +EcdhMultiPSIMaster::EcdhMultiPSIMaster(EcdhMultiPSIConfig::Ptr _config, TaskState::Ptr _taskState) + : m_config(std::move(_config)), m_taskState(std::move(_taskState)) +{ + auto task = m_taskState->task(); + auto receivers = task->getReceiverLists(); + m_taskID = task->id(); + m_masterCache = std::make_shared(m_taskState, m_config); + m_syncResult = (task->syncResultToPeer() && std::find(receivers.begin(), receivers.end(), + m_config->selfParty()) != receivers.end()); +} + +void EcdhMultiPSIMaster::asyncStartRunTask(ppc::protocol::Task::ConstPtr _task) +{ + ECDH_MASTER_LOG(INFO) << LOG_DESC("Master asyncStartRunTask") << printTaskInfo(_task); + initTask(_task); + auto B = m_config->eccCrypto()->generateRandomScalar(); + m_randomB = std::make_shared(B); + auto self = weak_from_this(); + m_config->threadPool()->enqueue([self]() { + auto master = self.lock(); + if (!master) + { + return; + } + ECDH_MASTER_LOG(INFO) << LOG_DESC("Master blindData") << LOG_KV("task", master->m_taskID); + master->blindData(); + }); +} + +void EcdhMultiPSIMaster::initTask(ppc::protocol::Task::ConstPtr _task) +{ + // Init all Roles from all Peers + auto peerParties = _task->getAllPeerParties(); + for (auto& party : peerParties) + { + auto partyId = party.first; + auto partySource = party.second; + if (partySource->partyIndex() == uint16_t(PartiesType::Calculator)) + { + m_calculatorParties[partyId] = partySource; + } + if (partySource->partyIndex() == uint16_t(PartiesType::Partner)) + { + m_partnerParties[partyId] = partySource; + } + if (partySource->partyIndex() == uint16_t(PartiesType::Master)) + { + m_masterParties[partyId] = partySource; + } + } +} + +// Part1-C,2-C: Master -> Calculator [H(X)*A ∩ H(Y)*A]*B +void EcdhMultiPSIMaster::onReceiveCalCipher(PSIMessageInterface::Ptr _msg) +{ + try + { + ECDH_MASTER_LOG(INFO) << LOG_DESC("onReceiveCalCipher") << printPSIMessage(_msg); + auto&& data = _msg->takeData(); + auto const& dataIndex = _msg->dataIndex(); + m_masterCache->addCalculatorCipher( + _msg->from(), std::move(data), dataIndex, _msg->seq(), _msg->dataBatchCount()); + auto ret = m_masterCache->tryToIntersection(); + if (!ret) + { + return; + } + m_masterCache->encryptIntersection(*m_randomB, m_calculatorParties); + } + catch (std::exception& e) + { + ECDH_MASTER_LOG(WARNING) << LOG_DESC("Exception in onReceiveCalCipher:") + << boost::diagnostic_information(e); + onTaskError(boost::diagnostic_information(e)); + } +} + +// Part1-P,2-P: Partner -> Master [H(X)*A ∩ H(Y)*A]*B +void EcdhMultiPSIMaster::onReceiveCipherFromPartner(PSIMessageInterface::Ptr _msg) +{ + try + { + ECDH_MASTER_LOG(INFO) << LOG_DESC("onReceiveCipherFromPartner") << printPSIMessage(_msg); + m_masterCache->addPartnerCipher( + _msg->from(), _msg->takeData(), _msg->seq(), _msg->dataBatchCount()); + auto ret = m_masterCache->tryToIntersection(); + if (!ret) + { + return; + } + m_masterCache->encryptIntersection(*m_randomB, m_calculatorParties); + } + catch (std::exception& e) + { + ECDH_MASTER_LOG(WARNING) << LOG_DESC("Exception in onReceiveCipherFromPartner:") + << boost::diagnostic_information(e); + onTaskError(boost::diagnostic_information(e)); + } +} + +// Part3: Master -> Calculator H(Z)*B +void EcdhMultiPSIMaster::blindData() +{ + try + { + ECDH_MULTI_LOG(INFO) << LOG_DESC("blindData") << LOG_KV("taskID", m_taskID); + auto startT = utcSteadyTime(); + auto reader = m_taskState->reader(); + do + { + if (m_taskState->loadFinished() || m_taskState->taskDone()) + { + break; + } + DataBatch::Ptr dataBatch = nullptr; + uint32_t seq = 0; + { + bcos::Guard l(m_mutex); + // Note: next is not thread-safe + dataBatch = + m_taskState->reader()->next(m_taskState->readerParam(), DataSchema::Bytes); + if (!dataBatch) + { + ECDH_CAL_LOG(INFO) << LOG_DESC("blindData return for all data loaded") + << LOG_KV("task", m_taskState->task()->id()); + m_taskState->setFinished(true); + break; + } + // allocate seq + seq = m_taskState->allocateSeq(); + if (m_taskState->sqlReader()) + { + m_taskState->setFinished(true); + } + } + auto startT = utcSteadyTime(); + ECDH_MASTER_LOG(INFO) << LOG_DESC("blindData: encrypt data") << LOG_KV("seq", seq) + << LOG_KV("task", m_taskState->task()->id()) + << LOG_KV("dataSize", dataBatch->size()); + std::vector cipher(dataBatch->size()); + tbb::parallel_for( + tbb::blocked_range(0U, dataBatch->size()), [&](auto const& range) { + for (auto i = range.begin(); i < range.end(); i++) + { + auto const& data = dataBatch->get(i); + auto hashData = + m_config->hash()->hash(bcos::bytesConstRef(data.data(), data.size())); + auto point = m_config->eccCrypto()->hashToCurve(hashData); + cipher[i] = m_config->eccCrypto()->ecMultiply(point, *m_randomB); + } + }); + // can release databatch after encrypted + dataBatch->release(); + // free after release + MallocExtension::instance()->ReleaseFreeMemory(); + ECDH_MASTER_LOG(INFO) << LOG_DESC("blindData: encrypt data success") + << LOG_KV("dataSize", cipher.size()) << LOG_KV("task", m_taskID) + << LOG_KV("seq", seq) + << LOG_KV("timecost", (utcSteadyTime() - startT)); + + ECDH_MASTER_LOG(INFO) << LOG_DESC("blindData: send encrypted data to all calculator") + << LOG_KV("seq", seq) << LOG_KV("task", m_taskID) + << LOG_KV("calculators", m_calculatorParties.size()); + auto message = m_config->psiMsgFactory()->createPSIMessage( + uint32_t(EcdhMultiPSIMessageType::SEND_ENCRYPTED_SET_TO_CALCULATOR)); + message->setData(cipher); + if (reader->readFinished()) + { + message->setDataBatchCount(m_taskState->sendedDataBatchSize()); + } + else + { + // 0 means not finished + message->setDataBatchCount(0); + } + message->setFrom(m_taskState->task()->selfParty()->id()); + auto self = weak_from_this(); + for (auto const& calcultor : m_calculatorParties) + { + m_config->generateAndSendPPCMessage( + calcultor.first, m_taskID, message, + [self, seq, calcultor](bcos::Error::Ptr&& _error) { + if (!_error || _error->errorCode() == 0) + { + return; + } + auto psi = self.lock(); + if (!psi) + { + return; + } + ECDH_MASTER_LOG(WARNING) + << LOG_DESC("send blindedData to calculator failed") + << LOG_KV("calculator", calcultor.first) << LOG_KV("seq", seq) + << LOG_KV("task", psi->m_taskState->task()->id()) + << LOG_KV("code", _error->errorCode()) + << LOG_KV("msg", _error->errorMessage()); + psi->m_taskState->onTaskException(_error->errorMessage()); + }, + seq); + } + } while (!m_taskState->sqlReader()); + } + catch (std::exception& e) + { + ECDH_MASTER_LOG(WARNING) << LOG_DESC("blindData exception") + << boost::diagnostic_information(e); + onTaskError(boost::diagnostic_information(e)); + } +} + +void EcdhMultiPSIMaster::onReceivePSIResult(PSIMessageInterface::Ptr _msg) +{ + ECDH_MASTER_LOG(INFO) << LOG_DESC("onReceivePSIResult") << printPSIMessage(_msg); + if (m_syncResult) + { + m_taskState->storePSIResult(m_config->dataResourceLoader(), _msg->takeData()); + ECDH_MASTER_LOG(INFO) << LOG_DESC("onReceivePSIResult: store psi result success") + << printPSIMessage(_msg); + } + else + { + ECDH_MASTER_LOG(INFO) << LOG_DESC("Master:No Need To store the psi result") + << printPSIMessage(_msg); + } + + m_taskState->setFinished(true); + m_taskState->onTaskFinished(); +} + + +void EcdhMultiPSIMaster::onTaskError(std::string&& _error) +{ + auto result = std::make_shared(m_taskState->task()->id()); + auto err = std::make_shared(-12222, _error); + result->setError(std::move(err)); + m_taskState->onTaskFinished(result, true); +} \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-psi/src/ecdh-multi-psi/core/EcdhMultiPSIMaster.h b/cpp/wedpr-computing/ppc-psi/src/ecdh-multi-psi/core/EcdhMultiPSIMaster.h new file mode 100644 index 00000000..2e684cca --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/ecdh-multi-psi/core/EcdhMultiPSIMaster.h @@ -0,0 +1,44 @@ +#pragma once +#include "ppc-psi/src/ecdh-multi-psi/EcdhMultiCache.h" +#include "ppc-psi/src/ecdh-multi-psi/EcdhMultiPSIConfig.h" +#include "ppc-psi/src/psi-framework/TaskState.h" +#include + +namespace ppc::psi +{ +class EcdhMultiPSIMaster : public std::enable_shared_from_this +{ +public: + using Ptr = std::shared_ptr; + EcdhMultiPSIMaster(EcdhMultiPSIConfig::Ptr _config, TaskState::Ptr _taskState); + virtual ~EcdhMultiPSIMaster() + { + MallocExtension::instance()->ReleaseFreeMemory(); + ECDH_MASTER_LOG(INFO) << LOG_DESC("the master destroyed") << LOG_KV("taskID", m_taskID); + } + virtual void asyncStartRunTask(ppc::protocol::Task::ConstPtr _task); + virtual void onReceiveCalCipher(PSIMessageInterface::Ptr _msg); + virtual void onReceiveCipherFromPartner(PSIMessageInterface::Ptr _msg); + virtual void blindData(); + virtual void onReceivePSIResult(PSIMessageInterface::Ptr _msg); + + const std::string& taskID() const { return m_taskID; } + +protected: + virtual void initTask(ppc::protocol::Task::ConstPtr _task); + virtual void onTaskError(std::string&& _error); + +private: + bool m_syncResult{false}; + std::map m_calculatorParties; + std::map m_partnerParties; + std::map m_masterParties; + std::string m_taskID; + TaskState::Ptr m_taskState; + EcdhMultiPSIConfig::Ptr m_config; + bcos::bytesPointer m_randomB; + MasterCache::Ptr m_masterCache; + + mutable bcos::Mutex m_mutex; +}; +} // namespace ppc::psi \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-psi/src/ecdh-multi-psi/core/EcdhMultiPSIPartner.cpp b/cpp/wedpr-computing/ppc-psi/src/ecdh-multi-psi/core/EcdhMultiPSIPartner.cpp new file mode 100644 index 00000000..67775c74 --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/ecdh-multi-psi/core/EcdhMultiPSIPartner.cpp @@ -0,0 +1,194 @@ +#include "EcdhMultiPSIPartner.h" +#include "ppc-psi/src/ecdh-multi-psi/Common.h" +#include + +using namespace ppc::psi; +using namespace ppc::io; +using namespace ppc::protocol; +using namespace ppc::front; +using namespace ppc::crypto; +using namespace bcos; + +EcdhMultiPSIPartner::EcdhMultiPSIPartner(EcdhMultiPSIConfig::Ptr _config, TaskState::Ptr _taskState) + : m_config(std::move(_config)), m_taskState(std::move(_taskState)) +{ + auto task = m_taskState->task(); + auto receivers = task->getReceiverLists(); + m_taskID = task->id(); + m_syncResult = (task->syncResultToPeer() && std::find(receivers.begin(), receivers.end(), + m_config->selfParty()) != receivers.end()); +} + +void EcdhMultiPSIPartner::initTask(ppc::protocol::Task::ConstPtr _task) +{ + // Init all Roles from all Peers + auto peerParties = _task->getAllPeerParties(); + for (auto& party : peerParties) + { + auto partyId = party.first; + auto partySource = party.second; + if (partySource->partyIndex() == uint16_t(PartiesType::Calculator)) + { + m_calculatorParties[partyId] = partySource; + } + if (partySource->partyIndex() == uint16_t(PartiesType::Partner)) + { + m_partnerParties[partyId] = partySource; + } + if (partySource->partyIndex() == uint16_t(PartiesType::Master)) + { + m_masterParties[partyId] = partySource; + } + } +} + +// PART1: Partner -> Master H(Y)*A +void EcdhMultiPSIPartner::onReceiveRandomA(bcos::bytesPointer _randA) +{ + try + { + ECDH_PARTNER_LOG(INFO) << LOG_DESC("onReceiveRandomA and blindData") + << printTaskInfo(m_taskState->task()); + auto reader = m_taskState->reader(); + uint64_t dataOffset = 0; + do + { + if (m_taskState->loadFinished() || m_taskState->taskDone()) + { + break; + } + DataBatch::Ptr dataBatch = nullptr; + uint32_t seq = 0; + { + bcos::Guard l(m_mutex); + // Note: next is not thread-safe + dataBatch = + m_taskState->reader()->next(m_taskState->readerParam(), DataSchema::Bytes); + if (!dataBatch) + { + ECDH_PARTNER_LOG(INFO) + << LOG_DESC("blindData: encode partner cipher return for all data loaded") + << LOG_KV("task", m_taskID); + m_taskState->setFinished(true); + break; + } + // allocate seq + seq = m_taskState->allocateSeq(); + if (m_taskState->sqlReader()) + { + m_taskState->setFinished(true); + } + } + ECDH_PARTNER_LOG(INFO) << LOG_DESC("blindData: encode parterner cipher") + << LOG_KV("size", dataBatch->size()) << LOG_KV("seq", seq) + << LOG_KV("task", m_taskState->task()->id()); + auto startT = utcSteadyTime(); + std::vector cipherData(dataBatch->size()); + tbb::parallel_for( + tbb::blocked_range(0U, dataBatch->size()), [&](auto const& range) { + for (auto i = range.begin(); i < range.end(); i++) + { + auto const& data = dataBatch->get(i); + auto hashData = + m_config->hash()->hash(bcos::bytesConstRef(data.data(), data.size())); + auto point = m_config->eccCrypto()->hashToCurve(hashData); + cipherData[i] = m_config->eccCrypto()->ecMultiply(point, *_randA); + } + }); + ECDH_PARTNER_LOG(INFO) + << LOG_DESC("blindData: encode parterner cipher success") << LOG_KV("seq", seq) + << LOG_KV("task", m_taskState->task()->id()) << LOG_KV("size", dataBatch->size()) + << LOG_KV("timecost", (utcSteadyTime() - startT)); + + ECDH_PARTNER_LOG(INFO) + << LOG_DESC("blindData: send cipher data to master") << LOG_KV("seq", seq) + << LOG_KV("size", dataBatch->size()) << LOG_KV("task", m_taskState->task()->id()); + auto message = m_config->psiMsgFactory()->createPSIMessage( + uint32_t(EcdhMultiPSIMessageType::SEND_ENCRYPTED_SET_TO_MASTER_FROM_PARTNER)); + message->setData(std::move(cipherData)); + message->setFrom(m_taskState->task()->selfParty()->id()); + if (reader->readFinished()) + { + message->setDataBatchCount(m_taskState->sendedDataBatchSize()); + } + else + { + // 0 means not finished + message->setDataBatchCount(0); + } + // generate and send encryptedHashSet + auto self = weak_from_this(); + for (auto const& master : m_masterParties) + { + m_config->generateAndSendPPCMessage( + master.first, m_taskState->task()->id(), message, + [self, master, seq](bcos::Error::Ptr&& _error) { + if (!_error || _error->errorCode() == 0) + { + return; + } + auto psi = self.lock(); + if (!psi) + { + return; + } + ECDH_PARTNER_LOG(WARNING) + << LOG_DESC("send blinded data to master failed") << LOG_KV("seq", seq) + << LOG_KV("master", master.first) + << LOG_KV("task", psi->m_taskState->task()->id()) + << LOG_KV("code", _error->errorCode()) + << LOG_KV("msg", _error->errorMessage()); + psi->m_taskState->onTaskException(_error->errorMessage()); + }, + seq); + } + ECDH_PARTNER_LOG(INFO) << LOG_DESC("blindData: send cipher data to master success") + << LOG_KV("size", dataBatch->size()) + << printTaskInfo(m_taskState->task()) << LOG_KV("seq", seq); + dataBatch->release(); + // free after release + MallocExtension::instance()->ReleaseFreeMemory(); + } while (!m_taskState->sqlReader()); + } + catch (std::exception& e) + { + ECDH_PARTNER_LOG(WARNING) << LOG_DESC("onReceiveRandomA exception") + << boost::diagnostic_information(e); + onTaskError(boost::diagnostic_information(e)); + } +} + +void EcdhMultiPSIPartner::onReceivePSIResult(PSIMessageInterface::Ptr _msg) +{ + ECDH_PARTNER_LOG(INFO) << LOG_DESC("onReceivePSIResult") << printPSIMessage(_msg); + if (m_syncResult) + { + m_taskState->storePSIResult(m_config->dataResourceLoader(), _msg->takeData()); + ECDH_PARTNER_LOG(INFO) << LOG_DESC("onReceivePSIResult: store psi result success") + << printPSIMessage(_msg); + } + else + { + ECDH_PARTNER_LOG(INFO) << LOG_DESC("Master:No Need To store the psi result") + << printPSIMessage(_msg); + } + m_taskState->setFinished(true); + m_taskState->onTaskFinished(); +} + + +void EcdhMultiPSIPartner::asyncStartRunTask(ppc::protocol::Task::ConstPtr _task) +{ + initTask(_task); + ECDH_PARTNER_LOG(INFO) << LOG_DESC("Partner asyncStartRunTask as partner") + << printTaskInfo(_task); +} + + +void EcdhMultiPSIPartner::onTaskError(std::string&& _error) +{ + auto result = std::make_shared(m_taskState->task()->id()); + auto err = std::make_shared(-12222, _error); + result->setError(std::move(err)); + m_taskState->onTaskFinished(result, true); +} diff --git a/cpp/wedpr-computing/ppc-psi/src/ecdh-multi-psi/core/EcdhMultiPSIPartner.h b/cpp/wedpr-computing/ppc-psi/src/ecdh-multi-psi/core/EcdhMultiPSIPartner.h new file mode 100644 index 00000000..b84fef03 --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/ecdh-multi-psi/core/EcdhMultiPSIPartner.h @@ -0,0 +1,42 @@ +#pragma once +#include "ppc-psi/src/ecdh-multi-psi/EcdhMultiPSIConfig.h" +#include "ppc-psi/src/psi-framework/TaskState.h" +#include + +namespace ppc::psi +{ +class EcdhMultiPSIPartner : public std::enable_shared_from_this +{ +public: + using Ptr = std::shared_ptr; + + EcdhMultiPSIPartner(EcdhMultiPSIConfig::Ptr _config, TaskState::Ptr _taskState); + + virtual ~EcdhMultiPSIPartner() + { + MallocExtension::instance()->ReleaseFreeMemory(); + ECDH_PARTNER_LOG(INFO) << LOG_DESC("the partner destroyed") << LOG_KV("taskID", m_taskID); + } + + virtual void onReceiveRandomA(bcos::bytesPointer _randA); + virtual void asyncStartRunTask(ppc::protocol::Task::ConstPtr _task); + virtual void onReceivePSIResult(PSIMessageInterface::Ptr _msg); + + const std::string& taskID() const { return m_taskID; } + +protected: + virtual void initTask(ppc::protocol::Task::ConstPtr _task); + virtual void onTaskError(std::string&& _error); + +private: + bool m_syncResult{false}; + EcdhMultiPSIConfig::Ptr m_config; + TaskState::Ptr m_taskState; + std::string m_taskID; + std::map m_calculatorParties; + std::map m_partnerParties; + std::map m_masterParties; + + mutable bcos::Mutex m_mutex; +}; +} // namespace ppc::psi \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-psi/src/ecdh-psi/CMakeLists.txt b/cpp/wedpr-computing/ppc-psi/src/ecdh-psi/CMakeLists.txt new file mode 100644 index 00000000..e3876908 --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/ecdh-psi/CMakeLists.txt @@ -0,0 +1,3 @@ +file(GLOB_RECURSE SRCS *.cpp) +add_library(${ECDH_2PC_PSI_TARGET} ${SRCS}) +target_link_libraries(${ECDH_2PC_PSI_TARGET} PUBLIC ${PSI_FRAMEWORK_TARGET} ${TOOLS_TARGET}) \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-psi/src/ecdh-psi/Common.h b/cpp/wedpr-computing/ppc-psi/src/ecdh-psi/Common.h new file mode 100644 index 00000000..a183cec4 --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/ecdh-psi/Common.h @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2022 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 Common.h + * @author: yujiechen + * @date 2022-12-27 + */ +#pragma once +#include "../Common.h" +#include "ppc-framework/Common.h" + +#define ECDH_LOG(LEVEL) BCOS_LOG(LEVEL) << LOG_BADGE("ECDH-PSI") \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-psi/src/ecdh-psi/EcdhCache.cpp b/cpp/wedpr-computing/ppc-psi/src/ecdh-psi/EcdhCache.cpp new file mode 100644 index 00000000..b20cc01d --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/ecdh-psi/EcdhCache.cpp @@ -0,0 +1,304 @@ +/* + * 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 EcdhCache.cpp + * @author: yujiechen + * @date 2023-1-6 + */ +#include "EcdhCache.h" +#include "gperftools/malloc_extension.h" + +using namespace ppc::psi; +using namespace ppc::io; + +void DataCache::setClientCipherData(std::vector&& _cipherData) +{ + if (m_state != CacheState::Evaluating) + { + return; + } + bcos::WriteGuard l(x_clientCipherData); + m_clientCipherData = std::move(_cipherData); + m_state = CacheState::Finalized; +} + +bool DataCache::tryToIntersectionAndStoreResult() +{ + try + { + bcos::RecursiveGuard l(m_mutex); + auto startT = bcos::utcSteadyTime(); + if (m_state != CacheState::Finalized) + { + return false; + } + // the server data has not been load finished + if (!m_serverCipherData->serverDataLoadFinished()) + { + return false; + } + m_state = CacheState::IntersectionProgressing; + auto const& serverCipherData = m_serverCipherData->serverCipherData(); + uint64_t offset = 0; + for (auto const& data : m_clientCipherData) + { + if (serverCipherData.count(data)) + { + m_intersectionData.emplace_back(m_plainData->getBytes(offset)); + } + offset++; + } + m_state = CacheState::Intersectioned; + ECDH_LOG(INFO) << LOG_DESC("tryToIntersectionAndStoreResult success") + << LOG_KV("intersections", m_intersectionData.size()) << printCurrentState() + << LOG_KV("timecost", (bcos::utcSteadyTime() - startT)); + // try to store psi-result + storePSIResult(); + return true; + } + catch (std::exception const& e) + { + ECDH_LOG(WARNING) << LOG_DESC("tryToIntersectionAndStoreResult exception") + << printCurrentState() << LOG_KV("msg", boost::diagnostic_information(e)); + m_taskState->onTaskException(boost::diagnostic_information(e)); + return false; + } +} + +void DataCache::storePSIResult() +{ + if (m_state != CacheState::Intersectioned) + { + return; + } + m_state = CacheState::Stored; + ECDH_LOG(INFO) << LOG_DESC("storePSIResult") << printCurrentState(); + m_taskState->storePSIResult(m_config->dataResourceLoader(), m_intersectionData); + if (m_taskState->task()->syncResultToPeer()) + { + syncPSIResult(); + return; + } + // update the taskState + m_taskState->eraseFinishedTaskSeq(m_seq, true); + m_state = CacheState::Synced; +} + +void DataCache::syncPSIResult() +{ + // sync the psi-result to the psi-server by dataBatchSize + auto self = weak_from_this(); + auto syncPSIResultMsg = + m_config->msgFactory()->createPSIMessage((uint64_t)PSIPacketType::PSIResultSyncMsg); + syncPSIResultMsg->setData(std::move(m_intersectionData)); + ECDH_LOG(INFO) << LOG_DESC("syncPSIResult") << printCurrentState(); + m_config->generateAndSendPPCMessage( + m_taskState->peerID(), m_taskState->task()->id(), syncPSIResultMsg, + [self](bcos::Error::Ptr&& _error) { + if (!_error || _error->errorCode() == 0) + { + return; + } + auto cache = self.lock(); + if (!cache) + { + return; + } + ECDH_LOG(WARNING) << LOG_DESC("syncPSIResult to peer error") + << LOG_KV("code", _error->errorCode()) + << LOG_KV("msg", _error->errorMessage()) + << printTaskInfo(cache->m_taskState->task()); + }, + m_seq, + [self](bcos::Error::Ptr _error, std::string const& _agencyID, + ppc::front::PPCMessageFace::Ptr _msg, ppc::front::ResponseFunc) { + bool success = true; + if (_error) + { + success = false; + ECDH_LOG(WARNING) << LOG_DESC("syncPSIResult to peer error") + << LOG_KV("code", _error->errorCode()) + << LOG_KV("msg", _error->errorMessage()); + } + ECDH_LOG(INFO) << LOG_DESC("syncPSIResult: receive response") + << LOG_KV("seq", _msg->seq()); + auto cache = self.lock(); + if (!cache) + { + return; + } + cache->m_state = CacheState::Synced; + cache->m_taskState->eraseFinishedTaskSeq(cache->m_seq, success); + }); +} + +ServerCipherDataCache::Ptr EcdhCache::insertServerCipherCache( + std::string const& _taskID, TaskState::Ptr const& _taskState) +{ + bcos::UpgradableGuard l(x_serverDataStore); + auto it = m_serverDataStore.find(_taskID); + if (it != m_serverDataStore.end()) + { + return it->second; + } + bcos::UpgradeGuard ul(l); + auto cache = std::make_shared(_taskID); + m_serverDataStore[_taskID] = cache; + return cache; +} + + +ServerCipherDataCache::Ptr EcdhCache::getServerCipherDataCache(std::string const& _taskID) +{ + bcos::ReadGuard l(x_serverDataStore); + auto it = m_serverDataStore.find(_taskID); + if (it != m_serverDataStore.end()) + { + return it->second; + } + return nullptr; +} + +DataCache::Ptr EcdhCache::insertSubTaskCache(std::string const& _taskID, uint32_t _seq, + TaskState::Ptr const& _taskState, ServerCipherDataCache::Ptr const& _serverCipherData, + ppc::io::DataBatch::Ptr&& _plainData) +{ + bcos::UpgradableGuard l(x_taskCache); + if (!m_taskCache.count(_taskID)) + { + std::map subTaskCache; + m_taskCache[_taskID] = subTaskCache; + } + auto it = m_taskCache.at(_taskID).find(_seq); + if (it != m_taskCache.at(_taskID).end()) + { + return it->second; + } + + auto cache = std::make_shared( + m_config, _taskID, _seq, _taskState, _serverCipherData, std::move(_plainData)); + bcos::UpgradeGuard ul(l); + m_taskCache[_taskID][_seq] = cache; + m_capacity += cache->capacity(); + return cache; +} + +DataCache::Ptr EcdhCache::getSubTaskCache(std::string const& _taskID, uint32_t _seq) const +{ + bcos::ReadGuard l(x_taskCache); + if (m_taskCache.count(_taskID) && m_taskCache.at(_taskID).count(_seq)) + { + return m_taskCache.at(_taskID).at(_seq); + } + return nullptr; +} + +void EcdhCache::tryToIntersectionAndStoreResult() +{ + bcos::WriteGuard l(x_taskCache); + for (auto it = m_taskCache.begin(); it != m_taskCache.end();) + { + auto& clientCipherCache = it->second; + for (auto pclientCipherCache = clientCipherCache.begin(); + pclientCipherCache != clientCipherCache.end();) + { + // Note: the cache must copy here in case of pclientCipherCache->second been erased + auto cache = pclientCipherCache->second; + // update the capacity and erase the finished sub-task + if (cache->state() == CacheState::Synced) + { + pclientCipherCache = clientCipherCache.erase(pclientCipherCache); + ECDH_LOG(INFO) << LOG_DESC( + "tryToIntersectionAndStoreResult: erase finished sub-task") + << cache->printCurrentState(); + if (m_capacity >= cache->capacity()) + { + m_capacity -= cache->capacity(); + } + else + { + m_capacity = 0; + } + continue; + } + if (cache->state() == CacheState::Finalized) + { + m_config->threadPool()->enqueue([cache]() { + // Note: the tryToIntersectionAndStoreResult should not throw exception + cache->tryToIntersectionAndStoreResult(); + }); + pclientCipherCache++; + continue; + } + pclientCipherCache++; + } + if (clientCipherCache.empty()) + { + it = m_taskCache.erase(it); + continue; + } + it++; + } +} + +void EcdhCache::eraseTaskCache(std::string const& _taskID) +{ + // erase the taskCache + // Note: here must using writeLock in case of the capacity been updated multiple times + bcos::WriteGuard l(x_taskCache); + if (!m_taskCache.count(_taskID)) + { + return; + } + ECDH_LOG(INFO) << LOG_DESC("eraseCache: erase the taskCache") << LOG_KV("taskID", _taskID); + // update the capacity + auto const& subTasks = m_taskCache.at(_taskID); + for (auto const& it : subTasks) + { + auto const& cache = it.second; + if (m_capacity >= cache->capacity()) + { + m_capacity -= cache->capacity(); + } + else + { + m_capacity = 0; + } + } + // erase the subTasks + m_taskCache.erase(_taskID); +} + +// Note: only when the task-finished can erase the cache +void EcdhCache::eraseCache(std::string const& _taskID) +{ + auto startT = bcos::utcSteadyTime(); + // Note: since the every DataCache references m_serverDataStore + // the m_serverDataStore only can be released after all the DataCache have been released + eraseTaskCache(_taskID); + // erase the server cipher data cache + bcos::UpgradableGuard l(x_serverDataStore); + if (!m_serverDataStore.count(_taskID)) + { + return; + } + ECDH_LOG(INFO) << LOG_DESC("eraseCache: erase the serverDataStore") + << LOG_KV("taskID", _taskID); + bcos::UpgradeGuard ul(l); + m_serverDataStore.erase(_taskID); + MallocExtension::instance()->ReleaseFreeMemory(); + ECDH_LOG(INFO) << LOG_DESC("eraseCache") << LOG_KV("taskID", _taskID) + << LOG_KV("timecost", (bcos::utcSteadyTime() - startT)); +} diff --git a/cpp/wedpr-computing/ppc-psi/src/ecdh-psi/EcdhCache.h b/cpp/wedpr-computing/ppc-psi/src/ecdh-psi/EcdhCache.h new file mode 100644 index 00000000..5fd7010a --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/ecdh-psi/EcdhCache.h @@ -0,0 +1,206 @@ +/* + * Copyright (C) 2022 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 EcdhCache.h + * @author: yujiechen + * @date 2022-12-28 + */ +#pragma once +#include "../psi-framework/TaskState.h" +#include "Common.h" +#include "EcdhPSIConfig.h" +#include +#include +namespace ppc::psi +{ +/// the server data-cache +class ServerCipherDataCache +{ +public: + using Ptr = std::shared_ptr; + ServerCipherDataCache(std::string const& _taskID) : m_taskID(_taskID) {} + virtual ~ServerCipherDataCache() + { + // release the memory + std::set().swap(m_serverCipherData); + } + + void setServerDataBatchCount(int64_t _serverDataBatchCount) + { + m_serverDataBatchCount = _serverDataBatchCount; + if ((int64_t)m_serverDataSeqList.size() == m_serverDataBatchCount) + { + m_serverDataLoadFinished = true; + } + } + + virtual void appendServerCipherData(uint32_t _seq, std::vector&& _cipherData) + { + bcos::WriteGuard l(x_serverCipherData); + if (m_serverDataSeqList.count(_seq)) + { + return; + } + for (auto& it : _cipherData) + { + m_serverCipherData.insert(std::move(it)); + } + m_serverDataSeqList.insert(_seq); + if ((int64_t)m_serverDataSeqList.size() == m_serverDataBatchCount) + { + m_serverDataLoadFinished = true; + } + } + + bool serverDataLoadFinished() { return m_serverDataLoadFinished; } + std::set const& serverCipherData() const { return m_serverCipherData; } + +private: + std::string m_taskID; + bool m_serverDataLoadFinished = false; + + // store the cipher-data of the server + // TODO: replace with unordered_set + std::set m_serverCipherData; + std::set m_serverDataSeqList; + bcos::SharedMutex x_serverCipherData; + std::atomic m_serverDataBatchCount = {-1}; +}; + +class DataCache : public std::enable_shared_from_this +{ +public: + using Ptr = std::shared_ptr; + // set the plainData here for obtain the plain intersection + DataCache(EcdhPSIConfig::Ptr const& _config, std::string const& _taskID, uint32_t _seq, + TaskState::Ptr const& _taskState, ServerCipherDataCache::Ptr const& _serverCipherData, + ppc::io::DataBatch::Ptr&& _plainData) + : m_config(_config), + m_taskID(_taskID), + m_seq(_seq), + m_taskState(_taskState), + m_state(CacheState::Evaluating), + m_serverCipherData(_serverCipherData), + m_plainData(std::move(_plainData)) + { + m_capacity = m_plainData->capacityBytes(); + // for m_clientCipherData + m_capacity += m_plainData->size() * 32; + } + virtual ~DataCache() + { + // release the memory + m_plainData = nullptr; + std::vector().swap(m_clientCipherData); + std::vector().swap(m_intersectionData); + } + virtual void setClientCipherData(std::vector&& _cipherData); + virtual bool tryToIntersectionAndStoreResult(); + std::string const& taskID() const { return m_taskID; } + + CacheState state() const { return m_state; } + + uint64_t capacity() const { return m_capacity; } + + inline std::string printCurrentState() + { + std::ostringstream stringstream; + stringstream << LOG_KV("task", m_taskID) << LOG_KV("seq", m_seq) + << LOG_KV("plainData", m_plainData ? m_plainData->size() : 0) + << LOG_KV("clientCipherData", m_clientCipherData.size()) + << LOG_KV("intersectionData", m_intersectionData.size()) + << LOG_KV("state", m_state); + return stringstream.str(); + } + +private: + void storePSIResult(); + void syncPSIResult(); + +private: + EcdhPSIConfig::Ptr m_config; + std::string m_taskID; + // the sub-task seq + uint32_t m_seq; + TaskState::Ptr m_taskState; + + CacheState m_state; + + uint64_t m_capacity; + + // the server cipher data cache + ServerCipherDataCache::Ptr m_serverCipherData; + + // the plainData + ppc::io::DataBatch::Ptr m_plainData; + // the cipher-data of the client + std::vector m_clientCipherData; + bcos::SharedMutex x_clientCipherData; + + // the intersection data + std::vector m_intersectionData; + + mutable bcos::RecursiveMutex m_mutex; +}; + +class EcdhCache : public std::enable_shared_from_this +{ +public: + using Ptr = std::shared_ptr; + EcdhCache(EcdhPSIConfig::Ptr const& _config, uint64_t _maxCacheSize = 1024 * 1024 * 1024) + : m_config(_config), m_maxTaskCacheSize(_maxCacheSize) + {} + virtual ~EcdhCache() = default; + + // insert the server-cipher-data-cache + virtual ServerCipherDataCache::Ptr insertServerCipherCache( + std::string const& _taskID, TaskState::Ptr const& _taskState); + // get the server cipher data cache + virtual ServerCipherDataCache::Ptr getServerCipherDataCache(std::string const& _taskID); + + // insert data-cache into m_taskCache + virtual DataCache::Ptr insertSubTaskCache(std::string const& _taskID, uint32_t _seq, + TaskState::Ptr const& _taskState, ServerCipherDataCache::Ptr const& _serverCipherData, + ppc::io::DataBatch::Ptr&& _plainData); + + DataCache::Ptr getSubTaskCache(std::string const& _taskID, uint32_t _seq) const; + // Note: only when the task-finished can erase the cache + virtual void eraseCache(std::string const& _taskID); + virtual void tryToIntersectionAndStoreResult(); + + bool isFull() { return m_capacity >= m_maxTaskCacheSize; } + + uint64_t capacity() const { return m_capacity; } + +private: + void eraseTaskCache(std::string const& _taskID); + +private: + EcdhPSIConfig::Ptr m_config; + + uint64_t m_maxTaskCacheSize; + // the capacity for sub-task + // Note: the intersection-data and cipherDataStore may occupy some memory + std::atomic m_capacity = {0}; + + // taskID => seq => sub-task-data + std::map> m_taskCache; + mutable bcos::SharedMutex x_taskCache; + + // taskID => the server cipher data + std::map m_serverDataStore; + mutable bcos::SharedMutex x_serverDataStore; +}; +} // namespace ppc::psi \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-psi/src/ecdh-psi/EcdhPSIConfig.h b/cpp/wedpr-computing/ppc-psi/src/ecdh-psi/EcdhPSIConfig.h new file mode 100644 index 00000000..f7ec036d --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/ecdh-psi/EcdhPSIConfig.h @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2022 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 EcdhPSIConfig.h + * @author: yujiechen + * @date 2022-12-26 + */ +#pragma once +#include "../PSIConfig.h" +#include "../psi-framework/interfaces/PSIMessageFactory.h" +#include "ppc-framework/crypto/ECDHCrypto.h" +#include "ppc-framework/protocol/Protocol.h" +#include + +namespace ppc::psi +{ +class EcdhPSIConfig : public PSIConfig +{ +public: + using Ptr = std::shared_ptr; + EcdhPSIConfig(std::string const& _selfParty, + ppc::crypto::ECDHCryptoFactory::Ptr const& _ecdhCryptoFactory, + ppc::front::FrontInterface::Ptr _front, + ppc::front::PPCMessageFaceFactory::Ptr _ppcMsgFactory, + PSIMessageFactory::Ptr const& _msgFactory, + ppc::io::DataResourceLoader::Ptr const& _dataResourceLoader, uint32_t _dataBatchSize, + int _holdingMessageMinutes, uint32_t minNeededMemoryGB = 1, + bcos::ThreadPool::Ptr const& _threadPool = nullptr, + int _threadPoolSize = std::thread::hardware_concurrency()) + : PSIConfig(ppc::protocol::TaskAlgorithmType::ECDH_PSI_2PC, _selfParty, _front, + _ppcMsgFactory, _dataResourceLoader, _holdingMessageMinutes, minNeededMemoryGB), + m_msgFactory(_msgFactory), + m_threadPool(_threadPool), + m_ecdhCryptoFactory(_ecdhCryptoFactory), + m_dataBatchSize(_dataBatchSize) + { + if (!m_threadPool) + { + m_threadPool = std::make_shared("ecdh-pool", _threadPoolSize); + } + } + ~EcdhPSIConfig() override + { + if (m_threadPool) + { + m_threadPool->stop(); + } + } + + PSIMessageFactory::Ptr const& msgFactory() const { return m_msgFactory; } + bcos::ThreadPool::Ptr const& threadPool() const { return m_threadPool; } + ppc::crypto::ECDHCryptoFactory::Ptr const& ecdhCryptoFactory() const + { + return m_ecdhCryptoFactory; + } + + uint32_t dataBatchSize() const { return m_dataBatchSize; } + +private: + PSIMessageFactory::Ptr m_msgFactory; + bcos::ThreadPool::Ptr m_threadPool; + ppc::crypto::ECDHCryptoFactory::Ptr m_ecdhCryptoFactory; + + uint32_t m_dataBatchSize = 10000; +}; +} // namespace ppc::psi \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-psi/src/ecdh-psi/EcdhPSIFactory.cpp b/cpp/wedpr-computing/ppc-psi/src/ecdh-psi/EcdhPSIFactory.cpp new file mode 100644 index 00000000..670c8347 --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/ecdh-psi/EcdhPSIFactory.cpp @@ -0,0 +1,42 @@ +/** + * Copyright (C) 2022 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 EcdhPSIFactory.cpp + * @author: yujiechen + * @date 2022-12-28 + */ +#include "EcdhPSIFactory.h" +#include "EcdhPSIMessageFactory.h" +#include "ppc-tools/src/config/PPCConfig.h" +#include + +using namespace ppc::psi; +using namespace ppc::tools; +using namespace ppc::front; +using namespace ppc::crypto; +using namespace ppc::io; + +EcdhPSIImpl::Ptr EcdhPSIFactory::createEcdhPSI(PPCConfig::Ptr const& _ppcConfig, + ECDHCryptoFactory::Ptr const& _ecdhCryptoFactory, FrontInterface::Ptr _front, + PPCMessageFaceFactory::Ptr _ppcMsgFactory, bcos::ThreadPool::Ptr _threadPool, + DataResourceLoader::Ptr const& _dataResourceLoader, uint32_t minNeededMemoryGB) +{ + auto psiMsgFactory = std::make_shared(); + auto const& ecdhParam = _ppcConfig->ecdhPSIConfig(); + auto config = std::make_shared(_ppcConfig->agencyID(), _ecdhCryptoFactory, + _front, _ppcMsgFactory, psiMsgFactory, _dataResourceLoader, ecdhParam.dataBatchSize, + _ppcConfig->holdingMessageMinutes(), minNeededMemoryGB, _threadPool); + return std::make_shared(config); +} diff --git a/cpp/wedpr-computing/ppc-psi/src/ecdh-psi/EcdhPSIFactory.h b/cpp/wedpr-computing/ppc-psi/src/ecdh-psi/EcdhPSIFactory.h new file mode 100644 index 00000000..08775356 --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/ecdh-psi/EcdhPSIFactory.h @@ -0,0 +1,43 @@ +/** + * Copyright (C) 2022 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 EcdhPSIFactory.h + * @author: yujiechen + * @date 2022-12-28 + */ +#pragma once +#include "EcdhPSIImpl.h" +#include +namespace ppc::tools +{ +class PPCConfig; +} +namespace ppc::psi +{ +class EcdhPSIFactory +{ +public: + using Ptr = std::shared_ptr; + EcdhPSIFactory() = default; + virtual ~EcdhPSIFactory() = default; + + virtual EcdhPSIImpl::Ptr createEcdhPSI(std::shared_ptr const& _ppcConfig, + ppc::crypto::ECDHCryptoFactory::Ptr const& _ecdhCryptoFactory, + ppc::front::FrontInterface::Ptr _front, + ppc::front::PPCMessageFaceFactory::Ptr _ppcMsgFactory, bcos::ThreadPool::Ptr _threadPool, + ppc::io::DataResourceLoader::Ptr const& _dataResourceLoader, + uint32_t minNeededMemoryGB = 1); +}; +} // namespace ppc::psi \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-psi/src/ecdh-psi/EcdhPSIImpl.cpp b/cpp/wedpr-computing/ppc-psi/src/ecdh-psi/EcdhPSIImpl.cpp new file mode 100644 index 00000000..3aa192bc --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/ecdh-psi/EcdhPSIImpl.cpp @@ -0,0 +1,781 @@ +/* + * Copyright (C) 2022 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 EcdhPSIImpl.cpp + * @author: yujiechen + * @date 2022-12-27 + */ +#include "EcdhPSIImpl.h" +#include "ppc-framework/protocol/GlobalConfig.h" + +using namespace ppc::psi; +using namespace ppc::protocol; +using namespace ppc::crypto; +using namespace ppc::io; +using namespace bcos; +using namespace ppc::task; + +void EcdhPSIImpl::asyncRunTask( + ppc::protocol::Task::ConstPtr _task, TaskResponseCallback&& _onTaskFinished) +{ + try + { + // check the partyIndex + auto partyIndex = _task->selfParty()->partyIndex(); + if (partyIndex != (int)PartyType::Client && partyIndex != (int)PartyType::Server) + { + auto taskResult = std::make_shared(_task->id()); + auto error = BCOS_ERROR_PTR((int)TaskParamsError, + "The party index of the ecdh-psi must be client(0) or server(1)!"); + ECDH_LOG(WARNING) << LOG_DESC("response task result") << LOG_KV("task", _task) + << LOG_KV("code", error->errorCode()) + << LOG_KV("msg", error->errorMessage()); + taskResult->setError(std::move(error)); + _onTaskFinished(std::move(taskResult)); + return; + } + // create the taskState + auto self = weak_from_this(); + auto taskState = m_taskStateFactory->createTaskState( + _task, [self, _task, _onTaskFinished](TaskResult::Ptr&& _result) { + auto result = std::move(_result); + _onTaskFinished(std::move(result)); + ECDH_LOG(INFO) << LOG_DESC("asyncRunTask finished") << printTaskInfo(_task); + }); + auto const& taskID = _task->id(); + taskState->registerFinalizeHandler([self, taskID]() { + auto psi = self.lock(); + if (!psi) + { + return; + } + // erase the cache + psi->m_cache->eraseCache(taskID); + // erase the taskInfo from the gateway + psi->m_config->front()->eraseTaskInfo(taskID); + }); + // Note: ecdh-psi with only run-psi command + auto error = lockResourceAndRecordTaskState(0, taskState); + if (error) + { + // trigger the callback + auto taskResult = std::make_shared(_task->id()); + ECDH_LOG(WARNING) << LOG_DESC("response task result") << LOG_KV("task", _task) + << LOG_KV("code", error->errorCode()) + << LOG_KV("msg", error->errorMessage()); + taskResult->setError(std::move(error)); + _onTaskFinished(std::move(taskResult)); + return; + } + // set the peerID + auto peerParty = checkAndSetPeerInfo(taskState, false); + if (!peerParty) + { + return; + } + auto const& peerID = peerParty->id(); + // check the dataResource + bool server = (partyIndex == (int)PartyType::Server) ? true : false; + if (!checkDataResourceForSelf(taskState, peerID, !server)) + { + return; + } + taskState->registerSubTaskFinishedHandler([self]() { + auto psi = self.lock(); + if (!psi) + { + return; + } + // tryToIntersectionAndStoreResult will erase the finished task, update the capacity and + // trigger next-round data-blinding + psi->m_cache->tryToIntersectionAndStoreResult(); + psi->wakeupWorker(); + }); + auto ret = initTaskState(taskState); + if (ret) + { + runPSI(taskState); + } + } + catch (std::exception const& e) + { + ECDH_LOG(WARNING) << LOG_DESC("asyncRunTask exception, cancel the task") + << printTaskInfo(_task) + << LOG_KV("msg", boost::diagnostic_information(e)); + auto error = std::make_shared( + -1, "asyncRunTask " + _task->id() + " exception: " + boost::diagnostic_information(e)); + cancelTask(std::move(error), _task->id()); + } +} + +void EcdhPSIImpl::runPSI(TaskState::Ptr const& _taskState) +{ + ECDH_LOG(INFO) << LOG_DESC("runPSI") << printTaskInfo(_taskState->task()); + // notify the taskInfo to the front + m_config->front()->notifyTaskInfo(_taskState->task()->id()); + // the psi-client send handshake request to the server + if (_taskState->task()->selfParty()->partyIndex() == (int)PartyType::Client) + { + sendHandshakeRequest(_taskState); + } +} + +// handle the psi message +void EcdhPSIImpl::handlePSIMsg(PSIMessageInterface::Ptr _msg) +{ + if (!checkPSIMsg(_msg)) + { + return; + } + // prioritize lightweight messages + if (handlePSIFrameworkMsg(_msg)) + { + return; + } + auto self = weak_from_this(); + m_config->threadPool()->enqueue([self, _msg]() { + auto psi = self.lock(); + if (!psi) + { + return; + } + try + { + switch (_msg->packetType()) + { + case (uint32_t)ECDHPacketType::EvaluateRequest: + { + psi->handleEvaluateRequest(_msg); + break; + } + case (uint32_t)ECDHPacketType::EvaluateResponse: + { + psi->handleEvaluateResponse(_msg); + break; + } + case (uint32_t)ECDHPacketType::ServerBlindedData: + { + psi->handleServerBlindData(_msg); + break; + } + case (uint32_t)ECDHPacketType::SyncDataBatchInfo: + { + psi->onRecvSyncDataInfoMsg(_msg); + break; + } + default: + { + ECDH_LOG(ERROR) << LOG_DESC("Unsupported packetType ") << (int)_msg->packetType(); + break; + } + } + } + catch (std::exception const& e) + { + ECDH_LOG(ERROR) << LOG_DESC("handlePSIMsg exception") + << LOG_KV("packetType", _msg->packetType()) << printPSIMessage(_msg) + << LOG_KV("error", boost::diagnostic_information(e)); + + auto error = BCOS_ERROR_PTR((int)PSIRetCode::HandleTaskError, + "Task " + _msg->taskID() + " error for " + boost::diagnostic_information(e)); + psi->onTaskError("handlePSIMsg", std::move(error), _msg->from(), _msg->taskID(), + "emptyDataResource"); + } + }); +} + +bool EcdhPSIImpl::initTaskState(TaskState::Ptr const& _taskState) +{ + auto task = _taskState->task(); + auto dataResource = task->selfParty()->dataResource(); + bool server = (task->selfParty()->partyIndex() == (int)PartyType::Server) ? true : false; + try + { + // the client + if (!server) + { + m_cache->insertServerCipherCache(task->id(), _taskState); + if (!_taskState->task()->enableOutputExists()) + { + // Note: if the output-resource already exists, will throw exception + m_config->dataResourceLoader()->checkResourceExists(dataResource->outputDesc()); + } + else + { + m_config->dataResourceLoader()->loadWriter(dataResource->outputDesc(), true); + } + } + else if (_taskState->task()->syncResultToPeer()) + { + // check the output resource existence when syncResultToPeer + _taskState->tryToGenerateDefaultOutputDesc(); + m_config->dataResourceLoader()->checkResourceExists( + task->selfParty()->dataResource()->outputDesc()); + } + // load the data + auto reader = loadData(m_config->dataResourceLoader(), task->id(), dataResource); + // Note: the sql read all data at one time + auto sqlReader = (reader->type() == ppc::protocol::DataResourceType::MySQL); + // fileReader: load dataBatchSize() elements from the given file + // sqlReader: load the first column + auto nextParam = sqlReader ? 0 : m_config->dataBatchSize(); + _taskState->setReader(std::move(reader), nextParam); + ECDH_LOG(INFO) << LOG_DESC("initTaskState") << printTaskInfo(task); + return true; + } + catch (std::exception const& e) + { + ECDH_LOG(WARNING) << LOG_DESC("initTaskState exception") + << LOG_KV("msg", boost::diagnostic_information(e)); + auto error = BCOS_ERROR_PTR((int)PSIRetCode::HandleTaskError, + "init task error for " + boost::diagnostic_information(e)); + onTaskError("initTaskState", std::move(error), _taskState->peerID(), task->id(), + dataResource ? dataResource->resourceID() : "emptyDataResource"); + return false; + } +} + +// the psi-server and psi-client load data from DataResource and blind the plainData into cipher +void EcdhPSIImpl::blindData(TaskState::Ptr const& _taskState) +{ + auto startT = utcSteadyTime(); + auto task = _taskState->task(); + bool server = (task->selfParty()->partyIndex() == (int)PartyType::Server) ? true : false; + // the client cache is full + if (!server && m_cache->isFull()) + { + return; + } + auto dataResource = task->selfParty()->dataResource(); + uint32_t packetType = (int32_t)ECDHPacketType::EvaluateRequest; + if (server) + { + packetType = (int32_t)ECDHPacketType::ServerBlindedData; + } + // load all data from the given resource + uint64_t batchDataCount = 0; + auto self = weak_from_this(); + auto const& taskID = task->id(); + auto serverCipherDataCache = m_cache->getServerCipherDataCache(taskID); + do + { + // the task has been canceled + if (!getTaskByID(taskID)) + { + // erase the cache and return + m_cache->eraseCache(taskID); + return; + } + // not to blind when the cache is Full + if (!server && m_cache->isFull()) + { + ECDH_LOG(TRACE) << LOG_DESC("blindData return for the cache is full") + << LOG_KV("capacity", m_cache->capacity()); + break; + } + if (_taskState->loadFinished()) + { + break; + } + int32_t seq = 0; + DataBatch::Ptr dataBatch = nullptr; + { + bcos::Guard l(m_mutex); + // Note: next is not thread-safe + dataBatch = _taskState->reader()->next(_taskState->readerParam(), DataSchema::Bytes); + if (!dataBatch) + { + _taskState->setFinished(true); + break; + } + // allocate seq + seq = _taskState->allocateSeq(); + if (_taskState->sqlReader()) + { + _taskState->setFinished(true); + } + } + auto ecdhTaskState = std::dynamic_pointer_cast(_taskState); + auto batchPk = ecdhTaskState->ecdhCrypto()->batchGetPublicKey(dataBatch); + + auto evaluateRequest = m_config->msgFactory()->createPSIMessage(packetType); + evaluateRequest->setData(std::move(batchPk)); + evaluateRequest->setResourceID(dataResource->resourceID()); + auto dataBatchSize = dataBatch->size(); + // the client should append the plainData into cache for get the plainData later + if (!server) + { + m_cache->insertSubTaskCache( + taskID, seq, _taskState, serverCipherDataCache, std::move(dataBatch)); + } + ECDH_LOG(INFO) << LOG_DESC("blindData") << LOG_KV("resource", dataResource->resourceID()) + << LOG_KV("seq", seq) << LOG_KV("size", dataBatchSize) + << LOG_KV("cacheCapacity", m_cache->capacity()) + << LOG_KV("task", _taskState->task()->id()); + auto sendT = utcSteadyTime(); + m_config->generateAndSendPPCMessage( + _taskState->peerID(), _taskState->task()->id(), evaluateRequest, + [self, seq, _taskState, sendT](Error::Ptr&& _error) { + if (!_error) + { + ECDH_LOG(INFO) << LOG_DESC("blindData: send evaluate request success") + << LOG_KV("seq", seq); + return; + } + auto psi = self.lock(); + if (!psi) + { + return; + } + ECDH_LOG(WARNING) << LOG_DESC("blindData: send evaluate request error") + << LOG_KV("seq", seq) << LOG_KV("code", _error->errorCode()) + << LOG_KV("msg", _error->errorMessage()) + << LOG_KV("timecost", (utcSteadyTime() - sendT)); + psi->cancelTask(std::move(_error), _taskState->task()->id()); + }, + seq); + batchDataCount++; + } while (m_started && !_taskState->sqlReader()); + if (!server) + { + return; + } + // the server send dataBatchCount to client + ECDH_LOG(INFO) << LOG_DESC("blindData: sync the server-data-batch-count") + << LOG_KV("batchDataCount", batchDataCount); + auto req = + m_config->msgFactory()->createPSIMessage((uint32_t)ECDHPacketType::SyncDataBatchInfo); + req->setDataBatchCount(batchDataCount); + req->setResourceID(dataResource->resourceID()); + m_config->generateAndSendPPCMessage(_taskState->peerID(), _taskState->task()->id(), req, + [self, _taskState](Error::Ptr&& _error) { + if (!_error) + { + return; + } + auto psi = self.lock(); + if (!psi) + { + return; + } + ECDH_LOG(WARNING) << LOG_DESC("blindData: send SyncDataBatchInfo request error") + << LOG_KV("code", _error->errorCode()) + << LOG_KV("msg", _error->errorMessage()); + // cancel the task + psi->cancelTask(std::move(_error), _taskState->task()->id()); + }); + ECDH_LOG(INFO) << LOG_DESC("blindData success") << printTaskInfo(_taskState->task()) + << LOG_KV("timecost", (utcSteadyTime() - startT)); +} + +// receive the blinded-data from client, the psi-server response the evaluated data +void EcdhPSIImpl::handleEvaluateRequest(PSIMessageInterface::Ptr _msg) +{ + auto ret = checkAndObtainTaskState(_msg); + if (!ret.first || !ret.second) + { + return; + } + auto taskState = ret.first; + auto ecdhCrypto = ret.second; + auto startT = utcSteadyTime(); + ECDH_LOG(INFO) << LOG_DESC("handleEvaluateRequest") << printPSIMessage(_msg); + auto sharedPk = ecdhCrypto->batchGetSharedPublicKey(_msg->takeData()); + // response the evaluated result + auto evaluateResponse = + m_config->msgFactory()->createPSIMessage((uint32_t)ECDHPacketType::EvaluateResponse); + evaluateResponse->setData(std::move(sharedPk)); + auto self = weak_from_this(); + auto startSendT = utcSteadyTime(); + m_config->generateAndSendPPCMessage( + _msg->from(), _msg->taskID(), evaluateResponse, + [self, _msg, startSendT](Error::Ptr&& _error) { + if (!_error) + { + return; + } + auto psi = self.lock(); + if (!psi) + { + return; + } + ECDH_LOG(WARNING) << LOG_DESC("handleEvaluateRequest: send evaluate response error") + << printPSIMessage(_msg) << LOG_KV("code", _error->errorCode()) + << LOG_KV("msg", _error->errorMessage()) + << LOG_KV("timecost", utcSteadyTime() - startSendT); + psi->onTaskError("handleEvaluateRequest: response evaluate data", std::move(_error), + _msg->from(), _msg->taskID(), _msg->resourceID()); + }, + _msg->seq()); + ECDH_LOG(INFO) << LOG_DESC("handleEvaluateRequest success") << printPSIMessage(_msg) + << LOG_KV("timecost", (utcSteadyTime() - startT)); +} + +std::pair EcdhPSIImpl::checkAndObtainTaskState( + PSIMessageInterface::Ptr _msg) +{ + auto taskState = getTaskByID(_msg->taskID()); + if (!taskState) + { + auto error = BCOS_ERROR_PTR((int)PSIRetCode::TaskNotFound, + "Task " + _msg->taskID() + " not found when handle server blinded-data!"); + onTaskError("handleServerBlindData", std::move(error), _msg->from(), _msg->taskID(), + "emptyDataResource"); + return std::make_pair(nullptr, nullptr); + } + auto ecdhTaskState = std::dynamic_pointer_cast(taskState); + // here the client maybe not ready for the ecdhCrypto when submit the multiple-tasks with same + // taskID and some tasks failed + if (!ecdhTaskState->ecdhCrypto()) + { + auto error = BCOS_ERROR_PTR((int)PSIRetCode::TaskNotReady, + "The ecdh-crypto-suite is not ready for task " + _msg->taskID() + + " not found when handle server blinded-data!"); + onTaskError("handleServerBlindData", std::move(error), _msg->from(), _msg->taskID(), + "emptyDataResource"); + return std::make_pair(nullptr, nullptr); + } + return std::make_pair(taskState, ecdhTaskState->ecdhCrypto()); +} + +void EcdhPSIImpl::handleServerBlindData(PSIMessageInterface::Ptr _msg) +{ + auto startT = utcSteadyTime(); + ECDH_LOG(INFO) << LOG_DESC("handleServerBlindData") << printPSIMessage(_msg); + auto ret = checkAndObtainTaskState(_msg); + if (!ret.first || !ret.second) + { + return; + } + auto taskState = ret.first; + auto ecdhCrypto = ret.second; + auto sharedPk = ecdhCrypto->batchGetSharedPublicKey(_msg->takeData()); + + // append the evaluated data into cache + auto cache = m_cache->getServerCipherDataCache(_msg->taskID()); + if (!cache) + { + auto taskState = getTaskByID(_msg->taskID()); + if (!taskState) + { + auto error = BCOS_ERROR_PTR(PSIRetCode::TaskNotFound, + m_config->selfParty() + " handleServerBlindData failed for task not found!"); + ECDH_LOG(WARNING) << LOG_DESC("handleServerBlindData failed") + << LOG_KV("error", error->errorCode()) + << LOG_KV("msg", error->errorMessage()) << printPSIMessage(_msg); + onTaskError("handleServerBlindData: Task not found", std::move(error), _msg->from(), + _msg->taskID(), _msg->resourceID()); + return; + } + cache = m_cache->insertServerCipherCache(_msg->taskID(), taskState); + } + cache->appendServerCipherData(_msg->seq(), std::move(sharedPk)); + m_cache->tryToIntersectionAndStoreResult(); + ECDH_LOG(INFO) << LOG_DESC("handleServerBlindData success") << printPSIMessage(_msg) + << LOG_KV("timecost", (utcSteadyTime() - startT)); +} + +void EcdhPSIImpl::handleEvaluateResponse(PSIMessageInterface::Ptr _msg) +{ + auto startT = utcSteadyTime(); + auto evaluateData = _msg->takeData(); + ECDH_LOG(INFO) << LOG_DESC("handleEvaluateResponse") << printPSIMessage(_msg) + << LOG_KV("dataSize", evaluateData.size()); + + // append the evaluate response into the cache + auto cache = m_cache->getSubTaskCache(_msg->taskID(), _msg->seq()); + // if the cache is empty, this means the blindData for the (taskID, seq) has not been triggered + // maybe this is evaluate response of the last-canceled task + if (!cache) + { + return; + } + cache->setClientCipherData(std::move(evaluateData)); + m_cache->tryToIntersectionAndStoreResult(); + ECDH_LOG(INFO) << LOG_DESC("handleEvaluateResponse success") << printPSIMessage(_msg) + << LOG_KV("timecost", (utcSteadyTime() - startT)); +} + +void EcdhPSIImpl::onRecvSyncDataInfoMsg(PSIMessageInterface::Ptr const& _msg) +{ + ECDH_LOG(INFO) << LOG_DESC("onRecvSyncDataInfoMsg") << printPSIMessage(_msg) + << LOG_KV("dataBatchCount", _msg->dataBatchCount()); + auto cache = m_cache->getServerCipherDataCache(_msg->taskID()); + if (!cache) + { + auto error = BCOS_ERROR_PTR( + PSIRetCode::TaskNotFound, "onRecvSyncDataInfoMsg failed for task not found!"); + onTaskError("onRecvSyncDataInfoMsg: Task not found", std::move(error), _msg->from(), + _msg->taskID(), _msg->resourceID()); + return; + } + cache->setServerDataBatchCount(_msg->dataBatchCount()); + // try to intersection and store the psi result + m_cache->tryToIntersectionAndStoreResult(); +} + +// the client receive the handshake response +void EcdhPSIImpl::onHandshakeResponse(PSIMessageInterface::Ptr const& _msg) +{ + auto handshakeResponse = std::dynamic_pointer_cast(_msg); + ECDH_LOG(INFO) << LOG_DESC("onHandshakeResponse") << LOG_KV("curve", handshakeResponse->curve()) + << LOG_KV("hashImpl", handshakeResponse->hashType()) << printPSIMessage(_msg) + << LOG_KV("uuid", _msg->uuid()); + auto taskState = getTaskByID(_msg->taskID()); + if (!taskState) + { + ECDH_LOG(INFO) << LOG_DESC("onHandshakeResponse return for the task not found") + << printPSIMessage(_msg); + auto error = + BCOS_ERROR_PTR((int)PSIRetCode::TaskNotFound, "Task " + _msg->taskID() + " not found!"); + onTaskError("onHandshakeResponse", std::move(error), _msg->from(), _msg->taskID(), + "emptyDataResource"); + return; + } + if (handshakeResponse->curve() == -1 || handshakeResponse->hashType() == -1) + { + auto errorMsg = "onHandshakeResponse return for not find the matching curve/hashType"; + ECDH_LOG(WARNING) << LOG_DESC(errorMsg) << printPSIMessage(handshakeResponse); + auto error = BCOS_ERROR_PTR((int)PSIRetCode::HandshakeFailed, errorMsg); + auto dataResource = taskState->task()->selfParty()->dataResource(); + onTaskError("onHandshakeResponse", std::move(error), taskState->peerID(), + taskState->task()->id(), dataResource ? dataResource->resourceID() : "empty"); + return; + } + // create and set the handshaked ecdh-crypto + auto ecdhCrypto = m_config->ecdhCryptoFactory()->createECDHCrypto( + handshakeResponse->curve(), handshakeResponse->hashType()); + auto ecdhTaskState = std::dynamic_pointer_cast(taskState); + ecdhTaskState->setEcdhCrypto(ecdhCrypto); + + // response to the server, the server can blindData + auto psiMsg = + m_msgFactory->createTaskNotificationMessage((uint32_t)PSIPacketType::HandshakeSuccess); + psiMsg->setErrorCode(0); + psiMsg->setErrorMessage("success"); + auto startT = bcos::utcSteadyTime(); + m_config->asyncSendResponse(_msg->fromNode(), taskState->task()->id(), _msg->uuid(), psiMsg, + [this, startT, _msg](bcos::Error::Ptr _error) { + if (!_error || _error->errorCode() == 0) + { + PSI_FRAMEWORK_LOG(INFO) << LOG_DESC("asyncSendResponse success") + << LOG_KV("timecost", (bcos::utcSteadyTime() - startT)) + << printPSIMessage(_msg) << LOG_KV("uuid", _msg->uuid()); + return; + } + PSI_FRAMEWORK_LOG(WARNING) + << LOG_DESC("onHandshakeResponse: response-handshake result error") + << LOG_KV("code", _error->errorCode()) << LOG_KV("msg", _error->errorMessage()) + << LOG_KV("timecost", (bcos::utcSteadyTime() - startT)); + }); + + // blindData using specified ecc-curve and hash-algorithm + triggerDataBlind(taskState); + + // Note: the sql will load all data at-one-time, no-need blindData repeatedly + if (!taskState->sqlReader()) + { + auto weakTaskState = std::weak_ptr(taskState); + auto self = weak_from_this(); + taskState->setWorker([weakTaskState, self]() { + auto psi = self.lock(); + if (!psi) + { + return; + } + auto state = weakTaskState.lock(); + if (!state) + { + return; + } + psi->triggerDataBlind(state); + }); + } +} + +void EcdhPSIImpl::triggerDataBlind(TaskState::Ptr const& _taskState) +{ + auto self = weak_from_this(); + m_config->threadPool()->enqueue([self, _taskState]() { + auto psi = self.lock(); + if (!psi) + { + return; + } + try + { + psi->blindData(_taskState); + } + catch (std::exception const& e) + { + ECDH_LOG(INFO) << LOG_DESC("runPSI exception") + << LOG_KV("error", boost::diagnostic_information(e)) + << printTaskInfo(_taskState->task()); + auto dataResource = _taskState->task()->selfParty()->dataResource(); + auto error = BCOS_ERROR_PTR((int)PSIRetCode::BlindDataError, + "ecdh-psi blindData error, msg: " + std::string(boost::diagnostic_information(e))); + psi->onTaskError("runPSI-blindData", std::move(error), _taskState->peerID(), + _taskState->task()->id(), dataResource ? dataResource->resourceID() : "empty"); + } + }); +} + +// the server receive the handshake request and response +void EcdhPSIImpl::onHandshakeRequest(PSIMessageInterface::Ptr const& _msg) +{ + auto taskState = getTaskByID(_msg->taskID()); + if (!taskState) + { + auto error = BCOS_ERROR_PTR((int)PSIRetCode::TaskNotFound, + "task " + _msg->taskID() + " not found when receiving handshake request"); + onTaskError( + "onHandshakeRequest", std::move(error), _msg->from(), _msg->taskID(), "emptyResource"); + return; + } + auto handshakeReq = std::dynamic_pointer_cast(_msg); + auto const& curves = handshakeReq->curves(); + auto const& hashList = handshakeReq->hashList(); + ECDH_LOG(INFO) << LOG_DESC("onHandshakeRequest") << LOG_KV("supportedCurves", curves.size()) + << LOG_KV("supportedHashList", hashList.size()) << printPSIMessage(_msg); + std::set clientCurves(curves.begin(), curves.end()); + std::set clientHashList(hashList.begin(), hashList.end()); + + auto supportedCurves = g_PPCConfig.supportedCurves( + (uint8_t)TaskType::PSI, (uint8_t)TaskAlgorithmType::ECDH_PSI_2PC); + auto supportedHashList = g_PPCConfig.supportedHashList( + (uint8_t)TaskType::PSI, (uint8_t)TaskAlgorithmType::ECDH_PSI_2PC); + std::set localCurves(supportedCurves.begin(), supportedCurves.end()); + std::set localHashTypes(supportedHashList.begin(), supportedHashList.end()); + auto handshakeResponse = + m_msgFactory->createHandshakeResponse((uint32_t)PSIPacketType::HandshakeResponse); + bool curveSelected = false; + bool hashTypeSelected = false; + // sm-crypto enabled + if (g_PPCConfig.smCrypto()) + { + // try to select SM2 + if (clientCurves.count((int)ppc::protocol::ECCCurve::SM2) && + localCurves.count((int)ppc::protocol::ECCCurve::SM2)) + { + handshakeResponse->setCurve((int)ppc::protocol::ECCCurve::SM2); + curveSelected = true; + } + // try to select SM3 + if (clientHashList.count((int)ppc::protocol::HashImplName::SM3) && + localHashTypes.count((int)ppc::protocol::HashImplName::SM3)) + { + handshakeResponse->setHashType((int)ppc::protocol::HashImplName::SM3); + hashTypeSelected = true; + } + } + if (!curveSelected) + { + handshakeResponse->setCurve(selectCryptoAlgorithm(handshakeReq->curves(), localCurves)); + } + if (!hashTypeSelected) + { + handshakeResponse->setHashType( + selectCryptoAlgorithm(handshakeReq->hashList(), localHashTypes)); + } + auto ecdhTaskState = std::dynamic_pointer_cast(taskState); + auto selectedCurve = handshakeResponse->curve(); + auto selectedHashType = handshakeResponse->hashType(); + + auto dataResource = taskState->task()->selfParty()->dataResource(); + if (selectedCurve != -1 && selectedHashType != -1) + { + ECDH_LOG(INFO) << LOG_DESC("onHandshakeRequest success") + << LOG_KV("selectedCurve", (ppc::protocol::ECCCurve)selectedCurve) + << LOG_KV("selectedHashType", (ppc::protocol::HashImplName)selectedHashType); + auto ecdhCrypto = + m_config->ecdhCryptoFactory()->createECDHCrypto(selectedCurve, selectedHashType); + ecdhTaskState->setEcdhCrypto(ecdhCrypto); + } + else + { + auto errorMsg = "onHandshakeRequest failed for no curve/hashType selected"; + ECDH_LOG(WARNING) << LOG_DESC(errorMsg) << LOG_KV("selectedCurve", selectedCurve) + << LOG_KV("selectedHashType", selectedHashType); + auto error = BCOS_ERROR_PTR((int)PSIRetCode::HandshakeFailed, errorMsg); + onTaskError("onHandshakeRequest", std::move(error), _msg->from(), _msg->taskID(), + dataResource ? dataResource->resourceID() : "emptyResource"); + return; + } + auto self = weak_from_this(); + auto startT = bcos::utcSteadyTime(); + m_config->generateAndSendPPCMessage( + _msg->from(), _msg->taskID(), handshakeResponse, + [self, _msg, taskState, dataResource](Error::Ptr&& _error) { + auto psi = self.lock(); + if (!psi) + { + return; + } + if (!_error || _error->errorCode() == 0) + { + return; + } + // response failed + ECDH_LOG(ERROR) << LOG_DESC("onHandshakeRequest: send handshake response error") + << LOG_KV("code", _error->errorCode()) + << LOG_KV("msg", _error->errorMessage()) << printPSIMessage(_msg); + psi->onTaskError("onHandshakeRequest", std::move(_error), _msg->from(), _msg->taskID(), + dataResource ? dataResource->resourceID() : "emptyResource"); + }, + 0, + [self, _msg, startT, taskState, dataResource](bcos::Error::Ptr _error, + std::string const& _agencyID, ppc::front::PPCMessageFace::Ptr _ppcMsg, + ppc::front::ResponseFunc) { + auto psi = self.lock(); + if (!psi) + { + return; + } + if (!_error || _error->errorCode() == 0) + { + ECDH_LOG(INFO) << LOG_DESC( + "onHandshakeRequest: send handshake response and receive the " + "client-ack, begin triggerDataBlind") + << printTaskInfo(taskState->task()) + << LOG_KV("uuid", _ppcMsg->uuid()); + // triggerDataBlind when receiving the client-ack + psi->triggerDataBlind(taskState); + return; + } + // response failed + ECDH_LOG(ERROR) << LOG_DESC( + "onHandshakeRequest: send handshake response and receive the " + "client-ack error") + << LOG_KV("code", _error->errorCode()) + << LOG_KV("timecost", (bcos::utcSteadyTime() - startT)) + << LOG_KV("msg", _error->errorMessage()) << printPSIMessage(_msg); + psi->onTaskError("onHandshakeRequest", std::move(_error), _msg->from(), _msg->taskID(), + dataResource ? dataResource->resourceID() : "emptyResource"); + }); +} + +int EcdhPSIImpl::selectCryptoAlgorithm( + std::vector _clientSupportedAlgorithms, std::set _localSupportedAlgorithms) +{ + for (auto const& algorithm : _clientSupportedAlgorithms) + { + if (_localSupportedAlgorithms.count(algorithm)) + { + return algorithm; + } + } + // Note: -1 means select algorithm failed + return -1; +} \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-psi/src/ecdh-psi/EcdhPSIImpl.h b/cpp/wedpr-computing/ppc-psi/src/ecdh-psi/EcdhPSIImpl.h new file mode 100644 index 00000000..52887156 --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/ecdh-psi/EcdhPSIImpl.h @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2022 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 EcdhPSIImpl.h + * @author: yujiechen + * @date 2022-12-27 + */ +#pragma once +#include "../psi-framework/PSIFramework.h" +#include "EcdhCache.h" +#include "EcdhPSIConfig.h" +#include "EcdhTaskState.h" + +namespace ppc::psi +{ +class EcdhPSIImpl : public PSIFramework, public std::enable_shared_from_this +{ +public: + using Ptr = std::shared_ptr; + EcdhPSIImpl(EcdhPSIConfig::Ptr const& _config, unsigned _idleTimeMs = 0) + : PSIFramework( + _config->msgFactory(), _config->dataResourceLoader(), _config, "ecdh-psi", _idleTimeMs), + m_config(_config) + { + m_taskStateFactory = std::make_shared(); + m_cache = std::make_shared(_config); + } + + ~EcdhPSIImpl() override = default; + + void asyncRunTask(ppc::protocol::Task::ConstPtr _task, + ppc::task::TaskResponseCallback&& _onTaskFinished) override; + + // handle the psi message + void handlePSIMsg(PSIMessageInterface::Ptr _msg) override; + // should lock the party resource or not + bool needLockResource(int, int _partyType) override + { + return _partyType == (int)ppc::protocol::PartyType::Client; + } + +protected: + // receive the handshake response + void onHandshakeResponse(PSIMessageInterface::Ptr const& _msg) override; + // receive the handshake request + void onHandshakeRequest(PSIMessageInterface::Ptr const& _msg) override; + + // the psi-server and psi-client load data from DataResource and blind the plainData into cipher + virtual void blindData(TaskState::Ptr const& _taskState); + virtual void triggerDataBlind(TaskState::Ptr const& _taskState); + + // receive the blinded-data from client, the psi-server response the evaluated data + virtual void handleEvaluateRequest(PSIMessageInterface::Ptr _msg); + // receive the evaluate-response from the sever + virtual void handleEvaluateResponse(PSIMessageInterface::Ptr _msg); + + // receive the blinded-data from the server + virtual void handleServerBlindData(PSIMessageInterface::Ptr _msg); + // receive the SyncDataBatchCount request from the server + virtual void onRecvSyncDataInfoMsg(PSIMessageInterface::Ptr const& _msg); + + void runPSI(TaskState::Ptr const& _taskState); + + int selectCryptoAlgorithm( + std::vector _clientSupportedAlgorithms, std::set _localSupportedAlgorithms); + + // init the task-state + bool initTaskState(TaskState::Ptr const& _taskState); + + std::pair checkAndObtainTaskState( + PSIMessageInterface::Ptr _msg); + +protected: + EcdhPSIConfig::Ptr m_config; + EcdhCache::Ptr m_cache; +}; +} // namespace ppc::psi \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-psi/src/ecdh-psi/EcdhPSIMessageFactory.h b/cpp/wedpr-computing/ppc-psi/src/ecdh-psi/EcdhPSIMessageFactory.h new file mode 100644 index 00000000..0230c133 --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/ecdh-psi/EcdhPSIMessageFactory.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2022 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 EcdhPSIMessageFactory.h + * @author: yujiechen + * @date 2022-12-29 + */ +#pragma once +#include "../psi-framework/protocol/PSIMessage.h" +namespace ppc::psi +{ +class EcdhPSIMessageFactory : public PSIMessageFactoryImpl +{ +public: + using Ptr = std::shared_ptr; + EcdhPSIMessageFactory() = default; + ~EcdhPSIMessageFactory() override = default; + + PSIMessageInterface::Ptr decodePSIMessage(bcos::bytesConstRef _data) override + { + auto inner = [inner = ppctars::PSIMessage()]() mutable { return &inner; }; + tars::TarsInputStream input; + input.setBuffer((const char*)_data.data(), _data.size()); + inner()->readFrom(input); + switch (inner()->packetType) + { + case (uint32_t)ECDHPacketType::EvaluateRequest: + case (uint32_t)ECDHPacketType::EvaluateResponse: + case (uint32_t)ECDHPacketType::ServerBlindedData: + case (uint32_t)ECDHPacketType::SyncDataBatchInfo: + return std::make_shared(inner); + default: + return decodePSIBaseMessage(inner); + } + } +}; +} // namespace ppc::psi \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-psi/src/ecdh-psi/EcdhTaskState.h b/cpp/wedpr-computing/ppc-psi/src/ecdh-psi/EcdhTaskState.h new file mode 100644 index 00000000..44ada257 --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/ecdh-psi/EcdhTaskState.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 EcdhTaskState.h + * @author: yujiechen + * @date 2023-1-3 + */ +#pragma once +#include "../psi-framework/TaskState.h" +#include "ppc-framework/crypto/ECDHCrypto.h" +namespace ppc::psi +{ +class EcdhTaskState : public TaskState +{ +public: + using Ptr = std::shared_ptr; + EcdhTaskState(ppc::protocol::Task::ConstPtr const& _task, + ppc::task::TaskResponseCallback&& _callback, bool _onlySelfRun = false) + : TaskState(_task, std::move(_callback), _onlySelfRun) + {} + ~EcdhTaskState() override = default; + + // return copy here to ensure thread-safe + ppc::crypto::ECDHCrypto::Ptr ecdhCrypto() const + { + bcos::ReadGuard l(x_ecdhCrypto); + return m_ecdhCrypto; + } + // Note: here must lock, in-case of multiple tasks with the same task-id processed at almost the + // same time + void setEcdhCrypto(ppc::crypto::ECDHCrypto::Ptr const& _ecdhCrypto) + { + bcos::WriteGuard l(x_ecdhCrypto); + m_ecdhCrypto = _ecdhCrypto; + } + +private: + ppc::crypto::ECDHCrypto::Ptr m_ecdhCrypto; + mutable bcos::SharedMutex x_ecdhCrypto; +}; + +class EcdhTaskStateFactory : public TaskStateFactory +{ +public: + using Ptr = std::shared_ptr; + EcdhTaskStateFactory() : TaskStateFactory() {} + ~EcdhTaskStateFactory() override = default; + + TaskState::Ptr createTaskState(ppc::protocol::Task::ConstPtr const& _task, + ppc::task::TaskResponseCallback&& _callback, bool _onlySelfRun = false, + PSIConfig::Ptr _config = nullptr) override + { + return std::make_shared(_task, std::move(_callback), false); + } +}; +} // namespace ppc::psi \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-psi/src/labeled-psi/CMakeLists.txt b/cpp/wedpr-computing/ppc-psi/src/labeled-psi/CMakeLists.txt new file mode 100644 index 00000000..5c029ce3 --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/labeled-psi/CMakeLists.txt @@ -0,0 +1,30 @@ +# for tars generator +set(TARS_HEADER_DIR ${CMAKE_BINARY_DIR}/generated/ppc-psi/labeled-psi/tars) +find_program(TARS_TARS2CPP tars2cpp REQUIRED) + +file(GLOB_RECURSE TARS_INPUT "*.tars") +# generate tars +if (TARS_INPUT) + foreach (TARS_FILE ${TARS_INPUT}) + get_filename_component(TARS_NAME ${TARS_FILE} NAME_WE) + get_filename_component(TARS_PATH ${TARS_FILE} PATH) + add_custom_command( + OUTPUT ${TARS_HEADER_DIR}/${TARS_NAME}.h + WORKING_DIRECTORY ${TARS_PATH} + COMMAND ${TARS_TARS2CPP} ${TARS_FILE} --unjson --without-trace --dir=${TARS_HEADER_DIR} + COMMENT "generating ${TARS_FILE} to ${TARS_HEADER_DIR}" + VERBATIM + ) + + list(APPEND OUT_TARS_H_LIST ${TARS_HEADER_DIR}/${TARS_NAME}.h) + endforeach () +endif () +set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${OUT_TARS_H_LIST}") +include_directories(${TARS_HEADER_DIR}) + +file(GLOB_RECURSE SRCS *.cpp) +add_library(${LABELED_PSI_TARGET} ${SRCS} ${OUT_TARS_H_LIST}) +target_include_directories(${LABELED_PSI_TARGET} PUBLIC + $) + +target_link_libraries(${LABELED_PSI_TARGET} PUBLIC ${PSI_FRAMEWORK_TARGET} apsi SEAL::seal Kuku::kuku TBB::tbb) diff --git a/cpp/wedpr-computing/ppc-psi/src/labeled-psi/Common.h b/cpp/wedpr-computing/ppc-psi/src/labeled-psi/Common.h new file mode 100644 index 00000000..95fe31f1 --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/labeled-psi/Common.h @@ -0,0 +1,102 @@ +/** + * Copyright (C) 2022 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 Common.h + * @author: shawnhe + * @date 2022-11-4 + */ +#pragma once + +#include "ppc-framework/Common.h" +#include "ppc-framework/protocol/PPCMessageFace.h" + +#include +#include + + +namespace ppc::psi +{ +DERIVE_PPC_EXCEPTION(ConfigPowersDagException); +DERIVE_PPC_EXCEPTION(TooManyItemsException); +DERIVE_PPC_EXCEPTION(ResultPackageException); +DERIVE_PPC_EXCEPTION(OverwriteItemException); +DERIVE_PPC_EXCEPTION(InsertItemException); +DERIVE_PPC_EXCEPTION(RemoveItemException); +DERIVE_PPC_EXCEPTION(LabelExceedsSizeException); +DERIVE_PPC_EXCEPTION(NonceExceedsSizeException); +DERIVE_PPC_EXCEPTION(RetrieveItemException); +DERIVE_PPC_EXCEPTION(RetrieveLabelException); +DERIVE_PPC_EXCEPTION(ExtracteRelinKeysException); +DERIVE_PPC_EXCEPTION(ExtracteCiphertextException); +DERIVE_PPC_EXCEPTION(QueryPowersException); +DERIVE_PPC_EXCEPTION(PowerDagException); + +#define LABELED_PSI_LOG(LEVEL) BCOS_LOG(LEVEL) << LOG_BADGE("PSI: Labeled-PSI") + +#define CUCKOO_TABLE_INSERT_ATTEMPTS 500 +#define MAX_LABEL_BYTE 1024 +#define MAX_QUERY_SIZE 8 + +constexpr static std::string_view CMD_SETUP_SENDER_DB = "setup_sender_db"; +constexpr static std::string_view CMD_RUN_LABELED_PSI = "run_labeled_psi"; +constexpr static std::string_view CMD_SAVE_SENDER_CACHE = "save_sender_cache"; +constexpr static std::string_view CMD_LOAD_SENDER_CACHE = "load_sender_cache"; +constexpr static std::string_view CMD_ADD_ITEMS = "add_items"; +constexpr static std::string_view CMD_UPDATE_LABELS = "update_labels"; +constexpr static std::string_view CMD_DELETE_ITEMS = "delete_items"; + +enum class LabeledPSIMessageType : uint8_t +{ + PARAMS_REQUEST = 0x01, + PARAMS_RESPONSE = 0x02, + OPRF_BLINDED_ITEMS = 0x03, + OPRF_EVALUATED_ITEMS = 0x04, + QUERY = 0x05, + RESPONSE = 0x06 +}; + +enum class LabeledPSIRetCode : int +{ + ON_EXCEPTION = -2000, + SENDER_NOT_READY = -2001, + CUCKOO_HASH_ERROR = -2002, + MISSING_LABEL_DATA = -2003, + LACK_LABEL_DATA = -2004, + UNDEFINED_TASK_ROLE = -2005, + UNDEFINED_COMMAND = -2006, + DATA_FORMAT_ERROR = -2007, + INVALID_TASK_PARAM = -2008, + SETUP_SENDER_ERROR = -2009, + LOAD_SENDER_CACHE_ERROR = -2010 +}; + +enum class LabeledPSICommand : int +{ + SETUP_SENDER_DB, + RUN_LABELED_PSI, + SAVE_SENDER_CACHE, + LOAD_SENDER_CACHE, + ADD_ITEMS, + UPDATE_LABELS, + DELETE_ITEMS +}; + +template +bool hasNZeros(T* ptr, size_t count) +{ + return std::all_of(ptr, ptr + count, [](auto a) { return a == T(0); }); +} + +} // namespace ppc::psi diff --git a/cpp/wedpr-computing/ppc-psi/src/labeled-psi/LabeledPSIConfig.h b/cpp/wedpr-computing/ppc-psi/src/labeled-psi/LabeledPSIConfig.h new file mode 100644 index 00000000..2456fd11 --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/labeled-psi/LabeledPSIConfig.h @@ -0,0 +1,73 @@ +/** + * Copyright (C) 2022 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 LabeledPSIConfig.h + * @author: shawnhe + * @date 2022-11-3 + */ + +#pragma once + +#include "Common.h" +#include "ppc-crypto/src/oprf/EcdhOprf.h" +#include "ppc-framework/crypto/CryptoBox.h" +#include "ppc-framework/crypto/Oprf.h" +#include "ppc-psi/src/PSIConfig.h" +#include "protocol/src/PPCMessage.h" + +#include +#include + +namespace ppc::psi +{ +class LabeledPSIConfig : public PSIConfig +{ +public: + using Ptr = std::shared_ptr; + + LabeledPSIConfig(std::string const& _selfPartyID, ppc::front::FrontInterface::Ptr _front, + ppc::crypto::CryptoBox::Ptr _cryptoBox, bcos::ThreadPool::Ptr _threadPool, + ppc::io::DataResourceLoader::Ptr _dataResourceLoader, int _holdingMessageMinutes, + uint32_t minNeededMemoryGB = 1, + front::PPCMessageFactory::Ptr _msgFactory = std::make_shared()) + : PSIConfig(ppc::protocol::TaskAlgorithmType::LABELED_PSI_2PC, _selfPartyID, + std::move(_front), _msgFactory, _dataResourceLoader, _holdingMessageMinutes, + minNeededMemoryGB), + m_cryptoBox(std::move(_cryptoBox)), + m_threadPool(std::move(_threadPool)), + m_messageFactory(_msgFactory) + { + m_oprfServer = std::make_shared( + sizeof(apsi::Item::value_type) + sizeof(apsi::LabelKey), m_cryptoBox->hashImpl(), + m_cryptoBox->eccCrypto()); + } + + virtual ~LabeledPSIConfig() = default; + +public: + crypto::Hash::Ptr const& hash() const { return m_cryptoBox->hashImpl(); } + crypto::EccCrypto::Ptr const& eccCrypto() const { return m_cryptoBox->eccCrypto(); } + bcos::ThreadPool::Ptr const& threadPool() const { return m_threadPool; } + crypto::OprfServer::Ptr const& oprfServer() const { return m_oprfServer; } + +private: + ppc::crypto::CryptoBox::Ptr m_cryptoBox; + bcos::ThreadPool::Ptr m_threadPool; + + crypto::OprfServer::Ptr m_oprfServer; + front::PPCMessageFactory::Ptr m_messageFactory; +}; + +} // namespace ppc::psi \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-psi/src/labeled-psi/LabeledPSIFactory.cpp b/cpp/wedpr-computing/ppc-psi/src/labeled-psi/LabeledPSIFactory.cpp new file mode 100644 index 00000000..30f41f81 --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/labeled-psi/LabeledPSIFactory.cpp @@ -0,0 +1,36 @@ +/** + * Copyright (C) 2022 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 LabeledPSIFactory.cpp + * @author: shawnhe + * @date 2022-11-14 + */ +#include "LabeledPSIFactory.h" + +using namespace ppc::psi; +using namespace ppc::crypto; +using namespace ppc::io; +using namespace ppc::front; + +LabeledPSIImpl::Ptr LabeledPSIFactory::buildLabeledPSI(std::string const& _selfParty, + FrontInterface::Ptr _front, CryptoBox::Ptr _cryptoBox, bcos::ThreadPool::Ptr _threadPool, + DataResourceLoader::Ptr _dataResourceLoader, int _holdingMessageMinutes, + uint32_t minNeededMemoryGB) +{ + auto config = std::make_shared(_selfParty, std::move(_front), + std::move(_cryptoBox), std::move(_threadPool), std::move(_dataResourceLoader), + _holdingMessageMinutes, minNeededMemoryGB); + return std::make_shared(config); +} \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-psi/src/labeled-psi/LabeledPSIFactory.h b/cpp/wedpr-computing/ppc-psi/src/labeled-psi/LabeledPSIFactory.h new file mode 100644 index 00000000..407dfa45 --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/labeled-psi/LabeledPSIFactory.h @@ -0,0 +1,39 @@ +/** + * Copyright (C) 2022 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 LabeledPSIFactory.h + * @author: shawnhe + * @date 2022-11-14 + */ +#pragma once +#include "LabeledPSIImpl.h" +#include "ppc-framework/crypto/CryptoBox.h" +#include "ppc-framework/io/DataResourceLoader.h" + +namespace ppc::psi +{ +class LabeledPSIFactory +{ +public: + using Ptr = std::shared_ptr; + LabeledPSIFactory() = default; + virtual ~LabeledPSIFactory() = default; + + virtual LabeledPSIImpl::Ptr buildLabeledPSI(std::string const& _selfParty, + ppc::front::FrontInterface::Ptr _front, ppc::crypto::CryptoBox::Ptr _cryptoBox, + bcos::ThreadPool::Ptr _threadPool, ppc::io::DataResourceLoader::Ptr _dataResourceLoader, + int _holdingMessageMinutes, uint32_t minNeededMemoryGB = 1); +}; +} // namespace ppc::psi \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-psi/src/labeled-psi/LabeledPSIImpl.cpp b/cpp/wedpr-computing/ppc-psi/src/labeled-psi/LabeledPSIImpl.cpp new file mode 100644 index 00000000..6d3e0481 --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/labeled-psi/LabeledPSIImpl.cpp @@ -0,0 +1,810 @@ +/** + * Copyright (C) 2022 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 LabeledPSIImpl.cpp + * @author: shawnhe + * @date 2022-11-7 + */ + +#include "LabeledPSIImpl.h" +#include "Common.h" +#include "LabeledPSI.h" +#include "core/LabeledPSIParams.h" +#include "core/SenderDB.h" +#include "core/TaskCommand.h" +#include "ppc-psi/src/labeled-psi/core/LabeledPSIReceiver.h" +#include "wedpr-protocol/tars/TarsSerialize.h" + +using namespace ppc::psi; +using namespace ppc::protocol; +using namespace ppc::front; +using namespace ppc::tools; +using namespace ppc::crypto; +using namespace ppc::io; +using namespace ppc::task; + +LabeledPSIImpl::LabeledPSIImpl(LabeledPSIConfig::Ptr _config, unsigned _idleTimeMs) + : Worker("LabeledPSI", _idleTimeMs), + TaskGuarder(_config, TaskAlgorithmType::LABELED_PSI_2PC, "Labeled-PSI-Timer"), + m_config(std::move(_config)), + m_msgQueue(std::make_shared()), + m_worker(std::make_shared("senderDB-worker", 1)) +{ + m_sender = make_shared( + m_config, [&](const std::string& _taskID, bcos::Error::Ptr _error) { + if (_error && _error->errorCode()) + { + onSelfError(_taskID, std::move(_error), true); + } + else + { + onSenderTaskDone(_taskID); + } + }); +} + +// run task +void LabeledPSIImpl::asyncRunTask( + ppc::protocol::Task::ConstPtr _task, TaskResponseCallback&& _onTaskFinished) +{ + auto onTaskFinished = [self = weak_from_this(), taskID = _task->id(), _onTaskFinished]( + ppc::protocol::TaskResult::Ptr&& _result) { + try + { + auto result = std::move(_result); + _onTaskFinished(std::move(result)); + LABELED_PSI_LOG(INFO) << LOG_DESC("finish a task") << LOG_KV("taskID", taskID); + auto psi = self.lock(); + if (!psi) + { + return; + } + + // erase the taskInfo from the gateway + psi->m_config->front()->eraseTaskInfo(taskID); + } + catch (std::exception& e) + { + LABELED_PSI_LOG(ERROR) << LOG_DESC("handle callback error after finishing task") + << LOG_KV("exception", boost::diagnostic_information(e)); + } + }; + + try + { + // there is always a self-help party + auto role = _task->selfParty()->partyIndex(); + if (role == uint16_t(PartyType::Client)) + { + auto error = checkTask(_task, 2, true, true, false); + if (error) + { + LABELED_PSI_LOG(WARNING) + << LOG_DESC("failed to check task, " + error->errorMessage()) + << printTaskInfo(_task); + // notice peer to cancel task + noticePeerToFinish(_task); + + auto result = std::make_shared(_task->id()); + result->setError(std::move(error)); + onTaskFinished(std::move(result)); + return; + } + + // add pending task + auto taskState = m_taskStateFactory->createTaskState(_task, std::move(onTaskFinished)); + taskState->setPeerID(getPeerID(_task)); + taskState->registerNotifyPeerFinishHandler([self = weak_from_this(), _task]() { + auto psi = self.lock(); + if (!psi) + { + return; + } + + psi->noticePeerToFinish(_task); + }); + addPendingTask(taskState); + // check the memory + checkHostResource(m_config->minNeededMemoryGB()); + + auto oprfClient = std::make_shared( + sizeof(apsi::Item::value_type) + sizeof(apsi::LabelKey), m_config->hash(), + m_config->eccCrypto()); + auto receiver = std::make_shared(m_config, taskState, oprfClient); + receiver->asyncRunTask(); + addReceiver(receiver); + + // notify the taskInfo to the front + error = m_config->front()->notifyTaskInfo(_task->id()); + if (error && error->errorCode()) + { + onSelfError(_task->id(), error, true); + } + } + else if (role == uint16_t(PartyType::Server)) + { + asyncRunSenderTask(_task, std::move(onTaskFinished)); + } + else + { + LABELED_PSI_LOG(WARNING) << LOG_DESC("undefined task role") << unsigned(role); + // notice peer to cancel task + noticePeerToFinish(_task); + + auto result = std::make_shared(_task->id()); + result->setError(std::make_shared( + (int)LabeledPSIRetCode::UNDEFINED_TASK_ROLE, "undefined task role")); + onTaskFinished(std::move(result)); + noticePeerToFinish(_task); + return; + } + } + catch (std::exception const& e) + { + LABELED_PSI_LOG(WARNING) << LOG_DESC("asyncRunTask exception") + << LOG_KV("task", printTaskInfo(_task)) + << LOG_KV("error", boost::diagnostic_information(e)); + auto error = std::make_shared( + -1, "asyncRunTask failed for " + boost::diagnostic_information(e)); + onSelfError(_task->id(), error, true); + } +} + +// register to the front to get the message related to labeled-psi +void LabeledPSIImpl::onReceiveMessage(ppc::front::PPCMessageFace::Ptr _msg) +{ + try + { + m_msgQueue->push(_msg); + + // notify to handle the message + wakeupWorker(); + } + catch (std::exception const& e) + { + LABELED_PSI_LOG(WARNING) << LOG_DESC("onReceiveMessage exception") << printPPCMsg(_msg) + << LOG_KV("error", boost::diagnostic_information(e)); + } +} + +void LabeledPSIImpl::start() +{ + if (m_started) + { + LABELED_PSI_LOG(WARNING) << LOG_DESC("The LabeledPSI has already been started"); + return; + } + LABELED_PSI_LOG(INFO) << LOG_DESC("Start the LabeledPSI"); + m_started = true; + + // start a thread to execute task + startWorking(); + + startPingTimer(); +} + +void LabeledPSIImpl::stop() +{ + if (!m_started) + { + return; + } + LABELED_PSI_LOG(INFO) << LOG_DESC("Stop LabeledPSI"); + m_started = false; + if (m_config->threadPool()) + { + m_config->threadPool()->stop(); + } + + finishWorker(); + if (isWorking()) + { + // stop the worker thread + stopWorking(); + terminate(); + } + stopPingTimer(); + + LABELED_PSI_LOG(INFO) << LOG_DESC("LabeledPSI stopped"); +} + +void LabeledPSIImpl::onReceivedErrorNotification(ppc::front::PPCMessageFace::Ptr const& _message) +{ + LABELED_PSI_LOG(WARNING) << LOG_DESC("onReceivedErrorNotification") << printPPCMsg(_message); + // finish the task while the peer is failed + auto taskState = findPendingTask(_message->taskID()); + if (taskState) + { + taskState->onPeerNotifyFinish(); + } +} + +void LabeledPSIImpl::onSelfError( + const std::string& _taskID, bcos::Error::Ptr _error, bool _noticePeer) +{ + LABELED_PSI_LOG(WARNING) << LOG_DESC("onSelfError") << LOG_KV("task", _taskID) + << LOG_KV("error", _error->errorMessage()) + << LOG_KV("noticePeer", _noticePeer); + try + { + auto taskState = findPendingTask(_taskID); + if (!taskState) + { + return; + } + + auto result = std::make_shared(taskState->task()->id()); + result->setError(std::move(_error)); + taskState->onTaskFinished(result, _noticePeer); + + wakeupWorker(); + } + catch (std::exception& e) + { + LABELED_PSI_LOG(ERROR) << LOG_DESC("onSelfError") + << LOG_KV("exception", boost::diagnostic_information(e)); + } +} + +void LabeledPSIImpl::asyncRunSenderTask( + const ppc::protocol::Task::ConstPtr& _task, TaskResponseCallback&& _onTaskFinished) +{ + TaskCommand::Ptr taskCommand; + try + { + // parse the task command + taskCommand = std::make_shared(_task->param()); + } + catch (const std::exception& e) + { + LABELED_PSI_LOG(WARNING) << LOG_DESC("asyncRunSenderTask exception") << printTaskInfo(_task) + << LOG_KV("error", boost::diagnostic_information(e)); + + auto result = std::make_shared(_task->id()); + result->setError(std::make_shared((int)LabeledPSIRetCode::ON_EXCEPTION, + "exception caught while asyncRunSenderTask: " + boost::diagnostic_information(e))); + _onTaskFinished(std::move(result)); + noticePeerToFinish(_task); + return; + } + + switch (taskCommand->command()) + { + case (int)LabeledPSICommand::SETUP_SENDER_DB: + { + if (m_senderReady) + { + LABELED_PSI_LOG(WARNING) + << LOG_DESC("sender has been set up: ") << printTaskInfo(_task); + auto result = std::make_shared(_task->id()); + result->setError(std::make_shared( + (int)LabeledPSIRetCode::SETUP_SENDER_ERROR, "sender has been set up")); + _onTaskFinished(std::move(result)); + return; + } + + auto error = checkTask(_task, 1, true, false, false); + if (error) + { + LABELED_PSI_LOG(WARNING) << LOG_DESC("failed to check task, " + error->errorMessage()) + << printTaskInfo(_task); + auto result = std::make_shared(_task->id()); + result->setError(std::move(error)); + _onTaskFinished(std::move(result)); + return; + } + + auto taskState = + m_taskStateFactory->createTaskState(_task, std::move(_onTaskFinished), true); + addPendingTask(taskState); + + m_worker->enqueue([self = weak_from_this(), _task, taskCommand]() { + auto psi = self.lock(); + if (psi) + { + auto labelByteCount = taskCommand->args()[0]; + psi->setupSenderDB(_task, labelByteCount); + } + }); + break; + } + case (int)LabeledPSICommand::RUN_LABELED_PSI: + { + if (!m_senderReady) + { + LABELED_PSI_LOG(WARNING) << LOG_DESC("sender not ready: ") << printTaskInfo(_task); + + // notice peer to cancel task + noticePeerToFinish(_task); + + auto result = std::make_shared(_task->id()); + result->setError(std::make_shared( + (int)LabeledPSIRetCode::SENDER_NOT_READY, "sender not ready")); + _onTaskFinished(std::move(result)); + return; + } + + auto error = checkTask(_task, 2, false, false, false, false); + if (error) + { + LABELED_PSI_LOG(WARNING) << LOG_DESC("failed to check task, " + error->errorMessage()) + << printTaskInfo(_task); + // notice peer to cancel task + noticePeerToFinish(_task); + auto result = std::make_shared(_task->id()); + result->setError(std::move(error)); + _onTaskFinished(std::move(result)); + return; + } + + auto taskState = m_taskStateFactory->createTaskState(_task, std::move(_onTaskFinished)); + taskState->setPeerID(getPeerID(_task)); + taskState->registerNotifyPeerFinishHandler([self = weak_from_this(), _task]() { + auto psi = self.lock(); + if (!psi) + { + return; + } + + psi->noticePeerToFinish(_task); + }); + addPendingTask(taskState); + + // notify the taskInfo to the front + error = m_config->front()->notifyTaskInfo(_task->id()); + if (error && error->errorCode()) + { + onSelfError(_task->id(), error, true); + } + break; + } + case (int)LabeledPSICommand::SAVE_SENDER_CACHE: + { + if (!m_senderReady) + { + LABELED_PSI_LOG(WARNING) << LOG_DESC("sender not ready: ") << printTaskInfo(_task); + auto result = std::make_shared(_task->id()); + result->setError(std::make_shared( + (int)LabeledPSIRetCode::SENDER_NOT_READY, "sender not ready")); + _onTaskFinished(std::move(result)); + return; + } + + auto error = checkTask(_task, 1, false, true, false); + if (error) + { + LABELED_PSI_LOG(WARNING) << LOG_DESC("failed to check task, " + error->errorMessage()) + << printTaskInfo(_task); + auto result = std::make_shared(_task->id()); + result->setError(std::move(error)); + _onTaskFinished(std::move(result)); + noticePeerToFinish(_task); + return; + } + + auto taskState = + m_taskStateFactory->createTaskState(_task, std::move(_onTaskFinished), true); + addPendingTask(taskState); + + m_worker->enqueue([self = weak_from_this(), _task]() { + auto psi = self.lock(); + if (psi) + { + psi->saveSenderCache(_task); + } + }); + break; + } + case (int)LabeledPSICommand::LOAD_SENDER_CACHE: + { + if (m_senderReady) + { + LABELED_PSI_LOG(WARNING) + << LOG_DESC("sender has been set up: ") << printTaskInfo(_task); + auto result = std::make_shared(_task->id()); + result->setError(std::make_shared( + (int)LabeledPSIRetCode::LOAD_SENDER_CACHE_ERROR, "sender has been set up")); + _onTaskFinished(std::move(result)); + return; + } + + auto error = checkTask(_task, 1, true, false, false); + if (error) + { + LABELED_PSI_LOG(WARNING) << LOG_DESC("failed to check task, " + error->errorMessage()) + << printTaskInfo(_task); + auto result = std::make_shared(_task->id()); + result->setError(std::move(error)); + _onTaskFinished(std::move(result)); + noticePeerToFinish(_task); + return; + } + + auto taskState = + m_taskStateFactory->createTaskState(_task, std::move(_onTaskFinished), true); + addPendingTask(taskState); + m_worker->enqueue([self = weak_from_this(), _task]() { + auto psi = self.lock(); + if (psi) + { + psi->loadSenderCache(_task); + } + }); + break; + } + default: + { + LABELED_PSI_LOG(WARNING) << LOG_DESC("unsupported command: ") << printTaskInfo(_task); + auto result = std::make_shared(_task->id()); + result->setError(std::make_shared( + (int)LabeledPSIRetCode::UNDEFINED_COMMAND, "unsupported command")); + _onTaskFinished(std::move(result)); + noticePeerToFinish(_task); + break; + } + } +} + +void LabeledPSIImpl::setupSenderDB(const ppc::protocol::Task::ConstPtr& _task, int _labelByteCount) +{ + try + { + auto dataResource = _task->selfParty()->dataResource(); + auto reader = loadReader(_task->id(), dataResource, DataSchema::Bytes, 2); + + DataBatch::Ptr items, labels; + if (reader->type() == ppc::protocol::DataResourceType::MySQL) + { + items = reader->next(0, DataSchema::Bytes); + labels = reader->next(1, DataSchema::Bytes); + } + else + { + auto lines = reader->next(-1, DataSchema::Bytes); + items = std::make_shared(); + items->setDataSchema(ppc::io::DataSchema::Bytes); + labels = std::make_shared(); + labels->setDataSchema(ppc::io::DataSchema::Bytes); + for (uint32_t i = 0; i < lines->size(); ++i) + { + auto line = lines->getBytes(i); + std::vector data; + boost::split(data, line, boost::is_any_of(",")); + if (data.size() != 2) + { + BOOST_THROW_EXCEPTION(BCOS_ERROR((int)LabeledPSIRetCode::DATA_FORMAT_ERROR, + "the data format should be: key,value")); + } + + items->append(bcos::bytes(data[0].begin(), data[0].end())); + labels->append(bcos::bytes(data[1].begin(), data[1].end())); + } + } + + if (items->size() != labels->size()) + { + BOOST_THROW_EXCEPTION(BCOS_ERROR((int)LabeledPSIRetCode::DATA_FORMAT_ERROR, + "the number of items and labels is not the same")); + } + + LABELED_PSI_LOG(INFO) << LOG_DESC("finish loading item-label") + << LOG_KV("count", items->size()); + + auto psiParams = getPsiParams(items->size()); + + m_senderDB = std::make_shared( + psiParams, m_config->oprfServer(), _labelByteCount, 16, false); + + std::set tmp; + for (uint32_t i = 0; i < items->size(); i++) + { + tmp.insert(items->getBytes(i)); + } + if (tmp.size() < items->size()) + { + BOOST_THROW_EXCEPTION( + BCOS_ERROR((int)LabeledPSIRetCode::DATA_FORMAT_ERROR, "duplicate key found")); + } + + m_senderDB->setData(items, labels); + + m_sender->setSenderDB(m_senderDB); + m_senderReady.exchange(true); + + LABELED_PSI_LOG(INFO) << LOG_DESC("setupSenderDB done") << printTaskInfo(_task); + + onSenderTaskDone(_task->id()); + } + catch (bcos::Error const& e) + { + LABELED_PSI_LOG(WARNING) << LOG_DESC("setupSenderDB exception") << printTaskInfo(_task) + << LOG_KV("code", e.errorCode()) + << LOG_KV("msg", e.errorMessage()); + onSelfError( + _task->id(), std::make_shared(e.errorCode(), e.errorMessage()), false); + } + catch (const std::exception& e) + { + LABELED_PSI_LOG(WARNING) << LOG_DESC("setupSenderDB exception") << printTaskInfo(_task) + << LOG_KV("error", boost::diagnostic_information(e)); + + onSelfError(_task->id(), + std::make_shared((int)LabeledPSIRetCode::ON_EXCEPTION, + "exception caught while setupSenderDB: " + boost::diagnostic_information(e)), + false); + } +} + +void LabeledPSIImpl::saveSenderCache(const ppc::protocol::Task::ConstPtr& _task) +{ + try + { + auto dataResource = _task->selfParty()->dataResource(); + + LineWriter::Ptr writer; + if (!_task->enableOutputExists()) + { + // Note: if the output-resource already exists, will throw exception + m_config->dataResourceLoader()->checkResourceExists(dataResource->outputDesc()); + } + writer = m_config->dataResourceLoader()->loadWriter(dataResource->outputDesc(), true); + + bcos::bytes out; + m_senderDB->saveToBytes(out); + + writer->writeBytes(bcos::ref(out)); + writer->flush(); + writer->close(); + + onSenderTaskDone(_task->id()); + LABELED_PSI_LOG(INFO) << LOG_DESC("saveSenderCache done") << printTaskInfo(_task); + } + catch (bcos::Error const& e) + { + LABELED_PSI_LOG(WARNING) << LOG_DESC("saveSenderCache exception") << printTaskInfo(_task) + << LOG_KV("code", e.errorCode()) + << LOG_KV("msg", e.errorMessage()); + onSelfError( + _task->id(), std::make_shared(e.errorCode(), e.errorMessage()), false); + } + catch (const std::exception& e) + { + LABELED_PSI_LOG(WARNING) << LOG_DESC("saveSenderCache exception") << printTaskInfo(_task) + << LOG_KV("error", boost::diagnostic_information(e)); + + onSelfError(_task->id(), + std::make_shared((int)LabeledPSIRetCode::ON_EXCEPTION, + "exception caught while saveSenderCache: " + boost::diagnostic_information(e)), + false); + } +} + +void LabeledPSIImpl::loadSenderCache(const ppc::protocol::Task::ConstPtr& _task) +{ + try + { + auto dataResource = _task->selfParty()->dataResource(); + auto reader = m_config->dataResourceLoader()->loadReader( + dataResource->desc(), ppc::io::DataSchema::Bytes, false); + + auto cache = reader->readBytes(); + m_senderDB = SenderDB::loadFromBytes(m_config->oprfServer(), cache); + + m_senderReady.exchange(true); + m_sender->setSenderDB(m_senderDB); + onSenderTaskDone(_task->id()); + LABELED_PSI_LOG(INFO) << LOG_DESC("loadSenderCache done") << printTaskInfo(_task); + } + catch (bcos::Error const& e) + { + LABELED_PSI_LOG(WARNING) << LOG_DESC("loadSenderCache exception") << printTaskInfo(_task) + << LOG_KV("code", e.errorCode()) + << LOG_KV("msg", e.errorMessage()); + onSelfError( + _task->id(), std::make_shared(e.errorCode(), e.errorMessage()), false); + } + catch (const std::exception& e) + { + LABELED_PSI_LOG(WARNING) << LOG_DESC("loadSenderCache exception") << printTaskInfo(_task) + << LOG_KV("error", boost::diagnostic_information(e)); + + onSelfError(_task->id(), + std::make_shared((int)LabeledPSIRetCode::ON_EXCEPTION, + "exception caught while loadSenderCache: " + boost::diagnostic_information(e)), + false); + } +} + +// labeled-psi main processing function +// for ut to make this function public +void LabeledPSIImpl::executeWorker() +{ + checkFinishedTask(); + auto result = m_msgQueue->tryPop(c_popWaitMs); + if (result.first) + { + handleReceivedMessage(result.second); + return; + } + waitSignal(); +} + +void LabeledPSIImpl::checkFinishedTask() +{ + std::set finishedTask; + { + bcos::WriteGuard l(x_pendingTasks); + if (m_pendingTasks.empty()) + { + return; + } + + for (auto it = m_pendingTasks.begin(); it != m_pendingTasks.end();) + { + auto task = it->second; + if (task->finished()) + { + finishedTask.insert(it->first); + } + it++; + } + } + for (auto& taskID : finishedTask) + { + removeReceiver(taskID); + removePendingTask(taskID); + } +} + +void LabeledPSIImpl::onSenderTaskDone(const std::string& _taskID) +{ + auto taskState = findPendingTask(_taskID); + if (taskState) + { + taskState->onTaskFinished(std::make_shared(_taskID), false); + } +} + +void LabeledPSIImpl::handleReceivedMessage(const ppc::front::PPCMessageFace::Ptr& _message) +{ + m_config->threadPool()->enqueue([self = weak_from_this(), _message]() { + try + { + auto psi = self.lock(); + if (!psi) + { + return; + } + switch (int(_message->messageType())) + { + case int(CommonMessageType::ErrorNotification): + { + psi->onReceivedErrorNotification(_message); + break; + } + case int(CommonMessageType::PingPeer): + { + break; + } + case int(LabeledPSIMessageType::PARAMS_REQUEST): + { + psi->onReceivePsiParamsRequest(_message); + break; + } + case int(LabeledPSIMessageType::PARAMS_RESPONSE): + { + psi->onReceivePsiParamsResponse(_message); + break; + } + case int(LabeledPSIMessageType::OPRF_BLINDED_ITEMS): + { + psi->onReceiveBlindedItems(_message); + break; + } + case int(LabeledPSIMessageType::OPRF_EVALUATED_ITEMS): + { + psi->onReceiveEvaluatedItems(_message); + break; + } + case int(LabeledPSIMessageType::QUERY): + { + psi->onReceiveQuery(_message); + break; + } + case int(LabeledPSIMessageType::RESPONSE): + { + psi->onReceiveResponse(_message); + break; + } + default: + { + LABELED_PSI_LOG(WARNING) + << LOG_DESC("unsupported messageType ") << unsigned(_message->messageType()); + break; + } + } + } + catch (std::exception const& e) + { + LABELED_PSI_LOG(WARNING) + << LOG_DESC("handleReceivedMessage exception") + << LOG_KV("type", unsigned(_message->messageType())) << printPPCMsg(_message) + << LOG_KV("error", boost::diagnostic_information(e)); + } + }); +} + + +void LabeledPSIImpl::onReceivePsiParamsRequest(ppc::front::PPCMessageFace::Ptr _message) +{ + if (!m_senderReady) + { + noticePeerToFinish(_message->taskID(), _message->sender()); + } + else + { + auto taskID = _message->taskID(); + if (findPendingTask(taskID)) + { + m_sender->handlePsiParamsRequest(std::move(_message)); + } + } +} + +void LabeledPSIImpl::onReceivePsiParamsResponse(ppc::front::PPCMessageFace::Ptr _message) +{ + auto receiver = findReceiver(_message->taskID()); + if (receiver) + { + receiver->handlePsiParams(std::move(_message)); + } +} + +void LabeledPSIImpl::onReceiveBlindedItems(ppc::front::PPCMessageFace::Ptr _message) +{ + auto taskID = _message->taskID(); + if (findPendingTask(taskID)) + { + m_sender->handleBlindedItems(std::move(_message)); + } +} + +void LabeledPSIImpl::onReceiveEvaluatedItems(ppc::front::PPCMessageFace::Ptr _message) +{ + auto receiver = findReceiver(_message->taskID()); + if (receiver) + { + receiver->handleEvaluatedItems(std::move(_message)); + } +} + +void LabeledPSIImpl::onReceiveQuery(ppc::front::PPCMessageFace::Ptr _message) +{ + auto taskID = _message->taskID(); + if (findPendingTask(taskID)) + { + m_sender->handleQuery(std::move(_message)); + } +} + + +void LabeledPSIImpl::onReceiveResponse(ppc::front::PPCMessageFace::Ptr _message) +{ + auto receiver = findReceiver(_message->taskID()); + if (receiver) + { + receiver->handleOneResponse(std::move(_message)); + } +} diff --git a/cpp/wedpr-computing/ppc-psi/src/labeled-psi/LabeledPSIImpl.h b/cpp/wedpr-computing/ppc-psi/src/labeled-psi/LabeledPSIImpl.h new file mode 100644 index 00000000..0d213fa2 --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/labeled-psi/LabeledPSIImpl.h @@ -0,0 +1,147 @@ +/** + * Copyright (C) 2022 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 LabeledPSIImpl.h + * @author: shawnhe + * @date 2022-11-7 + */ + +#pragma once +#include +#include +#include +#include +#include + +#include "../psi-framework/TaskGuarder.h" +#include "Common.h" +#include "LabeledPSIConfig.h" +#include "core/LabeledPSIReceiver.h" +#include "core/LabeledPSISender.h" +#include "ppc-framework/protocol/Task.h" +#include "ppc-framework/task/TaskFrameworkInterface.h" +#include "ppc-front/ppc-front/PPCChannel.h" +#include "ppc-tools/src/common/TransTools.h" +#include "protocol/src/PPCMessage.h" + +namespace ppc::psi +{ +class LabeledPSIImpl : public bcos::Worker, + public TaskGuarder, + public ppc::task::TaskFrameworkInterface, + public std::enable_shared_from_this +{ +public: + using Ptr = std::shared_ptr; + using LabeledPSIMsgQueue = bcos::ConcurrentQueue; + using LabeledPSIMsgQueuePtr = std::shared_ptr; + + LabeledPSIImpl(LabeledPSIConfig::Ptr _config, unsigned _idleTimeMs = 0); + + virtual ~LabeledPSIImpl() = default; + + // run task + void asyncRunTask(ppc::protocol::Task::ConstPtr _task, + ppc::task::TaskResponseCallback&& _onTaskFinished) override; + + // register to the front to get the message related to labeled-psi + void onReceiveMessage(ppc::front::PPCMessageFace::Ptr _message) override; + + void start() override; + void stop() override; + + void onReceivedErrorNotification(ppc::front::PPCMessageFace::Ptr const& _message) override; + void onSelfError( + const std::string& _taskID, bcos::Error::Ptr _error, bool _noticePeer) override; + + // labeled-psi main processing function + // for ut to make this function public + void executeWorker() override; + +protected: + void asyncRunSenderTask(const ppc::protocol::Task::ConstPtr& _task, + ppc::task::TaskResponseCallback&& _onTaskFinished); + + void checkFinishedTask(); + + void onSenderTaskDone(const std::string& _taskID); + + // init senderDB + void setupSenderDB(const ppc::protocol::Task::ConstPtr& _task, int _labelByteCount); + void saveSenderCache(const ppc::protocol::Task::ConstPtr& _task); + void loadSenderCache(const ppc::protocol::Task::ConstPtr& _task); + + void handleReceivedMessage(const ppc::front::PPCMessageFace::Ptr& _message); + void onReceivePsiParamsRequest(ppc::front::PPCMessageFace::Ptr _message); + void onReceivePsiParamsResponse(ppc::front::PPCMessageFace::Ptr _message); + void onReceiveBlindedItems(ppc::front::PPCMessageFace::Ptr _message); + void onReceiveEvaluatedItems(ppc::front::PPCMessageFace::Ptr _message); + void onReceiveQuery(ppc::front::PPCMessageFace::Ptr _message); + void onReceiveResponse(ppc::front::PPCMessageFace::Ptr _message); + + LabeledPSIReceiver::Ptr findReceiver(const std::string& _taskID) + { + bcos::ReadGuard l(x_receivers); + auto it = m_receivers.find(_taskID); + if (it != m_receivers.end()) + { + return it->second; + } + return nullptr; + } + void addReceiver(LabeledPSIReceiver::Ptr _receiver) + { + bcos::WriteGuard l(x_receivers); + m_receivers[_receiver->taskID()] = _receiver; + } + void removeReceiver(const std::string& _taskID) + { + bcos::WriteGuard l(x_receivers); + auto it = m_receivers.find(_taskID); + if (it != m_receivers.end()) + { + m_receivers.erase(it); + } + } + + +private: + void waitSignal() + { + boost::unique_lock l(x_signal); + m_signal.wait_for(l, boost::chrono::milliseconds(5)); + } + + void wakeupWorker() { m_signal.notify_all(); } + + LabeledPSIConfig::Ptr m_config; + LabeledPSIMsgQueuePtr m_msgQueue; + bcos::ThreadPool::Ptr m_worker; + + LabeledPSISender::Ptr m_sender; + std::atomic m_senderReady{false}; + + std::unordered_map m_receivers; + mutable bcos::SharedMutex x_receivers; + + SenderDB::Ptr m_senderDB; + + bool m_started = false; + boost::condition_variable m_signal; + boost::mutex x_signal; + + const int c_popWaitMs = 5; +}; +} // namespace ppc::psi \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-psi/src/labeled-psi/core/BinBundle.cpp b/cpp/wedpr-computing/ppc-psi/src/labeled-psi/core/BinBundle.cpp new file mode 100644 index 00000000..2cbb977b --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/labeled-psi/core/BinBundle.cpp @@ -0,0 +1,1287 @@ +/** + * Copyright (C) 2022 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. + * + * @reference https://github.com/microsoft/APSI/sender/bin_bundle.cpp + * @license MIT license + * @change change the implementation of load and save + * + * @file Binbundle.cpp + * @author: shawnhe + * @date 2022-12-18 + * + */ + +#include "BinBundle.h" + +// STD +#include +#include +#include +#include +#include + +// APSI +#include "apsi/bin_bundle.h" +#include "apsi/thread_pool_mgr.h" +#include "apsi/util/interpolate.h" +#include "apsi/util/utils.h" + +// SEAL +#include "seal/util/defines.h" + +using namespace std; +using namespace seal; +using namespace seal::util; +using namespace apsi; +using namespace apsi::sender::util; +using namespace ppc::psi; + +/** +Helper function. Determines if a field element is present in a bin. +*/ +bool is_present(const vector& bin, felt_t element) +{ + return bin.end() != find(bin.begin(), bin.end(), element); +} + +/** +Helper function. Determines if a field element is present in a bin. +*/ +bool is_present(const vector& bin, const CuckooFilter& filter, felt_t element) +{ + // Check if the key is already in the current bin. + if (filter.contains(element)) + { + // Perform a linear search to determine true/false positives + return is_present(bin, element); + } + + return false; +} + +/** +Helper function. Returns an iterator pointing to the given field element in the bin if +found and bin.end() otherwise. +*/ +template +auto get_iterator(BinT& bin, const CuckooFilter& filter, felt_t element) +{ + if (filter.contains(element)) + { + return find(bin.begin(), bin.end(), element); + } + + return bin.end(); +} + +void try_clear_irrelevant_bits(const EncryptionParameters& parms, Ciphertext& ciphertext) +{ + // If the parameter set has only one prime, we can compress the ciphertext by + // setting low-order bits to zero. This effectively maxes out the noise, but that + // doesn't matter as long as we don't use quite all noise budget. + if (parms.coeff_modulus().size() == 1) + { + // The number of data bits we need to have left in each ciphertext coefficient + int compr_coeff_bit_count = parms.plain_modulus().bit_count() + + get_significant_bit_count(parms.poly_modulus_degree()) + // Being pretty aggressive here + - 1; + + int coeff_mod_bit_count = parms.coeff_modulus()[0].bit_count(); + + // The number of bits to set to zero + int irrelevant_bit_count = coeff_mod_bit_count - compr_coeff_bit_count; + + // Can compression achieve anything? + if (irrelevant_bit_count > 0) + { + // Mask for zeroing out the irrelevant bits + uint64_t mask = ~((uint64_t(1) << irrelevant_bit_count) - 1); + seal_for_each_n(iter(ciphertext), ciphertext.size(), [&](auto&& I) { + // We only have a single RNS component so dereference once more + seal_for_each_n(*I, parms.poly_modulus_degree(), [&](auto& J) { J &= mask; }); + }); + } + } +} + +/** +Evaluates the polynomial on the given ciphertext. We don't compute the powers of the input +ciphertext C ourselves. Instead we assume they've been precomputed and accept the powers: +(C, C², C³, ...) as input. The number of powers provided MUST be at least +plaintext_polyn_coeffs_.size()-1. +*/ +Ciphertext BatchedPlaintextPolyn::eval( + const vector& ciphertext_powers, MemoryPoolHandle& pool) const +{ +#ifdef SEAL_THROW_ON_TRANSPARENT_CIPHERTEXT + static_assert(false, "SEAL must be built with SEAL_THROW_ON_TRANSPARENT_CIPHERTEXT=OFF"); +#endif + // We need to have enough ciphertext powers to evaluate this polynomial + if (ciphertext_powers.size() < max(batched_coeffs.size(), 2)) + { + throw invalid_argument("not enough ciphertext powers available"); + } + + auto seal_context = crypto_context.seal_context(); + auto evaluator = crypto_context.evaluator(); + + // We know now that ciphertext_powers is non-empty so read the parms_id from the first + // one; they should all be the same. + const auto& encode_parms_id = ciphertext_powers[1].parms_id(); + + // Lowest degree terms are stored in the lowest index positions in vectors. + // Specifically, ciphertext_powers[1] is the first power of the ciphertext data, but + // batched_coeffs[0] is the constant coefficient. + // + // Because the plaintexts in batched_coeffs can be identically zero, SEAL should be + // built with SEAL_THROW_ON_TRANSPARENT_CIPHERTEXT=OFF. We create a result ciphertext + // that is identically zero and set its NTT form flag to true so the additions below + // will work. + Ciphertext result(pool); + result.resize(*seal_context, encode_parms_id, 2); + result.is_ntt_form() = true; + Ciphertext temp(pool); + Plaintext coeff(pool); + for (size_t deg = 1; deg < batched_coeffs.size(); deg++) + { + coeff.unsafe_load(*seal_context, + reinterpret_cast(batched_coeffs[deg].data()), + batched_coeffs[deg].size()); + evaluator->multiply_plain(ciphertext_powers[deg], coeff, temp, pool); + evaluator->add_inplace(result, temp); + } + + // Need to transform back from NTT form before we can add the constant coefficient. The + // constant coefficient is specifically not in NTT form so this can work. + evaluator->transform_from_ntt_inplace(result); + coeff.unsafe_load(*seal_context, reinterpret_cast(batched_coeffs[0].data()), + batched_coeffs[0].size()); + evaluator->add_plain_inplace(result, coeff); + + // Make the result as small as possible by modulus switching and possibly clearing + // irrelevant bits. + while (result.parms_id() != seal_context->last_parms_id()) + { + evaluator->mod_switch_to_next_inplace(result, pool); + } + try_clear_irrelevant_bits(seal_context->last_context_data()->parms(), result); + + return result; +} + +/** +Evaluates the polynomial on the given ciphertext using the Paterson-Stockmeyer algorithm, +as long as it requires less computation than the standard evaluation function above. +The algorithm computes h+1 inner polynomials on low powers (C^1 to C^{l-1}). +Each inner polynomial is then multiplied by the corresponding high power. +The parameters l and h are determined according to the degree of the polynomial and the +number of splits in order to minimize the computation complexity. + +Evaluated polynomial a_0 + a_1*C + a_2*C^2 + ... + C^degree + +Inner polynomials: a_{l*i} + a_{l*i+1}*C + ... + a_{l*i+l-1}*C^{l-1} (for i=0,...,h-1) + and: a_{l*h} + a_{l*h+1}*C + ... + a_{l*h+degree%l}*C^{degree%l} (for i=h) + +Low powers: C^{1}, ..., C^{l-1} +High powers: C^{1*l}, ..., C^{l*h} +*/ +Ciphertext BatchedPlaintextPolyn::eval_patstock(const CryptoContext& eval_crypto_context, + const vector& ciphertext_powers, size_t ps_low_degree, MemoryPoolHandle& pool) const +{ +#ifdef SEAL_THROW_ON_TRANSPARENT_CIPHERTEXT + static_assert(false, "SEAL must be built with SEAL_THROW_ON_TRANSPARENT_CIPHERTEXT=OFF"); +#endif + // We need to have enough ciphertext powers to evaluate this polynomial + if (ciphertext_powers.size() < max(batched_coeffs.size(), 2)) + { + throw invalid_argument("not enough ciphertext powers available"); + } + + // This function should not be called when the low-degree is 1 + size_t degree = batched_coeffs.size() - 1; + if (ps_low_degree <= 1 || ps_low_degree >= degree) + { + throw invalid_argument( + "ps_low_degree must be greater than 1 and less than the " + "size of batched_coeffs"); + } + + auto seal_context = eval_crypto_context.seal_context(); + auto evaluator = eval_crypto_context.evaluator(); + auto relin_keys = eval_crypto_context.relin_keys(); + bool relinearize = eval_crypto_context.seal_context()->using_keyswitching(); + + auto high_powers_parms_id = get_parms_id_for_chain_idx(*crypto_context.seal_context(), 1); + + // This is the number of high-degree powers we have: the first high-degree is + // ps_low_degree + 1 and the rest are multiples of that up to (but not exceeding) the + // total degree. + size_t ps_high_degree = ps_low_degree + 1; + size_t ps_high_degree_powers = degree / ps_high_degree; + + // Lowest degree terms are stored in the lowest index positions in vectors. + // Specifically, ciphertext_powers[1] is the first power of the ciphertext data, but + // batched_coeffs[0] is the constant coefficient. + // + // Because the plaintexts in batched_coeffs can be identically zero, SEAL should be + // built with SEAL_THROW_ON_TRANSPARENT_CIPHERTEXT=OFF. We create a result ciphertext + // that is identically zero and set its NTT form flag to true so the additions below + // will work. The ciphertext here will have three components; we relinearize only at the + // end. + Ciphertext result(pool); + result.resize(*seal_context, high_powers_parms_id, 3); + result.is_ntt_form() = false; + + // Temporary variables + Ciphertext temp(pool); + Ciphertext temp_in(pool); + Plaintext coeff(pool); + + // Calculate polynomial for i=1,...,ps_high_degree_powers-1 + for (size_t i = 1; i < ps_high_degree_powers; i++) + { + // Evaluate inner polynomial. The free term is left out and added later on. + // The evaluation result is stored in temp_in. + for (size_t j = 1; j < ps_high_degree; j++) + { + coeff.unsafe_load(*seal_context, + reinterpret_cast(batched_coeffs[i * ps_high_degree + j].data()), + batched_coeffs[i * ps_high_degree + j].size()); + + evaluator->multiply_plain(ciphertext_powers[j], coeff, temp, pool); + + if (j == 1) + { + temp_in = temp; + } + else + { + evaluator->add_inplace(temp_in, temp); + } + } + + // Transform inner polynomial to coefficient form + evaluator->transform_from_ntt_inplace(temp_in); + evaluator->mod_switch_to_inplace(temp_in, high_powers_parms_id); + + // The high powers are already in coefficient form + evaluator->multiply_inplace(temp_in, ciphertext_powers[i * ps_high_degree], pool); + evaluator->add_inplace(result, temp_in); + } + + // Calculate polynomial for i=ps_high_degree_powers. + // Done separately because here the degree of the inner poly is degree % ps_high_degree. + // Once again, the free term will only be added later on. + if (degree % ps_high_degree > 0) + { + for (size_t j = 1; j <= degree % ps_high_degree; j++) + { + coeff.unsafe_load(*seal_context, + reinterpret_cast( + batched_coeffs[ps_high_degree_powers * ps_high_degree + j].data()), + batched_coeffs[ps_high_degree_powers * ps_high_degree + j].size()); + + evaluator->multiply_plain(ciphertext_powers[j], coeff, temp, pool); + + if (j == 1) + { + temp_in = temp; + } + else + { + evaluator->add_inplace(temp_in, temp); + } + } + + // Transform inner polynomial to coefficient form + evaluator->transform_from_ntt_inplace(temp_in); + evaluator->mod_switch_to_inplace(temp_in, high_powers_parms_id); + + // The high powers are already in coefficient form + evaluator->multiply_inplace( + temp_in, ciphertext_powers[ps_high_degree_powers * ps_high_degree], pool); + evaluator->add_inplace(result, temp_in); + } + + // Relinearize sum of ciphertext-ciphertext products if relinearization is supported by + // the parameters. + if (relinearize) + { + evaluator->relinearize_inplace(result, *relin_keys, pool); + } + + // Calculate inner polynomial for i=0. + // Done separately since there is no multiplication with a power of high-degree + for (size_t j = 1; j < ps_high_degree; j++) + { + coeff.unsafe_load(*seal_context, + reinterpret_cast(batched_coeffs[j].data()), batched_coeffs[j].size()); + + evaluator->multiply_plain(ciphertext_powers[j], coeff, temp, pool); + evaluator->transform_from_ntt_inplace(temp); + evaluator->mod_switch_to_inplace(temp, high_powers_parms_id); + evaluator->add_inplace(result, temp); + } + + // Add the constant coefficients of the inner polynomials multiplied by the respective + // powers of high-degree + for (size_t i = 1; i < ps_high_degree_powers + 1; i++) + { + coeff.unsafe_load(*seal_context, + reinterpret_cast(batched_coeffs[i * ps_high_degree].data()), + batched_coeffs[i * ps_high_degree].size()); + + evaluator->multiply_plain(ciphertext_powers[i * ps_high_degree], coeff, temp, pool); + evaluator->mod_switch_to_inplace(temp, high_powers_parms_id); + evaluator->add_inplace(result, temp); + } + + // Add the constant coefficient + coeff.unsafe_load(*seal_context, reinterpret_cast(batched_coeffs[0].data()), + batched_coeffs[0].size()); + + evaluator->add_plain_inplace(result, coeff); + + // Make the result as small as possible by modulus switching and possibly clearing + // irrelevant bits. + while (result.parms_id() != seal_context->last_parms_id()) + { + evaluator->mod_switch_to_next_inplace(result, pool); + } + try_clear_irrelevant_bits(seal_context->last_context_data()->parms(), result); + + return result; +} + +/** +Constructs a batched Plaintext polynomial from a list of polynomials. Takes an evaluator and +batch encoder to do encoding and NTT ops. +*/ +BatchedPlaintextPolyn::BatchedPlaintextPolyn( + const vector& polyns, CryptoContext context, uint32_t ps_low_degree, bool compressed) + : crypto_context(std::move(context)) +{ + // compr_mode_type compr_mode = compressed ? compr_mode_type::zstd : + // compr_mode_type::none; + compr_mode_type compr_mode = compr_mode_type::none; + // Find the highest degree polynomial in the list. The max degree determines how many + // Plaintexts we need to make + size_t max_deg = 0; + for (const FEltPolyn& p : polyns) + { + // Degree = number of coefficients - 1 + max_deg = max(p.size(), max_deg + 1) - 1; + } + + // We will encode with parameters that leave one or two levels, depending on whether + // Paterson-Stockmeyer is used. + size_t plain_coeffs_chain_idx = min( + crypto_context.seal_context()->first_context_data()->chain_index(), ps_low_degree ? 2 : 1); + auto encode_parms_id = + get_parms_id_for_chain_idx(*crypto_context.seal_context(), plain_coeffs_chain_idx); + + // Now make the Plaintexts. We let Plaintext i contain all bin coefficients of degree i. + size_t num_polyns = polyns.size(); + for (size_t i = 0; i < max_deg + 1; i++) + { + // Go through all the bins, collecting the coefficients at degree i + vector coeffs_of_deg_i; + coeffs_of_deg_i.reserve(num_polyns); + for (const FEltPolyn& p : polyns) + { + // Get the coefficient if it's set. Otherwise it's zero + felt_t coeff = 0; + if (i < p.size()) + { + coeff = p[i]; + } + + coeffs_of_deg_i.push_back(coeff); + } + + // Now let pt be the Plaintext consisting of all those degree i coefficients + Plaintext pt; + crypto_context.encoder()->encode(coeffs_of_deg_i, pt); + + // When evaluating the match and interpolation polynomials on encrypted query data, + // we multiply each power of the encrypted query with a plaintext (pt here) + // corresponding to the polynomial coefficient, and add the results together. The + // constant coefficient is handled by simply adding to the result, which requires + // that the plaintext is not in NTT form. When Paterson-Stockmeyer is used, this + // applies also to the constant coefficients for all inner polynomials, i.e., with + // i a multiple of the ps_high_degree == ps_low_degree + 1. + if ((!ps_low_degree && (i != 0)) || (ps_low_degree && (i % (ps_low_degree + 1)))) + { + crypto_context.evaluator()->transform_to_ntt_inplace(pt, encode_parms_id); + } + + // Push the new Plaintext + vector pt_data; + pt_data.resize(safe_cast(pt.save_size(compr_mode))); + size_t size = static_cast( + pt.save(reinterpret_cast(pt_data.data()), pt_data.size(), compr_mode)); + pt_data.resize(size); + batched_coeffs.push_back(std::move(pt_data)); + } +} + +BinBundleCache::BinBundleCache(const CryptoContext& crypto_context, size_t label_size) + : batched_matching_polyn(crypto_context) +{ + batched_interp_polyns.reserve(label_size); + for (size_t label_idx = 0; label_idx < label_size; label_idx++) + { + batched_interp_polyns.emplace_back(crypto_context); + } +} + +BinBundle::BinBundle(const CryptoContext& crypto_context, size_t label_size, size_t max_bin_size, + size_t ps_low_degree, size_t num_bins, bool compressed, bool stripped) + : cache_invalid_(true), + crypto_context_(crypto_context), + compressed_(compressed), + label_size_(label_size), + max_bin_size_(max_bin_size), + ps_low_degree_(ps_low_degree), + num_bins_(num_bins), + cache_(crypto_context_, label_size_) +{ + if (!crypto_context_.evaluator()) + { + throw invalid_argument("evaluator is not set in crypto_context"); + } + if (ps_low_degree > max_bin_size) + { + throw invalid_argument("ps_low_degree cannot be larger than max_bin_size"); + } + if (!num_bins) + { + throw invalid_argument("num_bins cannot be zero"); + } + + // Set up internal data structures + clear(stripped); +} + +/** +Returns the modulus that defines the finite field that we're working in +*/ +const Modulus& BinBundle::field_mod() const +{ + const auto& context_data = crypto_context_.seal_context()->first_context_data(); + return context_data->parms().plain_modulus(); +} + +template <> +int32_t BinBundle::multi_insert(const vector& items, size_t start_bin_idx, bool dry_run) +{ + if (stripped_) + { + LABELED_PSI_LOG(ERROR) << LOG_DESC("Cannot insert data to a stripped BinBundle"); + throw logic_error("failed to insert data"); + } + if (items.empty()) + { + LABELED_PSI_LOG(ERROR) << LOG_DESC("No item data to insert"); + return -1; + } + + // We are inserting items only; no labels. This BinBundle cannot have a non-zero label + // size. + if (get_label_size()) + { + LABELED_PSI_LOG(ERROR) << LOG_DESC( + "Attempted to insert unlabeled data in a labeled BinBundle"); + throw logic_error("failed to insert data"); + } + + // Return -1 if there isn't enough room in the BinBundle to insert at the given location + if (start_bin_idx >= get_num_bins() || items.size() > get_num_bins() - start_bin_idx) + { + return -1; + } + + // If we're here, that means we can insert in all bins + size_t max_bin_size = 0; + size_t curr_bin_idx = start_bin_idx; + for (felt_t curr_item : items) + { + vector& curr_bin = item_bins_[curr_bin_idx]; + + // Compare the would-be bin size here to the running max + if (max_bin_size < curr_bin.size() + 1) + { + max_bin_size = curr_bin.size() + 1; + } + + // Insert if not dry run + if (!dry_run) + { + // Insert the new item + CuckooFilter& curr_filter = filters_[curr_bin_idx]; + curr_bin.push_back(curr_item); + curr_filter.add(curr_item); + + // Indicate that the polynomials need to be recomputed + cache_invalid_ = true; + } + + curr_bin_idx++; + } + + return safe_cast(max_bin_size); +} + +template <> +int32_t BinBundle::multi_insert( + const vector>>& item_labels, size_t start_bin_idx, bool dry_run) +{ + if (stripped_) + { + LABELED_PSI_LOG(ERROR) << LOG_DESC("Cannot insert data to a stripped BinBundle"); + throw logic_error("failed to insert data"); + } + if (item_labels.empty()) + { + LABELED_PSI_LOG(ERROR) << LOG_DESC("No item or label data to insert"); + return -1; + } + + // We are inserting item-labels. This BinBundle cannot have a zero label size. + if (!get_label_size()) + { + LABELED_PSI_LOG(ERROR) << LOG_DESC( + "Attempted to insert labeled data in an unlabeled BinBundle"); + throw logic_error("failed to insert data"); + } + + // Check that item_labels has correct size + size_t label_size = get_label_size(); + for (const auto& curr_item_label : item_labels) + { + size_t curr_label_size = curr_item_label.second.size(); + if (curr_label_size != label_size) + { + LABELED_PSI_LOG(ERROR) + << LOG_DESC("Attempted to insert item-label with incorrect label size ") + << LOG_KV("curr_label_size", curr_label_size) << LOG_KV("expected", label_size); + throw invalid_argument("failed to insert data"); + } + } + + // Return -1 if there isn't enough room in the BinBundle to insert at the given location + if (start_bin_idx >= get_num_bins() || item_labels.size() > get_num_bins() - start_bin_idx) + { + return -1; + } + + // Do we have a non-zero label size? In that case we cannot have repeated item parts in + // bins + if (get_label_size()) + { + // For each key, check that we can insert into the corresponding bin. If the answer + // is "no" at any point, return -1. + size_t curr_bin_idx = start_bin_idx; + for (auto& curr_item_label : item_labels) + { + felt_t curr_item = curr_item_label.first; + vector& curr_bin = item_bins_[curr_bin_idx]; + CuckooFilter& curr_filter = filters_[curr_bin_idx]; + + // Check if the key is already in the current bin. If so, that's an insertion + // error + if (is_present(curr_bin, curr_filter, curr_item)) + { + return -1; + } + + curr_bin_idx++; + } + } + + // If we're here, that means we can insert in all bins + size_t max_bin_size = 0; + size_t curr_bin_idx = start_bin_idx; + for (auto& curr_item_label : item_labels) + { + felt_t curr_item = curr_item_label.first; + vector& curr_bin = item_bins_[curr_bin_idx]; + + // Compare the would-be bin size here to the running max + if (max_bin_size < curr_bin.size() + 1) + { + max_bin_size = curr_bin.size() + 1; + } + + // Insert if not dry run + if (!dry_run) + { + // Insert the new item + CuckooFilter& curr_filter = filters_[curr_bin_idx]; + curr_bin.push_back(curr_item); + curr_filter.add(curr_item); + + // Insert the new label; loop over each label part + for (size_t label_idx = 0; label_idx < get_label_size(); label_idx++) + { + // Add this label part to the matching bin + felt_t curr_label = curr_item_label.second[label_idx]; + label_bins_[label_idx][curr_bin_idx].push_back(curr_label); + } + + // Indicate that the polynomials need to be recomputed + cache_invalid_ = true; + } + + curr_bin_idx++; + } + + return safe_cast(max_bin_size); +} + +template <> +bool BinBundle::try_multi_overwrite(const vector& items, size_t start_bin_idx) +{ + if (stripped_) + { + LABELED_PSI_LOG(ERROR) << LOG_DESC("Cannot overwrite data in a stripped BinBundle"); + throw logic_error("failed to overwrite data"); + } + if (items.empty()) + { + LABELED_PSI_LOG(ERROR) << LOG_DESC("No item data to insert"); + return false; + } + + // This function may have been called accidentally; no label data is given, so nothing + // will be overwritten. This is equivalent to searching for the presence of the felt + // items in this BinBundle and forcing the cache to be recomputed. + // Return false if there isn't enough room in the BinBundle to insert at the given + // location + if (start_bin_idx >= get_num_bins() || items.size() > get_num_bins() - start_bin_idx) + { + return false; + } + + // Check that all the item components appear sequentially in this BinBundle + size_t curr_bin_idx = start_bin_idx; + for (felt_t curr_item : items) + { + vector& curr_bin = item_bins_[curr_bin_idx]; + CuckooFilter& curr_filter = filters_[curr_bin_idx]; + + // A non-match was found; the item is not here. + if (!is_present(curr_bin, curr_filter, curr_item)) + { + return false; + } + + curr_bin_idx++; + } + + // Nothing was done, but mark the cache as dirty anyway + cache_invalid_ = true; + + return true; +} + +template <> +bool BinBundle::try_multi_overwrite( + const vector>>& item_labels, size_t start_bin_idx) +{ + if (stripped_) + { + LABELED_PSI_LOG(ERROR) << LOG_DESC("Cannot overwrite data in a stripped BinBundle"); + throw logic_error("failed to overwrite data"); + } + if (item_labels.empty()) + { + LABELED_PSI_LOG(ERROR) << LOG_DESC("No item or label data to insert"); + return false; + } + + // Check that item_labels has correct size + size_t label_size = get_label_size(); + for (const auto& curr_item_label : item_labels) + { + size_t curr_label_size = curr_item_label.second.size(); + if (curr_label_size != label_size) + { + LABELED_PSI_LOG(ERROR) + << LOG_DESC("Attempted to overwrite item-label with incorrect label size ") + << LOG_KV("curr_label_size", curr_label_size) << LOG_KV("expected", label_size); + + throw invalid_argument("failed to overwrite data"); + } + } + + // Return false if there isn't enough room in the BinBundle to insert at the given + // location + if (start_bin_idx >= get_num_bins() || item_labels.size() > get_num_bins() - start_bin_idx) + { + return false; + } + + // Check that all the item components appear sequentially in this BinBundle + size_t curr_bin_idx = start_bin_idx; + for (auto& curr_item_label : item_labels) + { + felt_t curr_item = curr_item_label.first; + vector& curr_bin = item_bins_[curr_bin_idx]; + CuckooFilter& curr_filter = filters_[curr_bin_idx]; + + // A non-match was found; the item is not here. + if (!is_present(curr_bin, curr_filter, curr_item)) + { + return false; + } + + curr_bin_idx++; + } + + // If we're here, that means we can overwrite the labels + curr_bin_idx = start_bin_idx; + for (auto& curr_item_label : item_labels) + { + felt_t curr_item = curr_item_label.first; + + // Overwrite the label in the bin + vector& curr_bin = item_bins_[curr_bin_idx]; + + // No point in using cuckoo filters here for look-up: we know the item exists so do + // linear search + auto found_pos = find(curr_bin.begin(), curr_bin.end(), curr_item); + + // From the earlier check we know that found_pos is not the end-iterator. Check this + // again to be sure. + if (found_pos == curr_bin.end()) + { + LABELED_PSI_LOG(ERROR) << LOG_DESC( + "Attempted to overwrite item-label, but the item could no longer be found; " + "the internal state of this BinBundle has been corrupted"); + throw runtime_error("failed to overwrite data"); + } + + // Compute the location in the curr_bin so we know how to index into the label bins + auto item_idx_in_bin = static_cast(distance(curr_bin.begin(), found_pos)); + + // Write the new label; loop over each label part + for (size_t label_idx = 0; label_idx < get_label_size(); label_idx++) + { + // Overwrite this label part in the matching bin + felt_t curr_label = curr_item_label.second[label_idx]; + label_bins_[label_idx][curr_bin_idx][item_idx_in_bin] = curr_label; + } + + // Indicate that the polynomials need to be recomputed + cache_invalid_ = true; + + curr_bin_idx++; + } + + return true; +} + +bool BinBundle::try_multi_remove(const vector& items, size_t start_bin_idx) +{ + if (stripped_) + { + LABELED_PSI_LOG(ERROR) << LOG_DESC("Cannot remove data from a stripped BinBundle"); + throw logic_error("failed to remove data"); + } + if (items.empty()) + { + LABELED_PSI_LOG(ERROR) << LOG_DESC("No item data to remove"); + return false; + } + + // Return false if there isn't enough room in the BinBundle at the given location + if (start_bin_idx >= get_num_bins() || items.size() > get_num_bins() - start_bin_idx) + { + return false; + } + + // Go through all the items. If any item doesn't appear, we scrap the whole computation + // and return false. + size_t curr_bin_idx = start_bin_idx; + vector::iterator> to_remove_item_its; + vector::iterator>> to_remove_label_its(get_label_size()); + + for (auto& item : items) + { + vector& curr_bin = item_bins_[curr_bin_idx]; + CuckooFilter& curr_filter = filters_[curr_bin_idx]; + + auto to_remove_item_it = get_iterator(curr_bin, curr_filter, item); + if (curr_bin.end() == to_remove_item_it) + { + // One of the items isn't there; return false; + return false; + } + else + { + // Found the item; mark it for removal + to_remove_item_its.push_back(to_remove_item_it); + + // We need to also mark the corresponding labels for removal + auto item_loc_in_bin = distance(curr_bin.begin(), to_remove_item_it); + for (size_t label_idx = 0; label_idx < get_label_size(); label_idx++) + { + auto to_remove_label_it = + label_bins_[label_idx][curr_bin_idx].begin() + item_loc_in_bin; + to_remove_label_its[label_idx].push_back(to_remove_label_it); + } + } + + curr_bin_idx++; + } + + // We got to this point, so all of the items were found. Now just erase them. + curr_bin_idx = start_bin_idx; + for (auto to_remove_item_it : to_remove_item_its) + { + // Remove the item + filters_[curr_bin_idx].remove(*to_remove_item_it); + item_bins_[curr_bin_idx].erase(to_remove_item_it); + + // Indicate that the polynomials need to be recomputed + cache_invalid_ = true; + + curr_bin_idx++; + } + + // Finally erase the label parts + for (size_t label_idx = 0; label_idx < get_label_size(); label_idx++) + { + curr_bin_idx = start_bin_idx; + for (auto to_remove_label_it : to_remove_label_its[label_idx]) + { + // Remove the label + label_bins_[label_idx][curr_bin_idx].erase(to_remove_label_it); + + curr_bin_idx++; + } + } + + return true; +} + +bool BinBundle::try_get_multi_label( + const vector& items, size_t start_bin_idx, vector& labels) const +{ + if (stripped_) + { + LABELED_PSI_LOG(ERROR) << LOG_DESC("Cannot retrieve labels from a stripped BinBundle"); + throw logic_error("failed to retrieve labels"); + } + if (items.empty()) + { + LABELED_PSI_LOG(ERROR) << LOG_DESC("No item data to search for"); + return false; + } + + // Return false if there isn't enough room in the BinBundle at the given location + if (start_bin_idx >= get_num_bins() || items.size() > get_num_bins() - start_bin_idx) + { + return false; + } + + // Resize the labels vector to expected size; we will write in a non-linear order + labels.clear(); + labels.resize(items.size() * get_label_size()); + + // Go through all the items. If the item appears, find its label and write to labels. If + // any item doesn't appear, we scrap the whole computation and return false. + size_t curr_bin_idx = start_bin_idx; + for (size_t item_idx = 0; item_idx < items.size(); item_idx++) + { + const vector& curr_bin = item_bins_[curr_bin_idx]; + const CuckooFilter& curr_filter = filters_[curr_bin_idx]; + + // Find the item if present in this bin + auto item_it = get_iterator(curr_bin, curr_filter, items[item_idx]); + + if (curr_bin.end() == item_it) + { + // One of the items isn't there. No label to fetch. Clear the labels and return + // early. + labels.clear(); + return false; + } + + // Found the (felt) item. Next collect the label parts for this and write to label. + size_t item_idx_in_bin = static_cast(distance(curr_bin.begin(), item_it)); + for (size_t label_idx = 0; label_idx < get_label_size(); label_idx++) + { + // Need to reorder the felts + labels[items.size() * label_idx + item_idx] = + label_bins_[label_idx][curr_bin_idx][item_idx_in_bin]; + } + + curr_bin_idx++; + } + + return true; +} + +void BinBundle::clear(bool stripped) +{ + // Set the stripped flag + stripped_ = stripped; + + // Clear item data + item_bins_.clear(); + if (!stripped_) + { + item_bins_.resize(num_bins_); + } + + // Clear label data + label_bins_.clear(); + if (!stripped_) + { + label_bins_.reserve(label_size_); + for (size_t i = 0; i < label_size_; i++) + { + label_bins_.emplace_back(num_bins_); + } + } + + // Clear filters + filters_.clear(); + if (!stripped_) + { + filters_.reserve(num_bins_); + for (size_t i = 0; i < num_bins_; i++) + { + filters_.emplace_back(max_bin_size_, /* bits per tag */ 12); + } + } + + // Clear the cache + clear_cache(); +} + +void BinBundle::clear_cache() +{ + cache_.felt_matching_polyns.clear(); + cache_.batched_matching_polyn = crypto_context_; + + cache_.felt_interp_polyns.clear(); + cache_.batched_interp_polyns.clear(); + + cache_invalid_ = true; +} + +const BinBundleCache& BinBundle::get_cache() const +{ + if (cache_invalid_) + { + throw logic_error("tried to retrieve stale cache"); + } + + return cache_; +} + +void BinBundle::regen_plaintexts() +{ + // This function assumes that BinBundle::clear_cache and BinBundle::regen_polyns have + // been called and the polynomials have not been modified since then. + + // Allocate memory for the batched "label polynomials" + cache_.batched_interp_polyns.resize(get_label_size()); + + ThreadPoolMgr tpm; + + vector> futures; + futures.push_back(tpm.thread_pool().enqueue([&]() { + // Compute and cache the batched "matching polynomials". They're computed in both + // labeled and unlabeled PSI. + BatchedPlaintextPolyn bmp(cache_.felt_matching_polyns, crypto_context_, + static_cast(ps_low_degree_), compressed_); + cache_.batched_matching_polyn = std::move(bmp); + })); + + for (size_t label_idx = 0; label_idx < cache_.felt_interp_polyns.size(); label_idx++) + { + futures.push_back(tpm.thread_pool().enqueue([&, label_idx]() { + // Compute and cache the batched Newton interpolation polynomials + const auto& interp_polyn = cache_.felt_interp_polyns[label_idx]; + BatchedPlaintextPolyn bip( + interp_polyn, crypto_context_, static_cast(ps_low_degree_), compressed_); + cache_.batched_interp_polyns[label_idx] = std::move(bip); + })); + } + + // Wait for the tasks to finish + for (auto& f : futures) + { + f.get(); + } +} + +void BinBundle::regen_polyns() +{ + // This function assumes that BinBundle::clear_cache has been called and the polynomials + // have not been modified since then. Specifically, it assumes that item_bins_ is empty + // and and label_bins_ is set to the correct size. + + // Get the field modulus. We need this for polynomial calculations + const Modulus& mod = field_mod(); + + size_t num_bins = get_num_bins(); + size_t label_size = get_label_size(); + cache_.felt_matching_polyns.resize(num_bins); + cache_.felt_interp_polyns.resize(label_size); + for (auto& fips : cache_.felt_interp_polyns) + { + fips.resize(num_bins); + } + + ThreadPoolMgr tpm; + + vector> futures; + // For each bin in the bundle, compute and cache the corresponding "matching + // polynomial" + for (size_t bin_idx = 0; bin_idx < num_bins; bin_idx++) + { + futures.push_back(tpm.thread_pool().enqueue([&, bin_idx]() { + // Compute and cache the matching polynomial + FEltPolyn fmp = polyn_with_roots(item_bins_[bin_idx], mod); + cache_.felt_matching_polyns[bin_idx] = std::move(fmp); + })); + } + + // For each bin in the bundle, compute and cache the corresponding "label polynomials" + for (size_t label_idx = 0; label_idx < label_size; label_idx++) + { + for (size_t bin_idx = 0; bin_idx < num_bins; bin_idx++) + { + futures.push_back(tpm.thread_pool().enqueue([&, label_idx, bin_idx]() { + // Compute and cache the matching polynomial + FEltPolyn fip = newton_interpolate_polyn( + item_bins_[bin_idx], label_bins_[label_idx][bin_idx], mod); + cache_.felt_interp_polyns[label_idx][bin_idx] = std::move(fip); + })); + } + } + + // Wait for the tasks to finish + for (auto& f : futures) + { + f.get(); + } +} + +void BinBundle::regen_cache() +{ + // Only recompute the cache if it needs to be recomputed + if (cache_invalid_) + { + clear_cache(); + regen_polyns(); + regen_plaintexts(); + cache_invalid_ = false; + } +} + +bool BinBundle::empty() const +{ + return all_of(item_bins_.begin(), item_bins_.end(), [](auto& b) { return b.empty(); }); +} + +void BinBundle::strip() +{ + // Ensure the cache is valid + regen_cache(); + + stripped_ = true; + + item_bins_.clear(); + label_bins_.clear(); + filters_.clear(); + + cache_.felt_matching_polyns.clear(); + cache_.felt_interp_polyns.clear(); +} + +ppctars::BinBundle BinBundle::saveToTarsBinBundle() const +{ + ppctars::BinBundle binBundle; + + // write the items and labels + for (auto& bins : item_bins_) + { + std::vector tarsBins; + tarsBins.reserve(bins.size()); + for (auto& item : bins) + { + tarsBins.emplace_back(item); + } + binBundle.itemBins.emplace_back(tarsBins); + } + for (auto& bins : label_bins_) + { + std::vector> tarsBins; + for (auto& labels : bins) + { + std::vector tarsLabels; + tarsLabels.reserve(labels.size()); + for (auto& label : labels) + { + tarsLabels.emplace_back(label); + } + tarsBins.emplace_back(tarsLabels); + } + binBundle.labelBins.emplace_back(tarsBins); + } + + // write BinBundleCache + ppctars::BinBundleCache binBundleCache; + + for (auto& polyns : cache_.felt_matching_polyns) + { + std::vector tarsPolyns; + tarsPolyns.reserve(polyns.size()); + for (auto& polyn : polyns) + { + tarsPolyns.emplace_back(polyn); + } + binBundleCache.feltMatchingPolyns.emplace_back(tarsPolyns); + } + for (auto& interpPolyns : cache_.felt_interp_polyns) + { + std::vector> tarsInterpPolyns; + for (auto& polyns : interpPolyns) + { + std::vector tarsPolyns; + tarsPolyns.reserve(polyns.size()); + for (auto& polyn : polyns) + { + tarsPolyns.emplace_back(polyn); + } + tarsInterpPolyns.emplace_back(tarsPolyns); + } + binBundleCache.feltInterpPolyns.emplace_back(tarsInterpPolyns); + } + binBundleCache.batchedMatchingPolyn.batchedCoeffs = + cache_.batched_matching_polyn.batched_coeffs; + for (auto& polyns : cache_.batched_interp_polyns) + { + ppctars::BatchedPlaintextPolyn batchedPlaintextPolyn; + batchedPlaintextPolyn.batchedCoeffs = polyns.batched_coeffs; + binBundleCache.batchedInterpPolyns.emplace_back(batchedPlaintextPolyn); + } + binBundle.cache = binBundleCache; + + binBundle.cacheInvalid = cache_invalid_; + binBundle.compressed = compressed_; + binBundle.stripped = stripped_; + binBundle.labelSize = label_size_; + binBundle.maxBinSize = max_bin_size_; + binBundle.psLowDegree = ps_low_degree_; + binBundle.numBins = num_bins_; + + return binBundle; +} + +BinBundle BinBundle::loadFromTarsBinBundle( + const CryptoContext& _cryptoContext, const ppctars::BinBundle& _tarsBinBundle) +{ + BinBundle binBundle(_cryptoContext, _tarsBinBundle.labelSize, _tarsBinBundle.maxBinSize, + _tarsBinBundle.psLowDegree, _tarsBinBundle.numBins, _tarsBinBundle.compressed, + _tarsBinBundle.stripped); + binBundle.cache_invalid_ = _tarsBinBundle.cacheInvalid; + + // load the items and labels + binBundle.item_bins_.clear(); + for (auto& tarsBins : _tarsBinBundle.itemBins) + { + std::vector bins; + bins.reserve(tarsBins.size()); + for (auto& item : tarsBins) + { + bins.emplace_back(item); + } + binBundle.item_bins_.emplace_back(bins); + } + + binBundle.label_bins_.clear(); + for (auto& tarsBins : _tarsBinBundle.labelBins) + { + std::vector> bins; + for (auto& tarsLabels : tarsBins) + { + std::vector labels; + labels.reserve(tarsLabels.size()); + for (auto& label : tarsLabels) + { + labels.emplace_back(label); + } + bins.emplace_back(labels); + } + binBundle.label_bins_.emplace_back(bins); + } + + // init CuckooFilter + auto binSize = binBundle.item_bins_.size(); + for (size_t binIdx = 0; !binBundle.stripped_ && (binIdx < binSize); binIdx++) + { + auto& items = binBundle.item_bins_[binIdx]; + for (auto& felt : items) + { + binBundle.filters_[binIdx].add(felt); + } + } + + // init BinBundleCache + for (auto& tarsPolyns : _tarsBinBundle.cache.feltMatchingPolyns) + { + std::vector polyns; + polyns.reserve(tarsPolyns.size()); + for (auto& polyn : tarsPolyns) + { + polyns.emplace_back(polyn); + } + binBundle.cache_.felt_matching_polyns.emplace_back(polyns); + } + for (auto& tarsInterpPolyns : _tarsBinBundle.cache.feltInterpPolyns) + { + std::vector> interpPolyns; + for (auto& tarsPolyns : tarsInterpPolyns) + { + std::vector polyns; + polyns.reserve(tarsPolyns.size()); + for (auto& polyn : tarsPolyns) + { + polyns.emplace_back(polyn); + } + interpPolyns.emplace_back(polyns); + } + binBundle.cache_.felt_interp_polyns.emplace_back(interpPolyns); + } + binBundle.cache_.batched_matching_polyn.batched_coeffs = + _tarsBinBundle.cache.batchedMatchingPolyn.batchedCoeffs; + for (auto& polyn : _tarsBinBundle.cache.batchedInterpPolyns) + { + BatchedPlaintextPolyn batchedPlaintextPolyn; + batchedPlaintextPolyn.batched_coeffs = polyn.batchedCoeffs; + batchedPlaintextPolyn.crypto_context = _cryptoContext; + binBundle.cache_.batched_interp_polyns.emplace_back(std::move(batchedPlaintextPolyn)); + } + + return binBundle; +} diff --git a/cpp/wedpr-computing/ppc-psi/src/labeled-psi/core/BinBundle.h b/cpp/wedpr-computing/ppc-psi/src/labeled-psi/core/BinBundle.h new file mode 100644 index 00000000..e2273f3a --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/labeled-psi/core/BinBundle.h @@ -0,0 +1,430 @@ +/** + * Copyright (C) 2022 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. + * + * @reference https://github.com/microsoft/APSI/sender/bin_bundle.h + * @license MIT license + * @change change the implementation of load and save + * + * @file Binbundle.h + * @author: shawnhe + * @date 2022-12-18 + * + */ + +#pragma once + +// STD +#include +#include +#include + +// APSI +#include "apsi/crypto_context.h" +#include "apsi/util/cuckoo_filter.h" +#include "apsi/util/db_encoding.h" + +// SEAL +#include "seal/util/uintarithsmallmod.h" +#include "seal/util/uintcore.h" + +// GSL +#include "gsl/span" + +#include + +#include "../Common.h" +#include "SenderCache.h" +#include + +using namespace apsi::util; + +namespace ppc::psi +{ +/** +Represents a polynomial with coefficients that are field elements. Coefficients are stored +in degree-increasing order, so, for example, the constant term is at index 0. +*/ +using FEltPolyn = std::vector; + +/** +A bunch of polynomials represented using a sequence of batched SEAL Plaintexts. + +Example: Suppose we have 3 polynomials, + + 3x⁵ + 7x⁴ + x³ + 9x² + 4x + 2 + 8x³ + 5x² + + 1 + 9x⁴ + 2x³ + + x + 8 + +To represent them as a BatchedPlaintextPolyn, we would make a Plaintext for every column of +coefficients. Suppose each Plaintext has 3 slots. Let Plaintext #i holds all the +coefficients of degree i. So then the plaintexts P₀, ..., P₅ would be + + |P₅|P₄|P₃|P₂|P₁|P₀| + |--|--|--|--|--|--| + | 3| 7| 1| 9| 4| 2| + | 0| 0| 8| 5| 0| 1| + | 0| 9| 2| 0| 1| 8| +*/ +struct BatchedPlaintextPolyn +{ + /** + A sequence of coefficients represented as batched plaintexts. The length of this vector + is the degree of the highest-degree polynomial in the sequence. + */ + std::vector> batched_coeffs; + + /** + We need this to compute eval() + */ + apsi::CryptoContext crypto_context; + + BatchedPlaintextPolyn(const BatchedPlaintextPolyn& copy) = delete; + + BatchedPlaintextPolyn(BatchedPlaintextPolyn&& source) = default; + + BatchedPlaintextPolyn& operator=(const BatchedPlaintextPolyn& assign) = delete; + + BatchedPlaintextPolyn& operator=(BatchedPlaintextPolyn&& assign) = default; + + /** + Construct and empty BatchedPlaintextPolyn instance. + */ + BatchedPlaintextPolyn() = default; + + /** + Constructs a batched Plaintext polynomial from a list of polynomials. Takes an evaluator + and batch encoder to do encoding and NTT ops. + */ + BatchedPlaintextPolyn(const std::vector& polyns, apsi::CryptoContext context, + std::uint32_t ps_low_degree, bool compressed); + + /** + Constructs an uninitialized Plaintext polynomial using the given crypto context + */ + BatchedPlaintextPolyn(apsi::CryptoContext context) : crypto_context(std::move(context)) {} + + /** + Evaluates the polynomial on the given ciphertext. We don't compute the powers of the + input ciphertext C ourselves. Instead we assume they've been precomputed and accept the + powers: (C, C², C³, ...) as input. The number of powers provided MUST be equal to + plaintext_polyn_coeffs_.size()-1. + */ + seal::Ciphertext eval( + const std::vector& ciphertext_powers, seal::MemoryPoolHandle& pool) const; + + /** + Evaluates the polynomial on the given ciphertext using the Paterson-Stockmeyer + algorithm, as long as it requires less computation than the standard evaluation function + above. The algorithm computes h+1 inner polynomials on low powers (C¹ to C^{l-1}). Each + inner polynomial is then multiplied by the corresponding high power. The parameters l + and h are determined according to the degree of the polynomial and the number of splits + in order to minimize the computation. + + Evaluated polynomial a_0 + a_1*C + a_2*C^2 + ... + C^degree + + Inner polys: a_{l*i} + a_{l*i+1}*C + ... + a_{l*i+l-1}*C^{l-1} (for i=0,...,h-1) + and: a_{l*h} + a_{l*h+1}*C + ... + a_{l*h+degree%l}*C^{degree%l} (for i=h) + + Low powers: C^{1}, ..., C^{l-1} + High powers: C^{1*l}, ..., C^{l*h} + */ + seal::Ciphertext eval_patstock(const apsi::CryptoContext& eval_crypto_context, + const std::vector& ciphertext_powers, std::size_t ps_low_degree, + seal::MemoryPoolHandle& pool) const; + + /** + Returns whether this polynomial has non-zero size. + */ + explicit operator bool() const noexcept { return batched_coeffs.size(); } +}; + +// A cache of all the polynomial and plaintext computations on a single BinBundle +struct BinBundleCache +{ + BinBundleCache(const BinBundleCache& copy) = delete; + + BinBundleCache(BinBundleCache&& source) = default; + + BinBundleCache& operator=(const BinBundleCache& assign) = delete; + + BinBundleCache& operator=(BinBundleCache&& assign) = default; + + BinBundleCache(const apsi::CryptoContext& crypto_context, std::size_t label_size); + + /** + For each bin, stores the "matching polynomial", i.e., unique monic polynomial whose + roots are precisely the items in the bin. + */ + std::vector felt_matching_polyns; + + /** + For each bin, stores the Newton intepolation polynomial whose value at each item in the + bin equals the item's corresponding label. Note that this field is empty when doing + unlabeled PSI. + */ + std::vector> felt_interp_polyns; + + /** + Cached seal::Plaintext representation of the "matching" polynomial of this BinBundle. + */ + BatchedPlaintextPolyn batched_matching_polyn; + + /** + Cached seal::Plaintext representation of the interpolation polynomial of this BinBundle. + Note that this field is empty when doing unlabeled PSI. + */ + std::vector batched_interp_polyns; +}; // struct BinBundleCache + +/** +Represents a specific bin bundle and stores the associated data. The type parameter L +represents the label type. This is either a field element (in the case of labeled PSI), or +an element of the unit type (in the case of unlabeled PSI). +*/ +class BinBundle +{ +private: + /** + This is true iff cache_ needs to be regenerated + */ + bool cache_invalid_; + + /** + We need this to make Plaintexts + */ + apsi::CryptoContext crypto_context_; + + /** + Items (decomposed into field elements) for each bin in the BinBundle. The dimensions + are, in order: + - Bins in the BinBundle + - Field elements in the bin + */ + std::vector> item_bins_; + + /** + Item-size chunks of the label (decomposed into field elements) for each bin in the + BinBundle. The dimensions are, in order: + - Components of the label + - Bins in the BinBundle + - Field elements in the bin + */ + std::vector>> label_bins_; + + /** + Each bin in the BinBundle has a CuckooFilter that helps quickly determine whether a + field element is contained. + */ + std::vector filters_; + + /** + Indicates whether SEAL plaintexts are compressed in memory. + */ + bool compressed_; + + /** + Indicates whether the BinBundle has been stripped of all information not needed for + serving a query. + */ + bool stripped_; + + /** + The size of the labels in multiples of item length. + */ + std::size_t label_size_; + + /** + Maximum size of the bins. + */ + std::size_t max_bin_size_; + + /** + Holds the Paterson-Stockmeyer low-degree for this BinBundle. + */ + std::size_t ps_low_degree_; + + /** + The number of bins in the BinBundle. + */ + std::size_t num_bins_; + + /** + A cache of all the computations we can do on the bins. This is empty by default. + */ + BinBundleCache cache_; + + /** + Returns the modulus that defines the finite field that we're working in + */ + const seal::Modulus& field_mod() const; + + /** + Computes and caches the appropriate polynomials of each bin. For unlabeled PSI, this is + just the "matching" polynomial. For labeled PSI, this is the "matching" polynomial and + the Newton interpolation polynomial. Resulting values are stored in cache_. + */ + void regen_polyns(); + + /** + Batches this BinBundle's polynomials into SEAL Plaintexts. Resulting values are stored + in cache_. + */ + void regen_plaintexts(); + +public: + BinBundle(const apsi::CryptoContext& crypto_context, std::size_t label_size, + std::size_t max_bin_size, std::size_t ps_low_degree, std::size_t num_bins, bool compressed, + bool stripped); + + BinBundle(const BinBundle& copy) = delete; + + BinBundle(BinBundle&& source) = default; + + BinBundle& operator=(const BinBundle& assign) = delete; + + BinBundle& operator=(BinBundle&& assign) = default; + + /** + Inserts item-label pairs into sequential bins, beginning at start_bin_idx. If dry_run is + specified, no change is made to the BinBundle. On success, returns the size of the + largest bin bins in the modified range, after insertion has taken place. On failed + insertion, returns -1. On failure, no modification is made to the BinBundle. + */ + template + std::int32_t multi_insert( + const std::vector& item_labels, std::size_t start_bin_idx, bool dry_run); + + /** + Does a dry-run insertion of item-label pairs into sequential bins, beginning at + start_bin_idx. This does not mutate the BinBundle. On success, returns the size of the + largest bin bins in the modified range, after insertion has taken place. On failed + insertion, returns -1. + */ + template + std::int32_t multi_insert_dry_run(const std::vector& item_labels, std::size_t start_bin_idx) + { + return multi_insert(item_labels, start_bin_idx, true); + } + + /** + Inserts item-label pairs into sequential bins, beginning at start_bin_idx. On success, + returns the size of the largest bin bins in the modified range, after insertion has + taken place. On failed insertion, returns -1. On failure, no modification is made to the + BinBundle. + */ + template + std::int32_t multi_insert_for_real(const std::vector& item_labels, std::size_t start_bin_idx) + { + return multi_insert(item_labels, start_bin_idx, false); + } + + /** + Attempts to overwrite the stored items' labels with the given labels. Returns true iff + it found a contiguous sequence of given items. If no such sequence was found, this + BinBundle is not mutated. This function can be called on a + BinBundle> but it won't do anything except force the cache to get + recomputed, so don't bother. The labeled case has T equal to std::pair>. + */ + template + bool try_multi_overwrite(const std::vector& item_labels, std::size_t start_bin_idx); + + /** + Attempts to remove the stored items and labels. Returns true iff it found a contiguous + sequence of given items and the data was successfully removed. If no such sequence was + found, this BinBundle is not mutated. + */ + bool try_multi_remove(const std::vector& items, std::size_t start_bin_idx); + + /** + Sets the given labels to the set of labels associated with the sequence of items in this + BinBundle, starting at start_idx. If any item is not present in its respective bin, this + returns false and clears the given labels vector. Returns true on success. + */ + bool try_get_multi_label(const std::vector& items, std::size_t start_bin_idx, + std::vector& labels) const; + + /** + Clears the contents of the BinBundle and wipes out the cache. + */ + void clear(bool stripped = false); + + /** + Wipes out the cache of the BinBundle + */ + void clear_cache(); + + /** + Returns whether this BinBundle's cache needs to be recomputed + */ + bool cache_invalid() const noexcept { return cache_invalid_; } + + /** + Gets a constant reference to this BinBundle's cache. This will throw an exception if the + cache is invalid. Check the cache before you wreck the cache. + */ + const BinBundleCache& get_cache() const; + + /** + Generates and caches all the polynomials and plaintexts that this BinBundle requires + */ + void regen_cache(); + + /** + Returns a constant reference to the items in this BinBundle. + */ + const std::vector>& get_item_bins() const noexcept { return item_bins_; } + + /** + Returns the size of the label in multiples of the item size. + */ + std::size_t get_label_size() const noexcept { return label_size_; } + + /** + Returns the number of bins. + */ + std::size_t get_num_bins() const noexcept { return num_bins_; } + + /** + Returns a constant reference to the label parts in this BinBundle. + */ + const std::vector>>& get_label_bins() const noexcept + { + return label_bins_; + } + + /** + Returns whether this BinBundle is empty. + */ + bool empty() const; + + /** + Indicates whether the BinBundle has been stripped of all information not needed for + serving a query. + */ + bool is_stripped() const { return stripped_; } + + /** + Strips the BinBundle of all information not needed for serving a query. + */ + void strip(); + + ppctars::BinBundle saveToTarsBinBundle() const; + + static BinBundle loadFromTarsBinBundle( + const apsi::CryptoContext& _cryptoContext, const ppctars::BinBundle& _tarsBinBundle); +}; + +} // namespace ppc::psi \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-psi/src/labeled-psi/core/LabeledPSIParams.h b/cpp/wedpr-computing/ppc-psi/src/labeled-psi/core/LabeledPSIParams.h new file mode 100644 index 00000000..70b21e82 --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/labeled-psi/core/LabeledPSIParams.h @@ -0,0 +1,169 @@ +/** + * Copyright (C) 2022 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. + * + * @reference https://github.com/secretflow/spu + * @license Apache license + * + * @file LabeledPSIParams.h + * @author: shawnhe + * @date 2022-11-14 + * + */ + +#pragma once + +#include "LabeledPSI.h" +#include "ppc-psi/src/labeled-psi/Common.h" + +#include +#include +#include +#include +#include + +namespace ppc::psi +{ +struct BaseParams +{ + size_t maxItemsPerBin; + size_t polyModulusDegree; + // plain_modulus or plain_modulus_bits + size_t plainModulus = 0; + size_t plainModulusBits = 0; + std::vector coeffModulusBits; + + + size_t getPlainModulusBits() + { + // plain_modulus_bits + if (plainModulusBits > 0) + { + return plainModulusBits; + } + else if (plainModulus > 0) + { + // get plain_modulus_bits by plain_modulus + return std::floor(std::log2(plainModulus)); + } + return 0; + } +}; + +inline size_t getHashTruncateSize(size_t _senderSize, size_t _statsSecParams = 40) +{ + // reference: Fast Private Set Intersection from Homomorphic Encryption, section 4.2 + // url: https://eprint.iacr.org/2017/299 + size_t tSize = + std::ceil(std::log2(_senderSize)) + std::ceil(std::log2(MAX_QUERY_SIZE)) + _statsSecParams; + return std::max(static_cast(80), tSize); +} + +inline apsi::PSIParams getPsiParams(size_t _senderSize) +{ + // reference: microsoft APSI example parameter sets + // url: https://github.com/microsoft/APSI/tree/main/parameters + std::vector kBaseParams = { + {42, 2048, 65537, 0, {48}}, // 0 100k-1-16 + {228, 8192, 65537, 0, {56, 48, 48}}, // 1 1M-1-32 + {782, 8192, 0, 21, {56, 56, 56, 50}}, // 2 16M-1-32 + {8100, 8192, 0, 22, {56, 56, 56, 32}}, // 3 256M-1 + }; + + BaseParams baseParams; + if (_senderSize <= (1 << 18)) + { + baseParams = kBaseParams[0]; + } + else if (_senderSize <= (1 << 20)) + { + baseParams = kBaseParams[1]; + } + else if (_senderSize <= (1 << 24)) + { + baseParams = kBaseParams[2]; + } + else + { + baseParams = kBaseParams[3]; + } + + // item param + apsi::PSIParams::ItemParams itemParams{}; + size_t hash_size = getHashTruncateSize(_senderSize); + itemParams.felts_per_item = + std::ceil(static_cast(hash_size) / (baseParams.getPlainModulusBits() - 1)); + + // table param + apsi::PSIParams::TableParams tableParams{}; + tableParams.max_items_per_bin = baseParams.maxItemsPerBin; + tableParams.hash_func_count = 1; + + size_t polyItemCount = baseParams.polyModulusDegree / itemParams.felts_per_item; + tableParams.table_size = polyItemCount; + + size_t cuckooTableSize = std::ceil(4 * MAX_QUERY_SIZE); + while (tableParams.table_size < cuckooTableSize) + { + tableParams.table_size += polyItemCount; + } + + // query param + apsi::PSIParams::QueryParams queryParams; + if (tableParams.max_items_per_bin == 42) + { + queryParams.ps_low_degree = 0; + queryParams.query_powers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, + 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42}; + } + else if (tableParams.max_items_per_bin == 228) + { + queryParams.ps_low_degree = 0; + queryParams.query_powers = {1, 3, 8, 19, 33, 39, 92, 102}; + } + else if (tableParams.max_items_per_bin == 782) + { + queryParams.ps_low_degree = 26; + queryParams.query_powers = {1, 5, 8, 27, 135}; + } + else + { + queryParams.ps_low_degree = 310; + queryParams.query_powers = {1, 4, 10, 11, 28, 33, 78, 118, 143, 311, 1555}; + } + + // seal param + apsi::PSIParams::SEALParams apsiSealParams; + apsiSealParams.set_poly_modulus_degree(baseParams.polyModulusDegree); + + if (baseParams.plainModulusBits > 0) + { + apsiSealParams.set_plain_modulus(seal::PlainModulus::Batching( + baseParams.polyModulusDegree, baseParams.plainModulusBits)); + } + else + { + apsiSealParams.set_plain_modulus(baseParams.plainModulus); + } + + apsiSealParams.set_coeff_modulus( + seal::CoeffModulus::Create(baseParams.polyModulusDegree, baseParams.coeffModulusBits)); + + apsi::PSIParams psi_params(itemParams, tableParams, queryParams, apsiSealParams); + + return psi_params; +} + +} // namespace ppc::psi \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-psi/src/labeled-psi/core/LabeledPSIReceiver.cpp b/cpp/wedpr-computing/ppc-psi/src/labeled-psi/core/LabeledPSIReceiver.cpp new file mode 100644 index 00000000..ec399d4e --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/labeled-psi/core/LabeledPSIReceiver.cpp @@ -0,0 +1,657 @@ +/** + * Copyright (C) 2022 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 LabeledPSIReceiver.cpp + * @author: shawnhe + * @date 2022-11-3 + */ + +#include +#include +#include +#include +#include + +#include "LabeledPSI.h" +#include "LabeledPSIReceiver.h" +#include "ResultPackage.h" +#include "bcos-utilities/DataConvertUtility.h" +#include "ppc-psi/src/labeled-psi/Common.h" +#include "ppc-psi/src/labeled-psi/protocol/LabeledPSIResult.h" +#include "wedpr-protocol/tars/TarsSerialize.h" + +using namespace ppc::psi; +using namespace ppc::protocol; +using namespace ppc::front; +using namespace ppc::crypto; +using namespace ppc::tools; + +LabeledPSIReceiver::LabeledPSIReceiver( + LabeledPSIConfig::Ptr _config, TaskState::Ptr _taskState, OprfClient::Ptr _oprfClient) + : m_config(std::move(_config)), + m_taskState(std::move(_taskState)), + m_oprfClient(std::move(_oprfClient)) +{ + m_taskID = m_taskState->task()->id(); + auto originData = m_taskState->task()->selfParty()->dataResource()->rawData(); + if (originData.empty() || originData[0].size() > MAX_QUERY_SIZE) + { + BOOST_THROW_EXCEPTION( + TooManyItemsException() << bcos::errinfo_comment( + "Items count per query should be (0, " + std::to_string(MAX_QUERY_SIZE) + "]")); + } + m_items = std::move(originData[0]); +} + +void LabeledPSIReceiver::asyncRunTask() +{ + LABELED_PSI_LOG(INFO) << LOG_DESC("asyncRunTask as receiver") << LOG_KV("taskID", m_taskID); + m_config->threadPool()->enqueue([self = weak_from_this()]() { + auto receiver = self.lock(); + if (!receiver) + { + return; + } + try + { + receiver->runReceiver(); + } + catch (const std::exception& e) + { + receiver->onReceiverException("runTask", e); + } + }); +} + +void LabeledPSIReceiver::handlePsiParams(const front::PPCMessageFace::Ptr& _message) +{ + auto taskID = _message->taskID(); + LABELED_PSI_LOG(INFO) << LOG_BADGE("handlePsiParams") << LOG_KV("taskID", taskID); + + try + { + ppctars::PsiParams tarsParams; + ppctars::serialize::decode(*_message->data(), tarsParams); + m_psiParams = std::make_shared(toPSIParams(tarsParams)); + m_responseCount = tarsParams.binBundleCount; + + m_progress = std::make_shared(m_config->threadPool()); + m_progress->reset(m_responseCount, [self = weak_from_this()]() { + auto receiver = self.lock(); + if (!receiver) + { + return; + } + receiver->onReceiverTaskDone(nullptr); + }); + + // initialize receiver by params + initializeByParams(); + + // do next step + runOprfAsClient(); + } + catch (const std::exception& e) + { + onReceiverException("handlePsiParams", e); + } +} + +void LabeledPSIReceiver::handleEvaluatedItems(const front::PPCMessageFace::Ptr& _message) +{ + auto taskID = _message->taskID(); + LABELED_PSI_LOG(INFO) << LOG_BADGE("handleEvaluatedItems") << LOG_KV("taskID", taskID); + + try + { + ppctars::OprfData evaluatedData; + ppctars::serialize::decode(*_message->data(), evaluatedData); + + // finish oprf + doOprfFinalize(evaluatedData.data); + + // do next step + requestQuery(); + } + catch (const std::exception& e) + { + onReceiverException("handleEvaluatedItems", e); + } +} + +void LabeledPSIReceiver::handleOneResponse(const front::PPCMessageFace::Ptr& _message) +{ + auto taskID = _message->taskID(); + LABELED_PSI_LOG(INFO) << LOG_BADGE("handleOneResponse") << LOG_KV("taskID", taskID); + + try + { + ppctars::QueryResponse queryResponse; + ppctars::serialize::decode(*_message->data(), queryResponse); + + // handle response + decryptResults(queryResponse); + + m_progress->mark(_message->seq()); + } + catch (const std::exception& e) + { + onReceiverException("handleOneResponse", e); + } +} + +void LabeledPSIReceiver::runReceiver() +{ + LABELED_PSI_LOG(INFO) << LOG_DESC("request psi params from sender") + << LOG_KV("taskID", m_taskID) << LOG_KV("itemsSize", m_items.size()); + + auto message = m_config->ppcMsgFactory()->buildPPCMessage(uint8_t(protocol::TaskType::PSI), + uint8_t(protocol::TaskAlgorithmType::LABELED_PSI_2PC), m_taskID, + std::make_shared()); + message->setMessageType(uint8_t(LabeledPSIMessageType::PARAMS_REQUEST)); + + // send request + m_config->front()->asyncSendMessage( + m_taskState->peerID(), message, m_config->networkTimeout(), + [self = weak_from_this()](const bcos::Error::Ptr& _error) { + auto receiver = self.lock(); + if (!receiver) + { + return; + } + if (_error && _error->errorCode()) + { + receiver->onReceiverTaskDone(_error); + } + }, + nullptr); +} + +void LabeledPSIReceiver::initializeByParams() +{ + LABELED_PSI_LOG(INFO) << LOG_DESC("receiver do initialize") << LOG_KV("taskID", m_taskID) + << LOG_KV("psiParams", m_psiParams->to_string()); + + // initialize the CryptoContext with a new SEALContext + m_cryptoContext = apsi::CryptoContext(*m_psiParams); + + // create new keys + generateKeys(); + + // set up the PowersDag + computePowersDag((*m_psiParams).query_params().query_powers); +} + +void LabeledPSIReceiver::generateKeys() +{ + LABELED_PSI_LOG(INFO) << LOG_DESC("receiver generateKeys") << LOG_KV("taskID", m_taskID); + + // generate new keys + seal::KeyGenerator generator(*getSealContext()); + + // set the symmetric key, encryptor, and decryptor + m_cryptoContext.set_secret(generator.secret_key()); + + // create Serializable and move to m_relinKeys for storage + m_relinKeys.clear(); + if (getSealContext()->using_keyswitching()) + { + seal::Serializable relinKeys(generator.create_relin_keys()); + m_relinKeys.set(std::move(relinKeys)); + } +} + +std::uint32_t LabeledPSIReceiver::computePowersDag(const std::set& _sourcePowers) +{ + LABELED_PSI_LOG(INFO) << LOG_DESC("receiver do compute PowersDag") + << LOG_KV("taskID", m_taskID); + // first compute the target powers + std::set targetPowers = apsi::util::create_powers_set( + m_psiParams->query_params().ps_low_degree, m_psiParams->table_params().max_items_per_bin); + + // configure the PowersDag + m_powersDag.configure(_sourcePowers, targetPowers); + + // check that the PowersDag is valid + if (!m_powersDag.is_configured()) + { + LABELED_PSI_LOG(ERROR) << LOG_DESC("failed to configure PowersDag") + << LOG_KV("sourcePowers", apsi::util::to_string(_sourcePowers)) + << LOG_KV("targetPowers", apsi::util::to_string(targetPowers)); + + BOOST_THROW_EXCEPTION( + ConfigPowersDagException() << bcos::errinfo_comment("failed to configure PowersDag")); + } + + LABELED_PSI_LOG(INFO) << LOG_DESC("finish computing PowersDag") + << LOG_KV("PowersDagDepth", m_powersDag.depth()); + return m_powersDag.depth(); +} + +void LabeledPSIReceiver::runOprfAsClient() +{ + LABELED_PSI_LOG(INFO) << LOG_DESC("run oprf as client with sender") + << LOG_KV("taskID", m_taskID) << LOG_KV("itemsSize", m_items.size()); + + // blind items + ppctars::OprfData oprfData; + oprfData.data = m_oprfClient->blind(m_items); + + auto blindedMessage = m_config->ppcMsgFactory()->buildPPCMessage(uint8_t(TaskType::PSI), + uint8_t(TaskAlgorithmType::LABELED_PSI_2PC), m_taskID, std::make_shared()); + blindedMessage->setMessageType(uint8_t(LabeledPSIMessageType::OPRF_BLINDED_ITEMS)); + ppctars::serialize::encode(oprfData, *blindedMessage->data()); + + // send blinded items to sender + m_config->front()->asyncSendMessage( + m_taskState->peerID(), blindedMessage, m_config->networkTimeout(), + [self = weak_from_this()](const bcos::Error::Ptr& _error) { + auto receiver = self.lock(); + if (!receiver) + { + return; + } + if (_error && _error->errorCode()) + { + receiver->onReceiverTaskDone(_error); + } + }, + nullptr); +} + +void LabeledPSIReceiver::doOprfFinalize(const std::vector& _evaluatedItems) +{ + LABELED_PSI_LOG(INFO) << LOG_DESC("do oprf finalize") << LOG_KV("taskID", m_taskID) + << LOG_KV("itemsSize", m_items.size()); + + auto output = m_oprfClient->finalize(m_items, _evaluatedItems); + + m_oprfOutputs.first.resize(m_items.size()); + m_oprfOutputs.second.resize(m_items.size()); + + auto hashLen = m_oprfOutputs.first[0].value().size(); + auto keyLen = m_oprfOutputs.second[0].size(); + + for (uint32_t idx = 0; idx < m_items.size(); ++idx) + { + std::memcpy(m_oprfOutputs.first[idx].value().data(), output[idx].data(), hashLen); + std::memcpy(m_oprfOutputs.second[idx].data(), output[idx].data() + hashLen, keyLen); + } +} + +void LabeledPSIReceiver::prepareQueryData() +{ + LABELED_PSI_LOG(INFO) << LOG_DESC("prepare query data") << LOG_KV("taskID", m_taskID) + << LOG_KV("itemsSize", m_items.size()); + doCuckooHashing(); + + computeEncryptedPower(); +} + +void LabeledPSIReceiver::doCuckooHashing() +{ + kuku::KukuTable cuckoo(m_psiParams->table_params().table_size, // Size of the hash table + 0, // Not using a stash + m_psiParams->table_params().hash_func_count, // Number of hash functions + {0, 0}, // Hardcoded { 0, 0 } as the seed + CUCKOO_TABLE_INSERT_ATTEMPTS, // The number of insertion attempts + {0, 0}); + + LABELED_PSI_LOG(INFO) << LOG_BADGE("runCuckooHash") << LOG_KV("taskID", m_taskID) + << LOG_KV("tableSize", cuckoo.table_size()); + + // Hash the data into a cuckoo hash table + for (size_t idx = 0; idx < m_oprfOutputs.first.size(); ++idx) + { + const auto& item = m_oprfOutputs.first[idx]; + if (!cuckoo.insert(item.get_as().front())) + { + // Insertion can fail for two reasons: + // + // (1) The item was already in the table, in which case the + // "leftover item" is empty; (2) Cuckoo hashing failed due to too + // small table or too few hash functions. + // + // In case (1) simply move on to the next item and log this issue. Case + // (2) is a critical issue so throw an exception. + if (cuckoo.is_empty_item(cuckoo.leftover_item())) + { + LABELED_PSI_LOG(DEBUG) << LOG_DESC("skipping repeated insertion of items") + << LOG_KV("index", idx) << LOG_KV("item", item.to_string()); + } + else + { + LABELED_PSI_LOG(ERROR) + << LOG_DESC("failed to insert item into cuckoo table") << LOG_KV("index", idx) + << LOG_KV("item", item.to_string()) << LOG_KV("fill-rate", cuckoo.fill_rate()); + + onReceiverTaskDone( + std::make_shared((int)LabeledPSIRetCode::CUCKOO_HASH_ERROR, + "failed to insert item into cuckoo table, index: " + std::to_string(idx))); + } + } + } + LABELED_PSI_LOG(INFO) << LOG_BADGE("finishCuckooHash") << LOG_KV("taskID", m_taskID) + << LOG_KV("tableSize", cuckoo.table_size()) + << LOG_KV("fill-rate", cuckoo.fill_rate()); + + // once the table is filled, fill the table_idx_to_item_idx map + m_itt.item_count_ = m_oprfOutputs.first.size(); + for (size_t idx = 0; idx < m_oprfOutputs.first.size(); ++idx) + { + auto item_loc = cuckoo.query(m_oprfOutputs.first[idx].get_as().front()); + m_itt.table_idx_to_item_idx_[item_loc.location()] = idx; + } + + m_kukuData = cuckoo.table(); + + // clear hashed items + std::vector().swap(m_oprfOutputs.first); + MallocExtension::instance()->ReleaseFreeMemory(); +} + +void LabeledPSIReceiver::computeEncryptedPower() +{ + LABELED_PSI_LOG(INFO) << LOG_DESC("compute encrypted powers for items") + << LOG_KV("taskID", m_taskID) << LOG_KV("itemsSize", m_items.size()); + + // set up unencrypted query data + std::vector plainPowers; + for (uint32_t idx = 0; idx < m_psiParams->bundle_idx_count(); ++idx) + { + // first, find the items for this bundle index + gsl::span bundleItems( + m_kukuData.data() + idx * m_psiParams->items_per_bundle(), + m_psiParams->items_per_bundle()); + + std::vector algItems; + for (auto& item : bundleItems) + { + // now set up a BitstringView to this item + gsl::span itemBytes( + reinterpret_cast(item.data()), sizeof(item)); + apsi::BitstringView itemBits(itemBytes, m_psiParams->item_bit_count()); + + // create an algebraic item by breaking up the item into modulo plain_modulus parts + std::vector algItem = apsi::util::bits_to_field_elts( + itemBits, m_psiParams->seal_params().plain_modulus()); + copy(algItem.cbegin(), algItem.cend(), back_inserter(algItems)); + } + + // now that we have the algebraized items for this bundle index, we create a PlaintextPowers + // object that computes all necessary powers of the algebraized items. + plainPowers.emplace_back(std::move(algItems), *m_psiParams, m_powersDag); + } + + // the very last thing to do is encrypt the plainPowers and consolidate the matching + // powers for different bundle indices + LABELED_PSI_LOG(INFO) << LOG_DESC("start encrypt powers") << LOG_KV("taskID", m_taskID) + << LOG_KV("bundleCount", m_psiParams->bundle_idx_count()); + + for (uint32_t idx = 0; idx < m_psiParams->bundle_idx_count(); ++idx) + { + // encrypt the data for this power + auto encryptedPowers(plainPowers[idx].encrypt(m_cryptoContext)); + + // move the encrypted data to encrypted_powers + for (auto& ep : encryptedPowers) + { + m_encryptedPowers[ep.first].emplace_back(std::move(ep.second)); + } + } + + // clear kuku items + std::vector().swap(m_kukuData); + MallocExtension::instance()->ReleaseFreeMemory(); +} + +void LabeledPSIReceiver::requestQuery() +{ + prepareQueryData(); + + // construct tars struct for request + std::vector keys; + if (getSealContext()->using_keyswitching()) + { + keys.resize(m_relinKeys.save_size(m_comprMode)); + } + m_relinKeys.save(keys, m_comprMode); + + ppctars::QueryRequest queryRequest; + queryRequest.relinKeys = std::move(keys); + + for (const auto& ep : m_encryptedPowers) + { + ppctars::EncryptedPowers tarsEps; + tarsEps.power = ep.first; + for (const auto& ct : ep.second) + { + std::vector cipher; + cipher.resize(ct.save_size(m_comprMode)); + auto size = ct.save(cipher, m_comprMode); + cipher.resize(size); + tarsEps.ciphertexts.emplace_back(std::move(cipher)); + } + queryRequest.encryptedPowers.emplace_back(std::move(tarsEps)); + } + + auto queryMessage = m_config->ppcMsgFactory()->buildPPCMessage(uint8_t(TaskType::PSI), + uint8_t(TaskAlgorithmType::LABELED_PSI_2PC), m_taskID, std::make_shared()); + queryMessage->setMessageType(uint8_t(LabeledPSIMessageType::QUERY)); + ppctars::serialize::encode(queryRequest, *queryMessage->data()); + + LABELED_PSI_LOG(INFO) << LOG_DESC("send query request") << LOG_KV("taskID", m_taskID) + << LOG_KV("dataSize", queryMessage->data()->size()); + + // send request + m_config->front()->asyncSendMessage( + m_taskState->peerID(), queryMessage, m_config->networkTimeout(), + [self = weak_from_this()](const bcos::Error::Ptr& _error) { + auto receiver = self.lock(); + if (!receiver) + { + return; + } + if (_error && _error->errorCode()) + { + receiver->onReceiverTaskDone(_error); + } + }, + nullptr); + + // clear encrypted powers + std::unordered_map>>().swap( + m_encryptedPowers); + MallocExtension::instance()->ReleaseFreeMemory(); + + m_results.resize(m_items.size()); +} + +void LabeledPSIReceiver::decryptResults(const ppctars::QueryResponse& _queryResult) +{ + size_t bundleIdx = _queryResult.bundleIdx; + + LABELED_PSI_LOG(DEBUG) << LOG_DESC("decryptResults") << LOG_KV("taskID", m_taskID) + << LOG_KV("index", bundleIdx); + + // construct ResultPackage + ResultPackage resultPackage; + resultPackage.bundleIdx = bundleIdx; + resultPackage.labelByteCount = _queryResult.labelByteCount; + resultPackage.nonceByteCount = _queryResult.nonceByteCount; + + gsl::span cipherSpan( + reinterpret_cast(_queryResult.ciphertext.data()), + _queryResult.ciphertext.size()); + resultPackage.psiCipherResult.load(getSealContext(), cipherSpan); + + for (const auto& labelResult : _queryResult.labelResults) + { + gsl::span labelSpan( + reinterpret_cast(labelResult.data()), labelResult.size()); + apsi::SEALObject cipher; + cipher.load(getSealContext(), labelSpan); + resultPackage.labelCipherResults.emplace_back(std::move(cipher)); + } + + // decrypt and decode the result; the result vector will have full batch size + PlainResultPackage plainRp = resultPackage.extract(m_cryptoContext); + + // check if we are supposed to have label data present but don't have for some reason + auto labelByteCount = seal::util::safe_cast(plainRp.labelByteCount); + if (labelByteCount && plainRp.labelResults.empty()) + { + onReceiverTaskDone(std::make_shared( + (int)LabeledPSIRetCode::MISSING_LABEL_DATA, "missing label data")); + return; + } + + // read the nonce byte count and compute the effective label byte count; set the nonce byte + // count to zero if no label is expected anyway + size_t nonceByteCount = + labelByteCount ? seal::util::safe_cast(plainRp.nonceByteCount) : 0; + size_t effectiveLabelByteCount = seal::util::add_safe(nonceByteCount, labelByteCount); + + // how much label data did we actually receive? + size_t receivedLabelBitCount = seal::util::mul_safe( + seal::util::safe_cast(m_psiParams->item_bit_count()), plainRp.labelResults.size()); + + // compute the received label byte count and check that it is not less than what was expected + size_t receivedLabelByteCount = receivedLabelBitCount / 8; + + if (receivedLabelByteCount < nonceByteCount) + { + onReceiverTaskDone(std::make_shared((int)LabeledPSIRetCode::LACK_LABEL_DATA, + "nonce bytes, expected: " + std::to_string(nonceByteCount) + + ", received: " + std::to_string(receivedLabelByteCount))); + return; + } + else if (receivedLabelByteCount < effectiveLabelByteCount) + { + onReceiverTaskDone(std::make_shared((int)LabeledPSIRetCode::LACK_LABEL_DATA, + "label bytes, expected: " + std::to_string(labelByteCount) + + ", received: " + std::to_string(receivedLabelByteCount - nonceByteCount))); + return; + } + + auto itemsPerBundle = seal::util::safe_cast(m_psiParams->items_per_bundle()); + size_t bundleStart = + seal::util::mul_safe(seal::util::safe_cast(bundleIdx), itemsPerBundle); + + LABELED_PSI_LOG(DEBUG) << LOG_DESC("decryptResults") << LOG_KV("taskID", m_taskID) + << LOG_KV("bundleStart", bundleStart) << LOG_KV("bundleIdx", bundleIdx); + + auto feltsPerItem = seal::util::safe_cast(m_psiParams->item_params().felts_per_item); + seal::util::StrideIter plainRpIter(plainRp.psiResult.data(), feltsPerItem); + + seal::util::seal_for_each_n( + seal::util::iter(plainRpIter, size_t(0)), itemsPerBundle, [&](auto&& I) { + // find feltsPerItem consecutive zeros + bool match = hasNZeros(std::get<0>(I).ptr(), feltsPerItem); + if (!match) + { + return; + } + + // compute the cuckoo table index for this item. then find the corresponding index + // in the input items vector, so we know where to place the result. + size_t tableIdx = seal::util::add_safe(size_t(std::get<1>(I)), bundleStart); + auto itemIdx = m_itt.find_item_idx(tableIdx); + + if (match) + { + LABELED_PSI_LOG(DEBUG) << LOG_KV("match", match) << LOG_KV("tableIdx", tableIdx) + << LOG_KV("itemIdx", itemIdx); + } + + // ff this tableIdx doesn't match any itemIdx, ignore the result no matter what it is + if (itemIdx == m_itt.item_count()) + { + return; + } + + apsi::Label label; + if (labelByteCount) + { + // collect the entire label into this vector + apsi::util::AlgLabel algLabel; + + size_t labelOffset = seal::util::mul_safe(size_t(std::get<1>(I)), feltsPerItem); + for (auto& labelResult : plainRp.labelResults) + { + gsl::span labelSpan( + labelResult.data() + labelOffset, feltsPerItem); + std::copy(labelSpan.begin(), labelSpan.end(), back_inserter(algLabel)); + } + + // create the label + apsi::EncryptedLabel encryptedLabel = apsi::util::dealgebraize_label( + algLabel, receivedLabelBitCount, m_psiParams->seal_params().plain_modulus()); + + // resize down to the effective byte count + encryptedLabel.resize(effectiveLabelByteCount); + + // decrypt the label + label = apsi::util::decrypt_label( + encryptedLabel, m_oprfOutputs.second[itemIdx], nonceByteCount); + } + + m_results[itemIdx] = + std::make_pair(m_items[itemIdx], std::string(label.begin(), label.end())); + }); +} + +void LabeledPSIReceiver::onReceiverException(const std::string& _module, const std::exception& _e) +{ + LABELED_PSI_LOG(ERROR) << LOG_BADGE("onReceiverException") << LOG_KV("taskID", m_taskID) + << LOG_KV("module", _module) + << LOG_KV("error", boost::diagnostic_information(_e)); + auto error = std::make_shared((int)LabeledPSIRetCode::ON_EXCEPTION, + "exception caught while do " + _module + ", message: " + boost::diagnostic_information(_e)); + onReceiverTaskDone(error); +} + +void LabeledPSIReceiver::onReceiverTaskDone(bcos::Error::Ptr _error) +{ + if (m_taskState->taskDone()) + { + return; + } + LABELED_PSI_LOG(INFO) << LOG_BADGE("onReceiverDone") << LOG_KV("taskID", m_taskID) + << LOG_KV("success", _error == nullptr); + auto result = std::make_shared(m_taskID); + if (_error) + { + result->setError(std::move(_error)); + } + else + { + std::vector> outputs(2); + for (auto& kv : m_results) + { + if (!kv.first.empty()) + { + outputs[0].emplace_back(kv.first); + std::string label = kv.second; + label.erase( + std::remove_if(label.begin(), label.end(), [](char ch) { return ch == '\0'; }), + label.end()); + outputs[1].emplace_back(label); + } + } + result->setOutputs(std::move(outputs)); + } + m_taskState->onTaskFinished(result, true); +} \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-psi/src/labeled-psi/core/LabeledPSIReceiver.h b/cpp/wedpr-computing/ppc-psi/src/labeled-psi/core/LabeledPSIReceiver.h new file mode 100644 index 00000000..cfb54d5d --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/labeled-psi/core/LabeledPSIReceiver.h @@ -0,0 +1,143 @@ +/** + * Copyright (C) 2022 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 LabeledPSIReceiver.h + * @author: shawnhe + * @date 2022-11-3 + */ + +#pragma once +#include "../../psi-framework/TaskState.h" +#include "ppc-framework/crypto/Oprf.h" +#include "ppc-framework/protocol/Task.h" +#include "ppc-framework/task/TaskFrameworkInterface.h" +#include "ppc-front/ppc-front/PPCChannel.h" +#include "ppc-psi/src/labeled-psi/LabeledPSIConfig.h" +#include "ppc-psi/src/labeled-psi/protocol/Protocol.h" +#include "ppc-tools/src/common/Progress.h" +#include "protocol/src/PPCMessage.h" + +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace ppc::psi +{ +class LabeledPSIReceiver : public std::enable_shared_from_this +{ +public: + using Ptr = std::shared_ptr; + + // construct after calling asyncRequestParams + LabeledPSIReceiver( + LabeledPSIConfig::Ptr _config, TaskState::Ptr _taskState, crypto::OprfClient::Ptr _client); + + ~LabeledPSIReceiver() + { + m_powersDag.reset(); + std::vector().swap(m_items); + std::pair, std::vector>().swap(m_oprfOutputs); + std::vector().swap(m_kukuData); + std::unordered_map>>().swap( + m_encryptedPowers); + std::vector>().swap(m_results); + // release the memory to os + MallocExtension::instance()->ReleaseFreeMemory(); + LABELED_PSI_LOG(INFO) << LOG_DESC("the sender destroyed") << LOG_KV("taskID", m_taskID); + } + + void asyncRunTask(); + + // init receiver by psi params + void handlePsiParams(const front::PPCMessageFace::Ptr& _message); + + // finish oprf and run query + void handleEvaluatedItems(const front::PPCMessageFace::Ptr& _message); + + // handle one response package + void handleOneResponse(const front::PPCMessageFace::Ptr& _message); + + std::shared_ptr getSealContext() const + { + return m_cryptoContext.seal_context(); + } + + const std::string& taskID() const { return m_taskID; } + +protected: + void runReceiver(); + + // init receiver + void initializeByParams(); + + // generates a new set of keys to use for queries + void generateKeys(); + + /** + *Computes the PowersDag. The function returns the depth of the + *PowersDag. In some cases the receiver may want to ensure that the depth of + *the powers computation will be as expected (PowersDag::depth), and + *otherwise attempt to reconfigure the PowersDag. + */ + std::uint32_t computePowersDag(const std::set& _sourcePowers); + + // run oprf as receiver + void runOprfAsClient(); + void doOprfFinalize(const std::vector& _evaluatedItems); + + // process oprf results and send query quest + void requestQuery(); + void prepareQueryData(); + void doCuckooHashing(); + void computeEncryptedPower(); + + // decrypt psi results and labels, handled by per bundle + void decryptResults(const ppctars::QueryResponse& _queryResponse); + + void onReceiverException(const std::string& _module, const std::exception& e); + void onReceiverTaskDone(bcos::Error::Ptr _error); + +private: + LabeledPSIConfig::Ptr m_config; + TaskState::Ptr m_taskState; + crypto::OprfClient::Ptr m_oprfClient; + + std::string m_taskID; + + std::shared_ptr m_psiParams; + + apsi::CryptoContext m_cryptoContext; + apsi::PowersDag m_powersDag; + apsi::SEALObject m_relinKeys; + seal::compr_mode_type m_comprMode{seal::Serialization::compr_mode_default}; + + std::vector m_items; + std::pair, std::vector> m_oprfOutputs; + apsi::receiver::IndexTranslationTable m_itt; + std::vector m_kukuData; + std::unordered_map>> m_encryptedPowers; + + uint32_t m_responseCount{0}; + std::vector> m_results; + + tools::Progress::Ptr m_progress; +}; +} // namespace ppc::psi \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-psi/src/labeled-psi/core/LabeledPSISender.cpp b/cpp/wedpr-computing/ppc-psi/src/labeled-psi/core/LabeledPSISender.cpp new file mode 100644 index 00000000..dcfbe99c --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/labeled-psi/core/LabeledPSISender.cpp @@ -0,0 +1,461 @@ +/** + * Copyright (C) 2022 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 LabeledPSISender.cpp + * @author: shawnhe + * @date 2022-11-6 + */ + + +#include +#include + +#include "LabeledPSIParams.h" +#include "LabeledPSISender.h" +#include "QueryPackage.h" +#include "ppc-tools/src/common/TransTools.h" +#include "wedpr-protocol/tars/TarsSerialize.h" + +using namespace ppc::psi; +using namespace ppc::protocol; +using namespace ppc::front; +using namespace ppc::tools; +using namespace ppc::crypto; + +LabeledPSISender::LabeledPSISender(LabeledPSIConfig::Ptr _config, + std::function _taskEndTrigger) + : m_config(std::move(_config)), m_taskEndTrigger(std::move(_taskEndTrigger)) +{ + m_messageFactory = std::make_shared(); +} + +void LabeledPSISender::handlePsiParamsRequest(const PPCMessageFace::Ptr& _message) +{ + auto taskID = _message->taskID(); + LABELED_PSI_LOG(INFO) << LOG_BADGE("handlePsiParamsRequest") << LOG_KV("taskID", taskID); + + try + { + auto tarsParams = fromPSIParams(m_senderDB->getParams(), m_senderDB->getBinBundleCount()); + auto paramsMessage = m_messageFactory->buildPPCMessage(uint8_t(TaskType::PSI), + uint8_t(TaskAlgorithmType::LABELED_PSI_2PC), taskID, std::make_shared()); + paramsMessage->setMessageType(uint8_t(LabeledPSIMessageType::PARAMS_RESPONSE)); + ppctars::serialize::encode(tarsParams, *paramsMessage->data()); + + // send psi params response + m_config->front()->asyncSendMessage( + _message->sender(), paramsMessage, m_config->networkTimeout(), + [self = weak_from_this(), taskID](bcos::Error::Ptr _error) { + auto sender = self.lock(); + if (!sender) + { + return; + } + if (_error && _error->errorCode()) + { + sender->onSenderTaskDone(taskID, std::move(_error)); + } + }, + nullptr); + } + catch (const std::exception& e) + { + onSenderException(taskID, "handlePsiParamsRequest", e); + } +} + +void LabeledPSISender::handleBlindedItems(const front::PPCMessageFace::Ptr& _message) +{ + auto taskID = _message->taskID(); + LABELED_PSI_LOG(INFO) << LOG_BADGE("handleBlindedItems") << LOG_KV("taskID", taskID); + + try + { + ppctars::OprfData blindedData; + ppctars::serialize::decode(*_message->data(), blindedData); + + // evaluate items + ppctars::OprfData evaluatedData; + evaluatedData.data = m_config->oprfServer()->evaluate(blindedData.data); + + auto evaluatedMessage = m_messageFactory->buildPPCMessage(uint8_t(TaskType::PSI), + uint8_t(TaskAlgorithmType::LABELED_PSI_2PC), taskID, std::make_shared()); + evaluatedMessage->setMessageType(uint8_t(LabeledPSIMessageType::OPRF_EVALUATED_ITEMS)); + ppctars::serialize::encode(evaluatedData, *evaluatedMessage->data()); + + // send evaluated items + m_config->front()->asyncSendMessage( + _message->sender(), evaluatedMessage, m_config->networkTimeout(), + [self = weak_from_this(), taskID](bcos::Error::Ptr _error) { + auto sender = self.lock(); + if (!sender) + { + return; + } + if (_error && _error->errorCode()) + { + sender->onSenderTaskDone(taskID, std::move(_error)); + } + }, + nullptr); + } + catch (const std::exception& e) + { + onSenderException(taskID, "handleBlindedItems", e); + } +} + +// receive encrypted powers and send polynomial ciphertext response +void LabeledPSISender::handleQuery(const front::PPCMessageFace::Ptr& _message) +{ + auto taskID = _message->taskID(); + LABELED_PSI_LOG(INFO) << LOG_BADGE("onReceiveQueryRequest") << LOG_KV("taskID", taskID); + + try + { + ppctars::QueryRequest queryRequest; + ppctars::serialize::decode(*(_message->data()), queryRequest); + + // construct queryPackage + QueryPackage queryPackage(queryRequest, m_senderDB); + + // acquire read lock on SenderDB + auto senderDBlock = m_senderDB->getReaderLock(); + + LABELED_PSI_LOG(INFO) << LOG_DESC("start processing query request on database") + << LOG_KV("taskID", taskID) + << LOG_KV("itemSize", m_senderDB->getItemCount()); + + // Copy over the CryptoContext from SenderDB; set the Evaluator for this local + // instance. Relinearization keys may not have been included in the query. In + // that case query.relin_keys() simply holds an empty seal::RelinKeys + // instance. There is no problem with the below call to CryptoContext::set_evaluator. + apsi::CryptoContext cryptoContext(m_senderDB->getCryptoContext()); + cryptoContext.set_evaluator(queryPackage.relinKeys()); + + uint32_t bundleIdxCount = m_senderDB->getParams().bundle_idx_count(); + uint32_t maxItemsPerBin = m_senderDB->getParams().table_params().max_items_per_bin; + + // For each bundle index i, we need a vector of powers of the query Qᵢ. We + // need powers all the way up to Qᵢ^max_items_per_bin. We don't store the + // zeroth power. If Paterson-Stockmeyer is used, then only a subset of the + // powers will be populated. + auto allPowers = + std::make_shared>>(bundleIdxCount); + + // we use a custom SEAL memory that is freed after the query is done + auto memoryPool = std::make_shared( + seal::MemoryManager::GetPool(seal::mm_force_new)); + + // Initialize powers + for (auto& powers : *allPowers) + { + // The + 1 is because we index by power. The 0th power is a dummy value. I + // promise this makes things easier to read. + size_t powersSize = static_cast(maxItemsPerBin) + 1; + powers.reserve(powersSize); + for (size_t i = 0; i < powersSize; i++) + { + powers.emplace_back(*memoryPool); + } + } + + // Load inputs provided in the query + for (auto& powerIt : queryPackage.powers()) + { + // The exponent of all the query powers we're about to iterate through + auto exponent = static_cast(powerIt.first); + + // Load Qᵢᵉ for all bundle indices i, where e is the exponent specified + // above + for (size_t bundleIdx = 0; bundleIdx < bundleIdxCount; ++bundleIdx) + { + // Load input^power to allPowers[bundle_idx][exponent] + LABELED_PSI_LOG(DEBUG) + << LOG_DESC("extracting query ciphertext") << LOG_KV("power", exponent) + << LOG_KV("bundleIndex", bundleIdx); + + (*allPowers)[bundleIdx][exponent] = powerIt.second[bundleIdx]; + } + } + + auto receiverID = _message->sender(); + + // Compute query powers for the bundle indexes + for (size_t bundleIdx = 0; bundleIdx < bundleIdxCount; ++bundleIdx) + { + computePowers(taskID, receiverID, cryptoContext, allPowers, memoryPool, + queryPackage.powersDag(), static_cast(bundleIdx)); + } + + LABELED_PSI_LOG(INFO) << LOG_DESC("start processing bin bundle caches") + << LOG_KV("taskID", taskID); + uint32_t seq = 0; + auto current = std::make_shared>(0); + uint32_t total = m_senderDB->getBinBundleCount(); + for (size_t bundleIdx = 0; bundleIdx < bundleIdxCount; ++bundleIdx) + { + auto bundleCaches = m_senderDB->getCacheAt(static_cast(bundleIdx)); + for (auto& cache : bundleCaches) + { + m_config->threadPool()->enqueue([self = weak_from_this(), taskID, receiverID, + allPowers, memoryPool, cryptoContext, cache, + bundleIdx, seq, current, total]() { + auto sender = self.lock(); + if (!sender) + { + return; + } + + try + { + sender->processBinBundleCache(taskID, receiverID, cryptoContext, allPowers, + memoryPool, cache, bundleIdx, seq); + + auto currentStep = current->fetch_add(1); + if (currentStep + 1 == total) + { + // current task is done for sender + sender->onSenderTaskDone(taskID, nullptr); + } + } + catch (const std::exception& e) + { + sender->onSenderException(taskID, + "processBinBundleCache, bundleIdx: " + std::to_string(bundleIdx), e); + } + }); + seq++; + } + } + } + catch (const std::exception& e) + { + onSenderException(taskID, "handleBlindedItems", e); + } +} + + +void LabeledPSISender::computePowers(const std::string& _taskID, const std::string& _receiverID, + const apsi::CryptoContext& _cryptoContext, + std::shared_ptr>> _allPowers, + std::shared_ptr _memoryPool, const apsi::PowersDag& _powersDag, + uint32_t _bundleIdx) +{ + auto bundleCaches = m_senderDB->getCacheAt(_bundleIdx); + if (bundleCaches.empty()) + { + return; + } + + LABELED_PSI_LOG(INFO) << LOG_DESC("start computing powers") << LOG_KV("taskID", _taskID) + << LOG_KV("bundleIdx", _bundleIdx); + + auto evaluator = _cryptoContext.evaluator(); + auto relinKeys = _cryptoContext.relin_keys(); + bool relinearize = _cryptoContext.seal_context()->using_keyswitching(); + + _powersDag.parallel_apply([&](const apsi::PowersDag::PowersNode& node) { + if (!node.is_source()) + { + auto parents = node.parents; + seal::Ciphertext prod(*_memoryPool); + if (parents.first == parents.second) + { + evaluator->square((*_allPowers)[_bundleIdx][parents.first], prod, *_memoryPool); + } + else + { + evaluator->multiply((*_allPowers)[_bundleIdx][parents.first], + (*_allPowers)[_bundleIdx][parents.second], prod, *_memoryPool); + } + if (relinearize) + { + evaluator->relinearize_inplace(prod, *relinKeys, *_memoryPool); + } + (*_allPowers)[_bundleIdx][node.power] = std::move(prod); + } + }); + + // Now that all powers of the ciphertext have been computed, we need to + // transform them to NTT form. This will substantially improve the polynomial + // evaluation, because the plaintext polynomials are already in NTT + // transformed form, and the ciphertexts are used repeatedly for each bin + // bundle at this index. This computation is separate from the graph + // processing above, because the multiplications must all be done before + // transforming to NTT form. We omit the first ciphertext in the vector, + // because it corresponds to the zeroth power of the query and is included + // only for convenience of the indexing; the ciphertext is actually not set or + // valid for use. + + // After computing all powers we do modules switch down to parameters that + // one more level for low powers than for high powers; same choice must be + // used when encoding/NTT transforming the SenderDB data. + auto highPowersParmsId = + apsi::util::get_parms_id_for_chain_idx(*_cryptoContext.seal_context(), 1); + auto lowPowersParmsId = + apsi::util::get_parms_id_for_chain_idx(*_cryptoContext.seal_context(), 2); + + uint32_t psLowDegree = m_senderDB->getParams().query_params().ps_low_degree; + + std::vector targetPowers; + for (auto& power : _powersDag.target_powers()) + { + targetPowers.emplace_back(power); + } + + tbb::parallel_for(tbb::blocked_range(0U, targetPowers.size()), [&](auto const& range) { + for (auto i = range.begin(); i < range.end(); i++) + { + uint32_t power = targetPowers[i]; + + if (!psLowDegree) + { + // Only one ciphertext-plaintext multiplication is needed after this + evaluator->mod_switch_to_inplace( + (*_allPowers)[_bundleIdx][power], highPowersParmsId, *_memoryPool); + + // All powers must be in NTT form + evaluator->transform_to_ntt_inplace((*_allPowers)[_bundleIdx][power]); + } + else + { + if (power <= psLowDegree) + { + // Low powers must be at a higher level than high powers + evaluator->mod_switch_to_inplace( + (*_allPowers)[_bundleIdx][power], lowPowersParmsId, *_memoryPool); + + // Low powers must be in NTT form + evaluator->transform_to_ntt_inplace((*_allPowers)[_bundleIdx][power]); + } + else + { + // High powers are only modulus switched + evaluator->mod_switch_to_inplace( + (*_allPowers)[_bundleIdx][power], highPowersParmsId, *_memoryPool); + } + } + } + }); + + LABELED_PSI_LOG(INFO) << LOG_DESC("finish computing powers") << LOG_KV("taskID", _taskID) + << LOG_KV("bundleIdx", _bundleIdx); +} + +void LabeledPSISender::processBinBundleCache(const std::string& _taskID, + const std::string& _receiverID, const apsi::CryptoContext& _cryptoContext, + const std::shared_ptr>>& _allPowers, + const std::shared_ptr& _memoryPool, + std::reference_wrapper _cache, uint32_t _bundleIdx, uint32_t _seq) +{ + LABELED_PSI_LOG(DEBUG) << LOG_DESC("processBinBundleCache") << LOG_KV("taskID", _taskID) + << LOG_KV("bundleIdx", _bundleIdx); + + // Package for the result data + ResultPackage resultPackage; + resultPackage.bundleIdx = _bundleIdx; + resultPackage.nonceByteCount = seal::util::safe_cast(m_senderDB->getNonceByteCount()); + resultPackage.labelByteCount = seal::util::safe_cast(m_senderDB->getLabelByteCount()); + + // Compute the matching result and move to rp + const BatchedPlaintextPolyn& matchingPolyn = _cache.get().batched_matching_polyn; + + // Determine if we use Paterson-Stockmeyer or not + uint32_t psLowDegree = m_senderDB->getParams().query_params().ps_low_degree; + uint32_t degree = seal::util::safe_cast(matchingPolyn.batched_coeffs.size()) - 1; + + bool usingPs = (psLowDegree > 1) && (psLowDegree < degree); + if (usingPs) + { + resultPackage.psiCipherResult = matchingPolyn.eval_patstock(_cryptoContext, + (*_allPowers)[_bundleIdx], seal::util::safe_cast(psLowDegree), *_memoryPool); + } + else + { + resultPackage.psiCipherResult = matchingPolyn.eval((*_allPowers)[_bundleIdx], *_memoryPool); + } + + for (const auto& interpPolyn : _cache.get().batched_interp_polyns) + { + // Compute the label result and move to rp + degree = seal::util::safe_cast(interpPolyn.batched_coeffs.size()) - 1; + usingPs = (psLowDegree > 1) && (psLowDegree < degree); + if (usingPs) + { + resultPackage.labelCipherResults.emplace_back(interpPolyn.eval_patstock( + _cryptoContext, (*_allPowers)[_bundleIdx], psLowDegree, *_memoryPool)); + } + else + { + resultPackage.labelCipherResults.emplace_back( + interpPolyn.eval((*_allPowers)[_bundleIdx], *_memoryPool)); + } + } + + // send result package to receiver + sendResultPackage(_taskID, _receiverID, resultPackage, _seq); +} + +void LabeledPSISender::sendResultPackage(const std::string& _taskID, const std::string& _receiverID, + const ResultPackage& _resultPackage, uint32_t _seq) +{ + LABELED_PSI_LOG(DEBUG) << LOG_DESC("send result package") << LOG_KV("taskID", _taskID) + << LOG_KV("seq", _seq); + + ppctars::QueryResponse queryResponse; + queryResponse.labelByteCount = _resultPackage.labelByteCount; + queryResponse.nonceByteCount = _resultPackage.nonceByteCount; + queryResponse.bundleIdx = _resultPackage.bundleIdx; + + std::vector psiCipher(_resultPackage.psiCipherResult.save_size(m_comprMode)); + _resultPackage.psiCipherResult.save(psiCipher, m_comprMode); + queryResponse.ciphertext = std::move(psiCipher); + + for (auto& result : _resultPackage.labelCipherResults) + { + std::vector labelCipher(result.save_size(m_comprMode)); + result.save(labelCipher, m_comprMode); + queryResponse.labelResults.emplace_back(std::move(labelCipher)); + } + + auto resultMessage = m_messageFactory->buildPPCMessage(uint8_t(TaskType::PSI), + uint8_t(TaskAlgorithmType::LABELED_PSI_2PC), _taskID, std::make_shared()); + resultMessage->setMessageType(uint8_t(LabeledPSIMessageType::RESPONSE)); + resultMessage->setSeq(_seq); + ppctars::serialize::encode(queryResponse, *resultMessage->data()); + + auto error = m_config->sendMessage(_receiverID, resultMessage); + if (error && error->errorCode()) + { + onSenderTaskDone(_taskID, std::move(error)); + } +} + +void LabeledPSISender::onSenderException( + const std::string& _taskID, const std::string& _module, const std::exception& _e) +{ + LABELED_PSI_LOG(ERROR) << LOG_BADGE("onSenderException") << LOG_KV("taskID", _taskID) + << LOG_KV("module", _module) + << LOG_KV("error", boost::diagnostic_information(_e)); + auto error = std::make_shared((int)LabeledPSIRetCode::ON_EXCEPTION, + "exception caught while do " + _module + ", message: " + boost::diagnostic_information(_e)); + m_taskEndTrigger(_taskID, error); +} + +void LabeledPSISender::onSenderTaskDone(const std::string& _taskID, bcos::Error::Ptr _error) +{ + m_taskEndTrigger(_taskID, std::move(_error)); +} diff --git a/cpp/wedpr-computing/ppc-psi/src/labeled-psi/core/LabeledPSISender.h b/cpp/wedpr-computing/ppc-psi/src/labeled-psi/core/LabeledPSISender.h new file mode 100644 index 00000000..bddd01c6 --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/labeled-psi/core/LabeledPSISender.h @@ -0,0 +1,93 @@ +/** + * Copyright (C) 2022 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 LabeledPSISender.h + * @author: shawnhe + * @date 2022-11-6 + */ + + +#pragma once + +#include + +#include +#include +#include +#include + +#include "ResultPackage.h" +#include "SenderDB.h" +#include "ppc-framework/crypto/Oprf.h" +#include "ppc-framework/protocol/Task.h" +#include "ppc-front/ppc-front/PPCChannel.h" +#include "ppc-psi/src/labeled-psi/LabeledPSIConfig.h" +#include "ppc-psi/src/labeled-psi/protocol/Protocol.h" +#include "protocol/src/PPCMessage.h" + +namespace ppc::psi +{ +class LabeledPSISender : public std::enable_shared_from_this +{ +public: + using Ptr = std::shared_ptr; + virtual ~LabeledPSISender() = default; + + LabeledPSISender(LabeledPSIConfig::Ptr _config, + std::function _taskEndTrigger); + +public: + // send psi params for some task + void handlePsiParamsRequest(const front::PPCMessageFace::Ptr& _message); + + // receive blinded items and send evaluated items + void handleBlindedItems(const front::PPCMessageFace::Ptr& _message); + + // receive encrypted powers and send polynomial ciphertext response + void handleQuery(const front::PPCMessageFace::Ptr& _message); + + void setSenderDB(SenderDB::Ptr _senderDB) { m_senderDB = std::move(_senderDB); } + +protected: + void computePowers(const std::string& _taskID, const std::string& _receiverID, + const apsi::CryptoContext& _cryptoContext, + std::shared_ptr>> _allPowers, + std::shared_ptr _memoryPool, const apsi::PowersDag& _powersDag, + uint32_t _bundleIdx); + void processBinBundleCache(const std::string& _taskID, const std::string& _receiverID, + const apsi::CryptoContext& _cryptoContext, + const std::shared_ptr>>& _allPowers, + const std::shared_ptr& _memoryPool, + std::reference_wrapper _cache, uint32_t _bundleIdx, uint32_t _seq); + void sendResultPackage(const std::string& _taskID, const std::string& _receiverID, + const ResultPackage& _resultPackage, uint32_t _seq); + + void onSenderException( + const std::string& _taskID, const std::string& _module, const std::exception& _e); + void onSenderTaskDone(const std::string& _taskID, bcos::Error::Ptr _error); + +private: + LabeledPSIConfig::Ptr m_config; + + std::function m_taskEndTrigger; + + front::PPCMessageFactory::Ptr m_messageFactory; + + // set after initialization of sender + SenderDB::Ptr m_senderDB; + + seal::compr_mode_type m_comprMode{seal::Serialization::compr_mode_default}; +}; +} // namespace ppc::psi diff --git a/cpp/wedpr-computing/ppc-psi/src/labeled-psi/core/QueryPackage.cpp b/cpp/wedpr-computing/ppc-psi/src/labeled-psi/core/QueryPackage.cpp new file mode 100644 index 00000000..c1e86738 --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/labeled-psi/core/QueryPackage.cpp @@ -0,0 +1,128 @@ +/** + * Copyright (C) 2022 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 QueryPackage.cpp + * @author: shawnhe + * @date 2022-11-14 + * + */ + +#include +#include +#include + +#include "QueryPackage.h" +#include "ppc-psi/src/labeled-psi/Common.h" + +using namespace ppc::psi; + +QueryPackage::QueryPackage(ppctars::QueryRequest _queryQuest, SenderDB::Ptr _senderDB) +{ + auto sealContext = _senderDB->getSealContext(); + + // extract and validate relinearization keys + apsi::SEALObject relinKeys; + if (sealContext->using_keyswitching()) + { + gsl::span relinKeysSpan( + reinterpret_cast(_queryQuest.relinKeys.data()), + _queryQuest.relinKeys.size()); + relinKeys.load(sealContext, relinKeysSpan); + m_relinKeys = relinKeys.extract(sealContext); + if (!is_valid_for(m_relinKeys, *sealContext)) + { + BOOST_THROW_EXCEPTION(ExtracteRelinKeysException() << bcos::errinfo_comment( + "Extracted RelinKeys are invalid for SEALContext")); + } + } + + // extract and validate query ciphertexts + for (auto& encryptedPowers : _queryQuest.encryptedPowers) + { + std::vector ciphertexts; + ciphertexts.reserve(encryptedPowers.ciphertexts.size()); + for (auto& ct : encryptedPowers.ciphertexts) + { + gsl::span ctSpan(reinterpret_cast(ct.data()), ct.size()); + apsi::SEALObject temp; + temp.load(sealContext, ctSpan); + ciphertexts.emplace_back(temp.extract(sealContext)); + if (!is_valid_for(ciphertexts.back(), *sealContext)) + { + BOOST_THROW_EXCEPTION(ExtracteCiphertextException() << bcos::errinfo_comment( + "Extracted ciphertext is invalid for SEALContext")); + } + } + m_powers.emplace(encryptedPowers.power, std::move(ciphertexts)); + } + + uint32_t psLowDegree = _senderDB->getParams().query_params().ps_low_degree; + uint32_t maxItemsPerBin = _senderDB->getParams().table_params().max_items_per_bin; + + std::set targetPowers = create_powers_set(psLowDegree, maxItemsPerBin); + const std::set& queryPowers = _senderDB->getParams().query_params().query_powers; + + // create the PowersDag + m_powersDag.configure(queryPowers, targetPowers); + + // check that the PowersDag is valid + if (!m_powersDag.is_configured()) + { + BOOST_THROW_EXCEPTION(PowerDagException() << bcos::errinfo_comment( + "Failed to configure PowersDag, queryPowers: " + + apsi::util::to_string(queryPowers) + + ", targetPowers: " + apsi::util::to_string(targetPowers))); + } + LABELED_PSI_LOG(INFO) << LOG_DESC("finished configuring PowersDag") + << LOG_KV("depth", m_powersDag.depth()); + + // check that the query data size matches the PSIParams + + if (m_powers.size() != queryPowers.size()) + { + BOOST_THROW_EXCEPTION( + QueryPowersException() << bcos::errinfo_comment( + "Extracted query data is incompatible with PSI parameters, powderDag contains " + + std::to_string(m_powers.size()) + + " ciphertext powers which does not match with the size of queryPowers (" + + std::to_string(queryPowers.size()) + ")")); + } + uint32_t bundleIdxCount = _senderDB->getParams().bundle_idx_count(); + for (auto& powers : m_powers) + { + // check that powers in the query data match source nodes in the PowersDag + if (powers.second.size() != bundleIdxCount) + { + BOOST_THROW_EXCEPTION( + QueryPowersException() << bcos::errinfo_comment( + "Extracted query data is incompatible with PSI parameters, queryPower " + + std::to_string(powers.first) + " contains " + + std::to_string(powers.second.size()) + + " ciphertexts which does not match with bundle_idx_count (" + + std::to_string(bundleIdxCount) + ")")); + } + + auto where = find_if(queryPowers.cbegin(), queryPowers.cend(), + [&powers](auto n) { return n == powers.first; }); + if (where == queryPowers.cend()) + { + BOOST_THROW_EXCEPTION( + QueryPowersException() << bcos::errinfo_comment( + "Extracted query data is incompatible with PowersDag, queryPower " + + std::to_string(powers.first) + + " does not match with a source node in PowersDag")); + } + } +} \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-psi/src/labeled-psi/core/QueryPackage.h b/cpp/wedpr-computing/ppc-psi/src/labeled-psi/core/QueryPackage.h new file mode 100644 index 00000000..87579bfc --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/labeled-psi/core/QueryPackage.h @@ -0,0 +1,64 @@ +/** + * Copyright (C) 2022 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 QueryPackage.h + * @author: shawnhe + * @date 2022-11-14 + * + */ + +#pragma once + +#include +#include +#include +#include + +#include +#include +#include + +#include "LabeledPSI.h" +#include "SenderDB.h" +#include "ppc-psi/src/labeled-psi/Common.h" + + +namespace ppc::psi +{ +class QueryPackage +{ +public: + QueryPackage() = default; + + QueryPackage(ppctars::QueryRequest _queryQuest, SenderDB::Ptr _senderDB); + + const seal::RelinKeys& relinKeys() { return m_relinKeys; } + + const std::unordered_map>& powers() + { + return m_powers; + } + + const apsi::PowersDag& powersDag() const noexcept { return m_powersDag; } + +private: + seal::RelinKeys m_relinKeys; + + std::unordered_map> m_powers; + + apsi::PowersDag m_powersDag; +}; + +} // namespace ppc::psi diff --git a/cpp/wedpr-computing/ppc-psi/src/labeled-psi/core/ResultPackage.cpp b/cpp/wedpr-computing/ppc-psi/src/labeled-psi/core/ResultPackage.cpp new file mode 100644 index 00000000..d425f734 --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/labeled-psi/core/ResultPackage.cpp @@ -0,0 +1,61 @@ +/** + * Copyright (C) 2022 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 ResultPackage.cpp + * @author: shawnhe + * @date 2022-11-6 + */ + +#include "ResultPackage.h" +#include "ppc-psi/src/labeled-psi/Common.h" + +using namespace ppc::psi; + +PlainResultPackage ResultPackage::extract(const apsi::CryptoContext& _cryptoContext) +{ + if (!_cryptoContext.decryptor()) + { + BOOST_THROW_EXCEPTION(ResultPackageException() << bcos::errinfo_comment( + "Decryptor is not configured in CryptoContext")); + } + + PlainResultPackage plainRp; + plainRp.bundleIdx = bundleIdx; + plainRp.labelByteCount = labelByteCount; + plainRp.nonceByteCount = nonceByteCount; + + // psi + seal::Plaintext psiPlain; + seal::Ciphertext psiCipher = psiCipherResult.extract(_cryptoContext.seal_context()); + _cryptoContext.decryptor()->decrypt(psiCipher, psiPlain); + _cryptoContext.encoder()->decode(psiPlain, plainRp.psiResult); + + // labels + for (auto& ct : labelCipherResults) + { + seal::Plaintext labelPlain; + seal::Ciphertext labelCipher = ct.extract(_cryptoContext.seal_context()); + _cryptoContext.decryptor()->decrypt(labelCipher, labelPlain); + + std::vector labelResultData; + _cryptoContext.encoder()->decode(labelPlain, labelResultData); + plainRp.labelResults.emplace_back(std::move(labelResultData)); + } + + // clear the label data + std::vector>().swap(labelCipherResults); + + return plainRp; +} diff --git a/cpp/wedpr-computing/ppc-psi/src/labeled-psi/core/ResultPackage.h b/cpp/wedpr-computing/ppc-psi/src/labeled-psi/core/ResultPackage.h new file mode 100644 index 00000000..b6a55ad2 --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/labeled-psi/core/ResultPackage.h @@ -0,0 +1,68 @@ +/** + * Copyright (C) 2022 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 ResultPackage.h + * @author: shawnhe + * @date 2022-11-6 + */ + +#pragma once +#include +#include + +#include +#include +#include +#include + +namespace ppc::psi +{ +/** +Stores a decrypted and decoded PSI response and optionally a labeled PSI response. +*/ +struct PlainResultPackage +{ + std::uint32_t bundleIdx; + + std::vector psiResult; + + std::uint32_t labelByteCount; + + std::uint32_t nonceByteCount; + + std::vector> labelResults; +}; + +/** +Stores a PSI response and optionally labeled PSI response ciphertexts. +*/ +struct ResultPackage +{ +public: + PlainResultPackage extract(const apsi::CryptoContext& crypto_context); + + std::uint32_t bundleIdx; + + apsi::SEALObject psiCipherResult; + + std::uint32_t labelByteCount; + + std::uint32_t nonceByteCount; + + std::vector> labelCipherResults; +}; + + +} // namespace ppc::psi \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-psi/src/labeled-psi/core/SenderDB.cpp b/cpp/wedpr-computing/ppc-psi/src/labeled-psi/core/SenderDB.cpp new file mode 100644 index 00000000..567176f5 --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/labeled-psi/core/SenderDB.cpp @@ -0,0 +1,1184 @@ +/** + * Copyright (C) 2022 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. + * + * @reference https://github.com/microsoft/APSI/sender/sender_db.cpp + * @license MIT license + * @change optimize the implementation of some functions & replace the instance of oprf + * + * @file SenderDB.h + * @author: shawnhe + * @date 2022-11-7 + * + */ + +// APSI +#include +#include +#include +#include + +// Kuku +#include "kuku/locfunc.h" + +// SEAL +#include "seal/util/common.h" +#include "seal/util/streambuf.h" + +#include +#include +#include + +#include "SenderDB.h" +#include "ppc-psi/src/labeled-psi/Common.h" + +#include "../protocol/Protocol.h" + +using namespace ppc; +using namespace ppc::crypto; +using namespace ppc::psi; + +/** +Creates and returns the vector of hash functions similarly to how Kuku 2.x sets +them internally. +*/ +inline std::vector hashFunctions(const apsi::PSIParams& params) +{ + std::vector result; + for (uint32_t i = 0; i < params.table_params().hash_func_count; i++) + { + result.emplace_back(params.table_params().table_size, kuku::make_item(i, 0)); + } + + return result; +} + +/** +Computes all cuckoo hash table locations for a given item. +*/ +inline std::unordered_set allLocations( + const std::vector& hash_funcs, const apsi::HashedItem& item) +{ + std::unordered_set result; + for (auto& hf : hash_funcs) + { + result.emplace(hf(item.get_as().front())); + } + + return result; +} + +/** +Compute the label size in multiples of item-size chunks. +*/ +inline size_t computeLabelSize(size_t label_byte_count, const apsi::PSIParams& params) +{ + return (label_byte_count * 8 + params.item_bit_count() - 1) / params.item_bit_count(); +} + +/** +Unpacks a cuckoo idx into its bin and bundle indices +*/ +inline std::pair unpackCuckooIdx(size_t cuckoo_idx, size_t bins_per_bundle) +{ + // Recall that bin indices are relative to the bundle index. That is, the + // first bin index of a bundle at bundle index 5 is 0. A cuckoo index is + // similar, except it is not relative to the bundle index. It just keeps + // counting past bundle boundaries. So in order to get the bin index from the + // cuckoo index, just compute cuckoo_idx (mod bins_per_bundle). + size_t bin_idx = cuckoo_idx % bins_per_bundle; + + // Compute which bundle index this cuckoo index belongs to + size_t bundle_idx = (cuckoo_idx - bin_idx) / bins_per_bundle; + + return {bin_idx, bundle_idx}; +} + +/** +Compute oprf hash for items and encrypt labels +*/ +inline std::vector> preprocessItemsAndLabels( + ppc::io::DataBatch::Ptr _items, ppc::io::DataBatch::Ptr _labels, size_t _labelByteCount, + size_t _nonceByteCount, crypto::OprfServer::Ptr _oprfServer) +{ + // do oprf + size_t dataSize = _items->size(); + std::vector oprfOut; + oprfOut.reserve(dataSize); + oprfOut.resize(dataSize); + + tbb::parallel_for(tbb::blocked_range(0U, dataSize), [&](auto const& range) { + for (auto i = range.begin(); i < range.end(); i++) + { + oprfOut[i] = _oprfServer->fullEvaluate(_items->getBytes(i)); + } + }); + + std::vector> results(dataSize); + tbb::parallel_for(tbb::blocked_range(0U, dataSize), [&](auto const& range) { + for (auto i = range.begin(); i < range.end(); ++i) + { + // the left half is item hash + apsi::HashedItem hashedItem; + std::memcpy(hashedItem.value().data(), oprfOut[i].data(), hashedItem.value().size()); + + // the right half is key for label encryption + apsi::LabelKey key; + std::memcpy(key.data(), oprfOut[i].data() + hashedItem.value().size(), key.size()); + + // encrypt labels + apsi::EncryptedLabel encryptedLabel = + encrypt_label(_labels->getBytes(i), key, _labelByteCount, _nonceByteCount); + + results[i] = std::make_pair(hashedItem, encryptedLabel); + } + }); + + return results; +} + +inline std::vector> preprocessItemsAndLabels( + const std::vector>& _pairs, size_t _labelByteCount, + size_t _nonceByteCount, crypto::OprfServer::Ptr _oprfServer) +{ + // do oprf + size_t dataSize = _pairs.size(); + std::vector oprfOut; + oprfOut.reserve(dataSize); + oprfOut.resize(dataSize); + + tbb::parallel_for(tbb::blocked_range(0U, dataSize), [&](auto const& range) { + for (auto i = range.begin(); i < range.end(); i++) + { + oprfOut[i] = _oprfServer->fullEvaluate( + bcos::bytes(_pairs[i].first.value().begin(), _pairs[i].first.value().end())); + } + }); + + std::vector> results(dataSize); + + tbb::parallel_for(tbb::blocked_range(0U, dataSize), [&](auto const& range) { + for (auto i = range.begin(); i < range.end(); ++i) + { + // the left half is item hash + apsi::HashedItem hashedItem; + std::memcpy(hashedItem.value().data(), oprfOut[i].data(), hashedItem.value().size()); + + // the right half is key for label encryption + apsi::LabelKey key; + std::memcpy(key.data(), oprfOut[i].data() + hashedItem.value().size(), key.size()); + + // encrypt labels + apsi::EncryptedLabel encryptedLabel = + encrypt_label(_pairs[i].second, key, _labelByteCount, _nonceByteCount); + + results[i] = std::make_pair(hashedItem, encryptedLabel); + } + }); + + return results; +} + +/** +Compute oprf hash for items +*/ +inline std::vector preprocessItems( + const std::vector& _items, crypto::OprfServer::Ptr _oprfServer) +{ + // do oprf + size_t dataSize = _items.size(); + std::vector oprfOut; + oprfOut.reserve(dataSize); + oprfOut.resize(dataSize); + tbb::parallel_for(tbb::blocked_range(0U, dataSize), [&](auto const& range) { + for (auto i = range.begin(); i < range.end(); i++) + { + std::string itemStr(_items[i].value().size(), 0); + std::memcpy(itemStr.data(), _items[i].value().data(), _items[i].value().size()); + oprfOut[i] = _oprfServer->fullEvaluate(itemStr); + } + }); + + std::vector results; + for (auto& hash : oprfOut) + { + // truncate hash + apsi::Item::value_type value{}; + std::memcpy(value.data(), hash.data(), value.size()); + results.emplace_back(value); + } + + return results; +} + +/** +Converts each given Item-Label pair in between the given iterators into its +algebraic form, i.e., a sequence of felt-felt pairs. Also computes each Item's +cuckoo index. +*/ +std::vector> transformLabeledData( + const std::vector>::const_iterator begin, + const std::vector>::const_iterator end, + const apsi::PSIParams& params) +{ + LABELED_PSI_LOG(DEBUG) << LOG_DESC("start transforming labeled data") + << LOG_KV("count", distance(begin, end)); + + // Some variables we'll need + size_t bins_per_item = params.item_params().felts_per_item; + size_t item_bit_count = params.item_bit_count(); + + // Set up Kuku hash functions + auto hash_funcs = hashFunctions(params); + + // Calculate the cuckoo indices for each item. Store every pair of + // (item-label, cuckoo_idx) in a vector. Later, we're gonna sort this vector + // by cuckoo_idx and use the result to parallelize the work of inserting the + // items into BinBundles. + std::vector> data_with_indices; + for (auto it = begin; it != end; it++) + { + const std::pair& item_label_pair = *it; + + // Serialize the data into field elements + const apsi::HashedItem& item = item_label_pair.first; + const apsi::EncryptedLabel& label = item_label_pair.second; + apsi::util::AlgItemLabel alg_item_label = algebraize_item_label( + item, label, item_bit_count, params.seal_params().plain_modulus()); + + // Get the cuckoo table locations for this item and add to data_with_indices + for (auto location : allLocations(hash_funcs, item)) + { + // The current hash value is an index into a table of Items. In reality + // our BinBundles are tables of bins, which contain chunks of items. How + // many chunks? bins_per_item many chunks + size_t bin_idx = location * bins_per_item; + + // Store the data along with its index + data_with_indices.emplace_back(alg_item_label, bin_idx); + } + } + + LABELED_PSI_LOG(DEBUG) << LOG_DESC("finished transforming labeled data") + << LOG_KV("count", distance(begin, end)); + + return data_with_indices; +} + +/** +Converts each given Item into its algebraic form, i.e., a sequence of +felt-monostate pairs. Also computes each Item's cuckoo index. +*/ +std::vector> transformUnlabeledData( + const std::vector::const_iterator begin, + const std::vector::const_iterator end, const apsi::PSIParams& params) +{ + LABELED_PSI_LOG(DEBUG) << LOG_DESC("start transforming unlabeled data") + << LOG_KV("count", distance(begin, end)); + + // Some variables we'll need + size_t bins_per_item = params.item_params().felts_per_item; + size_t item_bit_count = params.item_bit_count(); + + // Set up Kuku hash functions + auto hash_funcs = hashFunctions(params); + + // Calculate the cuckoo indices for each item. Store every pair of + // (item-label, cuckoo_idx) in a vector. Later, we're gonna sort this vector + // by cuckoo_idx and use the result to parallelize the work of inserting the + // items into BinBundles. + std::vector> data_with_indices; + for (auto it = begin; it != end; it++) + { + const apsi::HashedItem& item = *it; + + // Serialize the data into field elements + apsi::util::AlgItem alg_item = + algebraize_item(item, item_bit_count, params.seal_params().plain_modulus()); + + // Get the cuckoo table locations for this item and add to data_with_indices + for (auto location : allLocations(hash_funcs, item)) + { + // The current hash value is an index into a table of Items. In reality + // our BinBundles are tables of bins, which contain chunks of items. How + // many chunks? bins_per_item many chunks + size_t bin_idx = location * bins_per_item; + + // Store the data along with its index + data_with_indices.emplace_back(std::make_pair(alg_item, bin_idx)); + } + } + + LABELED_PSI_LOG(DEBUG) << LOG_DESC("finished transforming unlabeled data") + << LOG_KV("count", distance(begin, end)); + + return data_with_indices; +} + +/** +Converts given Item into its algebraic form, i.e., a sequence of felt-monostate +pairs. Also computes the Item's cuckoo index. +*/ +std::vector> transformUnlabeledData( + const apsi::HashedItem& item, const apsi::PSIParams& params) +{ + std::vector item_singleton{item}; + return transformUnlabeledData(item_singleton.begin(), item_singleton.end(), params); +} + +/** +Inserts the given items and corresponding labels into bin_bundles at their +respective cuckoo indices. It will only insert the data with bundle index in the +half-open range range indicated by work_range. If inserting into a BinBundle +would make the number of items in a bin larger than max_bin_size, this function +will create and insert a new BinBundle. If overwrite is set, this will overwrite +the labels if it finds an AlgItemLabel that matches the input perfectly. +*/ +template +void insertOrAssignWorker(std::vector& bin_bundles, + const std::vector>& data_with_indices, + const apsi::CryptoContext& crypto_context, uint32_t bundle_index, size_t label_size, + const apsi::PSIParams& _params, bool overwrite, bool compressed) +{ + LABELED_PSI_LOG(DEBUG) << LOG_DESC("start insert-or-assign worker") + << LOG_KV("bundleIndex", bundle_index) << LOG_KV("overwrite", overwrite); + + // Iteratively insert each item-label pair at the given cuckoo index + for (auto& data_with_idx : data_with_indices) + { + const T& data = data_with_idx.first; + + // Get the bundle index + size_t cuckoo_idx = data_with_idx.second; + size_t bin_idx, bundle_idx; + std::tie(bin_idx, bundle_idx) = unpackCuckooIdx(cuckoo_idx, _params.bins_per_bundle()); + + // If the bundle_idx isn't in the prescribed range, don't try to insert this + // data + if (bundle_idx != bundle_index) + { + // Dealing with this bundle index is not our job + continue; + } + + // Try to insert or overwrite these field elements in an existing BinBundle + // at this bundle index. Keep track of whether we succeed or not. + bool written = false; + for (auto bundle_it = bin_bundles.rbegin(); bundle_it != bin_bundles.rend(); bundle_it++) + { + // If we're supposed to overwrite, try to overwrite. One of these + // BinBundles has to have the data we're trying to overwrite. + if (overwrite) + { + // If we successfully overwrote, we're done with this bundle + written = bundle_it->try_multi_overwrite(data, bin_idx); + if (written) + { + break; + } + } + + // Do a dry-run insertion and see if the new largest bin size in the range + // exceeds the limit + int32_t new_largest_bin_size = bundle_it->multi_insert_dry_run(data, bin_idx); + + // Check if inserting would violate the max bin size constraint + if (new_largest_bin_size > 0 && seal::util::safe_cast(new_largest_bin_size) < + _params.table_params().max_items_per_bin) + { + // All good + bundle_it->multi_insert_for_real(data, bin_idx); + written = true; + break; + } + } + + // We tried to overwrite an item that doesn't exist. This should never + // happen + if (overwrite && !written) + { + BOOST_THROW_EXCEPTION(OverwriteItemException() + << bcos::errinfo_comment("Tried to overwrite non-existent item")); + } + + // If we had conflicts everywhere when trying to insert, then we need to + // make a new BinBundle and insert the data there + if (!written) + { + // Make a fresh BinBundle and insert + BinBundle new_bin_bundle(crypto_context, label_size, + _params.table_params().max_items_per_bin, _params.query_params().ps_low_degree, + _params.bins_per_bundle(), compressed, false); + int res = new_bin_bundle.multi_insert_for_real(data, bin_idx); + + // If even that failed, I don't know what could've happened + if (res < 0) + { + BOOST_THROW_EXCEPTION(InsertItemException() << bcos::errinfo_comment( + "Failed to insert item into a new BinBundle with index " + + std::to_string(bundle_idx))); + } + + // Push a new BinBundle to the set of BinBundles at this bundle index + bin_bundles.push_back(std::move(new_bin_bundle)); + } + } + + LABELED_PSI_LOG(DEBUG) << LOG_DESC("finished insert-or-assign worker") + << LOG_KV("bundleIndex", bundle_index) << LOG_KV("overwrite", overwrite); +} + + +/** +Takes algebraized data to be inserted, splits it up, and distributes it so that +thread_count many threads can all insert in parallel. If overwrite is set, this +will overwrite the labels if it finds an AlgItemLabel that matches the input +perfectly. +*/ +template +void dispatchInsertOrAssign(std::vector>& bin_bundles, + const std::vector>& data_with_indices, + const apsi::CryptoContext& crypto_context, size_t label_size, const apsi::PSIParams& _params, + bool overwrite, bool compressed) +{ + // Collect the bundle indices and partition them into thread_count many + // partitions. By some uniformity assumption, the number of things to insert + // per partition should be roughly the same. Note that the contents of + // bundle_indices is always sorted (increasing order). + std::set bundle_indices_set; + for (auto& data_with_idx : data_with_indices) + { + size_t cuckoo_idx = data_with_idx.second; + size_t bin_idx, bundle_idx; + std::tie(bin_idx, bundle_idx) = unpackCuckooIdx(cuckoo_idx, _params.bins_per_bundle()); + bundle_indices_set.insert(bundle_idx); + } + + std::vector bundle_indices; + bundle_indices.assign(bundle_indices_set.begin(), bundle_indices_set.end()); + + tbb::parallel_for( + tbb::blocked_range(0U, bundle_indices.size()), [&](auto const& range) { + for (auto i = range.begin(); i < range.end(); ++i) + { + auto bundleIndex = static_cast(bundle_indices[i]); + insertOrAssignWorker(bin_bundles[bundleIndex], data_with_indices, crypto_context, + bundleIndex, label_size, _params, overwrite, compressed); + } + }); + + LABELED_PSI_LOG(INFO) << LOG_DESC("finished all insert-or-assign worker tasks"); +} + + +/** +Removes the given items and corresponding labels from bin_bundles at their +respective cuckoo indices. +*/ +void removeWorker(std::vector& bin_bundles, + const std::vector>& data_with_indices, + uint32_t bundle_index, uint32_t bins_per_bundle) +{ + LABELED_PSI_LOG(INFO) << LOG_DESC("start remove worker") << LOG_KV("bundleIndex", bundle_index); + + + // Iteratively remove each item-label pair at the given cuckoo index + for (auto& data_with_idx : data_with_indices) + { + // Get the bundle index + size_t cuckoo_idx = data_with_idx.second; + size_t bin_idx, bundle_idx; + std::tie(bin_idx, bundle_idx) = unpackCuckooIdx(cuckoo_idx, bins_per_bundle); + + // If the bundle_idx isn't in the prescribed range, don't try to remove this + // data + if (bundle_idx != bundle_index) + { + // Dealing with this bundle index is not our job + continue; + } + + // Try to remove these field elements from an existing BinBundle at this + // bundle index. Keep track of whether we succeed or not. + bool removed = false; + for (BinBundle& bundle : bin_bundles) + { + // If we successfully removed, we're done with this bundle + removed = bundle.try_multi_remove(data_with_idx.first, bin_idx); + if (removed) + { + break; + } + } + + // We may have produced some empty BinBundles so just remove them all + auto rem_it = std::remove_if( + bin_bundles.begin(), bin_bundles.end(), [](auto& bundle) { return bundle.empty(); }); + bin_bundles.erase(rem_it, bin_bundles.end()); + + // We tried to remove an item that doesn't exist. This should never happen + if (!removed) + { + BOOST_THROW_EXCEPTION(RemoveItemException() << bcos::errinfo_comment( + "Failed to remove item that do not exist, bundle index: " + + std::to_string(bundle_idx))); + } + } + + LABELED_PSI_LOG(INFO) << LOG_DESC("finished removing items") + << LOG_KV("bundleIndex", bundle_index); +} + +/** +Takes algebraized data to be removed, splits it up, and distributes it so that +thread_count many threads can all remove in parallel. +*/ +void dispatchRemove(std::vector>& bin_bundles, + const std::vector>& data_with_indices, + uint32_t bins_per_bundle) +{ + // Collect the bundle indices and partition them into thread_count many + // partitions. By some uniformity assumption, the number of things to remove + // per partition should be roughly the same. Note that the contents of + // bundle_indices is always sorted (increasing order). + std::set bundle_indices_set; + for (auto& data_with_idx : data_with_indices) + { + size_t cuckoo_idx = data_with_idx.second; + size_t bin_idx, bundle_idx; + std::tie(bin_idx, bundle_idx) = unpackCuckooIdx(cuckoo_idx, bins_per_bundle); + bundle_indices_set.insert(bundle_idx); + } + + std::vector bundle_indices; + bundle_indices.assign(bundle_indices_set.begin(), bundle_indices_set.end()); + + tbb::parallel_for( + tbb::blocked_range(0U, bundle_indices.size()), [&](auto const& range) { + for (auto i = range.begin(); i < range.end(); ++i) + { + auto bundleIndex = static_cast(bundle_indices[i]); + removeWorker( + bin_bundles[bundleIndex], data_with_indices, bundleIndex, bins_per_bundle); + } + }); + + LABELED_PSI_LOG(INFO) << LOG_DESC("finished all remove worker tasks"); +} + +/** +Returns a set of DB cache references corresponding to the bundles in the given +set +*/ +std::vector> collectCaches( + std::vector* bin_bundles) +{ + std::vector> result; + for (const auto& bundle : (*bin_bundles)) + { + result.emplace_back(std::cref(bundle.get_cache())); + } + + return result; +} + +SenderDB::SenderDB(const apsi::PSIParams& params, crypto::OprfServer::Ptr _oprfServer, + std::size_t label_byte_count, std::size_t nonce_byte_count, bool compressed) + : params_(params), + crypto_context_(params_), + label_byte_count_(label_byte_count), + nonce_byte_count_(nonce_byte_count), + item_count_(0), + compressed_(compressed), + m_oprfServer(std::move(_oprfServer)) +{ + // The labels cannot be more than 1 KB. + if (label_byte_count_ > MAX_LABEL_BYTE) + { + BOOST_THROW_EXCEPTION(LabelExceedsSizeException() << bcos::errinfo_comment( + "Requested label byte count exceeds the maximum (1024), count: " + + std::to_string(label_byte_count_))); + } + + if (nonce_byte_count_ > apsi::max_nonce_byte_count) + { + BOOST_THROW_EXCEPTION(NonceExceedsSizeException() << bcos::errinfo_comment( + "Requested nonce byte count exceeds the maximum (16), count: " + + std::to_string(nonce_byte_count_))); + } + + // Set the evaluator. This will be used for BatchedPlaintextPolyn::eval. + crypto_context_.set_evaluator(); + + // Reset the SenderDB data structures + clear(); +} + +SenderDB::SenderDB(SenderDB&& source) + : params_(source.params_), + crypto_context_(source.crypto_context_), + label_byte_count_(source.label_byte_count_), + nonce_byte_count_(source.nonce_byte_count_), + item_count_(source.item_count_), + compressed_(source.compressed_), + stripped_(source.stripped_), + m_oprfServer(std::move(source.m_oprfServer)) +{ + // Lock the source before moving stuff over + auto lock = source.getWriterLock(); + + hashed_items_ = std::move(source.hashed_items_); + bin_bundles_ = std::move(source.bin_bundles_); + + // Reset the source data structures + source.clearInternal(); +} + +SenderDB& SenderDB::operator=(SenderDB&& source) +{ + // Do nothing if moving to self + if (&source == this) + { + return *this; + } + + // Lock the current SenderDB + auto this_lock = getWriterLock(); + + params_ = source.params_; + crypto_context_ = source.crypto_context_; + label_byte_count_ = source.label_byte_count_; + nonce_byte_count_ = source.nonce_byte_count_; + item_count_ = source.item_count_; + compressed_ = source.compressed_; + stripped_ = source.stripped_; + m_oprfServer = std::move(source.m_oprfServer); + + // Lock the source before moving stuff over + auto source_lock = source.getWriterLock(); + + hashed_items_ = std::move(source.hashed_items_); + bin_bundles_ = std::move(source.bin_bundles_); + + // Reset the source data structures + source.clearInternal(); + + return *this; +} + +size_t SenderDB::getBinBundleCount(uint32_t bundle_idx) const +{ + // Lock the database for reading + auto lock = getReaderLock(); + + return bin_bundles_.at(seal::util::safe_cast(bundle_idx)).size(); +} + +size_t SenderDB::getBinBundleCount() const +{ + // Lock the database for reading + auto lock = getReaderLock(); + + // Compute the total number of BinBundles + return std::accumulate(bin_bundles_.cbegin(), bin_bundles_.cend(), size_t(0), + [&](auto a, auto& b) { return a + b.size(); }); +} + +double SenderDB::getPackingRate() const +{ + // Lock the database for reading + auto lock = getReaderLock(); + + uint64_t item_count = seal::util::mul_safe(static_cast(getItemCount()), + static_cast(params_.table_params().hash_func_count)); + uint64_t max_item_count = seal::util::mul_safe(static_cast(getBinBundleCount()), + static_cast(params_.items_per_bundle()), + static_cast(params_.table_params().max_items_per_bin)); + + return max_item_count ? static_cast(item_count) / static_cast(max_item_count) : + 0.0; +} + +void SenderDB::clearInternal() +{ + // Assume the SenderDB is already locked for writing + + // Clear the set of inserted items + hashed_items_.clear(); + item_count_ = 0; + + // Clear the BinBundles + bin_bundles_.clear(); + bin_bundles_.resize(params_.bundle_idx_count()); + + // Reset the stripped_ flag + stripped_ = false; +} + +void SenderDB::clear() +{ + // Lock the database for writing + auto lock = getWriterLock(); + clearInternal(); +} + +void SenderDB::generateCaches() +{ + LABELED_PSI_LOG(INFO) << LOG_DESC("start generating bin bundle caches"); + + for (auto& bundle_idx : bin_bundles_) + { + for (auto& bb : bundle_idx) + { + bb.regen_cache(); + } + } + LABELED_PSI_LOG(INFO) << LOG_DESC("finished generating bin bundle caches"); +} + +std::vector> SenderDB::getCacheAt(uint32_t bundle_idx) +{ + return collectCaches(&(bin_bundles_.at(seal::util::safe_cast(bundle_idx)))); +} + +void SenderDB::strip() +{ + // Lock the database for writing + auto lock = getWriterLock(); + + stripped_ = true; + + hashed_items_.clear(); + + uint32_t bundleSize = bin_bundles_.size(); + + tbb::parallel_for(tbb::blocked_range(0U, bundleSize), [&](auto const& range) { + for (auto i = range.begin(); i < range.end(); ++i) + { + for (auto& bb : bin_bundles_[i]) + { + bb.strip(); + } + } + }); + + LABELED_PSI_LOG(INFO) << LOG_DESC("SenderDB has been stripped"); +} + + +void SenderDB::insertOrAssign(const std::vector>& data) +{ + if (stripped_) + { + BOOST_THROW_EXCEPTION(InsertItemException() << bcos::errinfo_comment( + "Cannot insert data to a stripped SenderDB")); + } + if (!isLabeled()) + { + BOOST_THROW_EXCEPTION( + InsertItemException() << bcos::errinfo_comment( + "Attempted to insert labeled data but this is an unlabeled SenderDB")); + } + + LABELED_PSI_LOG(INFO) << LOG_DESC("start inserting items and labels in SenderDB") + << LOG_KV("count", data.size()); + + auto hashedData = + preprocessItemsAndLabels(data, label_byte_count_, nonce_byte_count_, m_oprfServer); + + doInsertOrAssign(hashedData); + + LABELED_PSI_LOG(INFO) << LOG_DESC("finished inserting items and labels in SenderDB"); +} + + +void SenderDB::insertOrAssign(ppc::io::DataBatch::Ptr _items, ppc::io::DataBatch::Ptr _labels) +{ + if (stripped_) + { + BOOST_THROW_EXCEPTION(InsertItemException() << bcos::errinfo_comment( + "Cannot insert data to a stripped SenderDB")); + } + if (!isLabeled()) + { + BOOST_THROW_EXCEPTION( + InsertItemException() << bcos::errinfo_comment( + "Attempted to insert labeled data but this is an unlabeled SenderDB")); + } + + LABELED_PSI_LOG(INFO) << LOG_DESC("start inserting items and labels in SenderDB") + << LOG_KV("count", _items->size()); + + auto hashedData = preprocessItemsAndLabels( + std::move(_items), std::move(_labels), label_byte_count_, nonce_byte_count_, m_oprfServer); + + doInsertOrAssign(hashedData); + + LABELED_PSI_LOG(INFO) << LOG_DESC("finished inserting items and labels in SenderDB"); +} + + +void SenderDB::doInsertOrAssign( + std::vector>& _hashedData) +{ + // Lock the database for writing + auto lock = getWriterLock(); + + std::vector> newData; + std::vector> reWriteData; + + for (auto itemLabelPair : _hashedData) + { + if (hashed_items_.find(itemLabelPair.first) == hashed_items_.end()) + { + hashed_items_.insert(itemLabelPair.first); + item_count_++; + newData.emplace_back(std::move(itemLabelPair)); + } + else + { + reWriteData.emplace_back(std::move(itemLabelPair)); + } + } + + // Compute the label size; this ceil(effective_label_bit_count / item_bit_count) + size_t labelSize = computeLabelSize(nonce_byte_count_ + label_byte_count_, params_); + + auto newItemCount = newData.size(); + auto existingItemCount = reWriteData.size(); + + // Dispatch the insertion, first for the new data, then for the data we're gonna overwrite + + if (existingItemCount) + { + LABELED_PSI_LOG(INFO) << LOG_DESC("found existing items to replace in SenderDB") + << LOG_KV("count", existingItemCount); + + // Break the data into field element representation. Also compute the items' + // cuckoo indices. + std::vector> data_with_indices = + transformLabeledData(reWriteData.begin(), reWriteData.end(), params_); + + dispatchInsertOrAssign(bin_bundles_, data_with_indices, crypto_context_, labelSize, params_, + /* overwrite items */ true, compressed_); + } + if (newItemCount) + { + LABELED_PSI_LOG(INFO) << LOG_DESC("found new items to replace in SenderDB") + << LOG_KV("count", newItemCount); + + // Process and add the new data. Break the data into field element + // representation. Also compute the items' cuckoo indices. + std::vector> data_with_indices = + transformLabeledData(newData.begin(), newData.end(), params_); + + dispatchInsertOrAssign(bin_bundles_, data_with_indices, crypto_context_, labelSize, params_, + /* don't overwrite items */ false, compressed_); + } + + // Generate the BinBundle caches + generateCaches(); +} + +void SenderDB::insertOrAssign(const std::vector& data) +{ + if (stripped_) + { + BOOST_THROW_EXCEPTION(InsertItemException() << bcos::errinfo_comment( + "Cannot insert item to a stripped SenderDB")); + } + if (isLabeled()) + { + BOOST_THROW_EXCEPTION(InsertItemException() << bcos::errinfo_comment( + "Attempted to insert item data but this is an labeled SenderDB")); + } + + LABELED_PSI_LOG(INFO) << LOG_DESC("start inserting items in SenderDB") + << LOG_KV("count", data.size()); + + std::vector hashedData = preprocessItems(data, m_oprfServer); + + // Lock the database for writing + auto lock = getWriterLock(); + + // We are not going to insert items that already appear in the database. + auto newDataEnd = std::remove_if(hashedData.begin(), hashedData.end(), [&](const auto& item) { + bool found = hashed_items_.find(item) != hashed_items_.end(); + if (!found) + { + // Add to hashed_items_ already at this point! + hashed_items_.insert(item); + item_count_++; + } + + // Remove those that were found + return found; + }); + + // Erase the previously existing items from hashed_data; in unlabeled case + // there is nothing to do + hashedData.erase(newDataEnd, hashedData.end()); + + LABELED_PSI_LOG(INFO) << LOG_DESC("found new items to replace in SenderDB") + << LOG_KV("count", hashedData.size()); + + // Break the new data down into its field element representation. Also compute + // the items' cuckoo indices. + std::vector> data_with_indices = + transformUnlabeledData(hashedData.begin(), hashedData.end(), params_); + + // Dispatch the insertion + dispatchInsertOrAssign(bin_bundles_, data_with_indices, crypto_context_, + /* label size */ 0, params_, /* don't overwrite items */ false, compressed_); + + // Generate the BinBundle caches + generateCaches(); + + LABELED_PSI_LOG(INFO) << LOG_DESC("finished inserting items in SenderDB"); +} + +void SenderDB::remove(const std::vector& data) +{ + if (stripped_) + { + BOOST_THROW_EXCEPTION(RemoveItemException() << bcos::errinfo_comment( + "Cannot remove data from a stripped SenderDB")); + } + + LABELED_PSI_LOG(INFO) << LOG_DESC("start removing items in SenderDB") + << LOG_KV("count", data.size()); + + std::vector hashedData = preprocessItems(data, m_oprfServer); + + // Lock the database for writing + auto lock = getWriterLock(); + + // Remove items that do not exist in the database. + std::remove_if(hashedData.begin(), hashedData.end(), [&](const auto& item) { + bool found = hashed_items_.find(item) != hashed_items_.end(); + if (found) + { + // Remove from hashed_items_ already at this point! + hashed_items_.erase(item); + item_count_--; + } + + // Remove those that were not found + return !found; + }); + + // Break the data down into its field element representation. Also compute the + // items' cuckoo indices. + std::vector> data_with_indices = + transformUnlabeledData(hashedData.begin(), hashedData.end(), params_); + + // Dispatch the removal + uint32_t bins_per_bundle = params_.bins_per_bundle(); + dispatchRemove(bin_bundles_, data_with_indices, bins_per_bundle); + + // Generate the BinBundle caches + generateCaches(); + + LABELED_PSI_LOG(INFO) << LOG_DESC("finished removing items in SenderDB"); +} + +bool SenderDB::hasItem(const apsi::Item& item) const +{ + if (stripped_) + { + BOOST_THROW_EXCEPTION( + RetrieveItemException() << bcos::errinfo_comment( + "Cannot retrieve the presence of an item from a stripped SenderDB")); + } + + std::string itemStr(item.value().size(), 0); + std::memcpy(&itemStr[0], item.value().data(), item.value().size()); + + bcos::bytes oprfOut = m_oprfServer->fullEvaluate(itemStr); + + apsi::HashedItem hashedItem; + std::memcpy(hashedItem.value().data(), oprfOut.data(), hashedItem.value().size()); + + // Lock the database for reading + auto lock = getReaderLock(); + + return hashed_items_.find(hashedItem) != hashed_items_.end(); +} + +apsi::Label SenderDB::getLabel(const apsi::Item& item) const +{ + if (stripped_) + { + BOOST_THROW_EXCEPTION( + RetrieveLabelException() << bcos::errinfo_comment( + "Cannot retrieve the presence of a label from a stripped SenderDB")); + } + if (!isLabeled()) + { + BOOST_THROW_EXCEPTION( + RetrieveLabelException() << bcos::errinfo_comment( + "Attempted to retrieve a label but this is an unlabeled SenderDB")); + } + + std::string itemStr(item.value().size(), 0); + std::memcpy(&itemStr[0], item.value().data(), item.value().size()); + + bcos::bytes oprfOut = m_oprfServer->fullEvaluate(itemStr); + + apsi::HashedItem hashedItem; + std::memcpy(hashedItem.value().data(), oprfOut.data(), hashedItem.value().size()); + + // Lock the database for reading + auto lock = getReaderLock(); + + // Check if this item is in the DB. If not, throw an exception + if (hashed_items_.find(hashedItem) == hashed_items_.end()) + { + BOOST_THROW_EXCEPTION(RetrieveLabelException() << bcos::errinfo_comment( + "Cannot retrieve label for an item that is not in the SenderDB")); + } + + uint32_t bins_per_bundle = params_.bins_per_bundle(); + + // Preprocess a single element. This algebraizes the item and gives back its + // field element representation as well as its cuckoo hash. We only read one + // of the locations because the labels are the same in each location. + apsi::util::AlgItem alg_item; + size_t cuckoo_idx; + std::tie(alg_item, cuckoo_idx) = transformUnlabeledData(hashedItem, params_)[0]; + + // Now figure out where to look to get the label + size_t bin_idx, bundle_idx; + std::tie(bin_idx, bundle_idx) = unpackCuckooIdx(cuckoo_idx, bins_per_bundle); + + // Retrieve the algebraic labels from one of the BinBundles at this index + const std::vector& bundle_set = bin_bundles_[bundle_idx]; + std::vector alg_label; + bool got_labels = false; + for (const BinBundle& bundle : bundle_set) + { + // Try to retrieve the contiguous labels from this BinBundle + if (bundle.try_get_multi_label(alg_item, bin_idx, alg_label)) + { + got_labels = true; + break; + } + } + + // It shouldn't be possible to have items in your set but be unable to + // retrieve the associated label. Throw an exception because something is + // terribly wrong. + if (!got_labels) + { + BOOST_THROW_EXCEPTION( + RetrieveLabelException() << bcos::errinfo_comment( + "Failed to retrieve label for an item that was supposed to be in the SenderDB")); + } + + // All good. Now just reconstruct the big label from its split-up parts + apsi::EncryptedLabel encrypted_label = dealgebraize_label(alg_label, + alg_label.size() * static_cast(params_.item_bit_count_per_felt()), + params_.seal_params().plain_modulus()); + + // Resize down to the effective byte count + encrypted_label.resize(nonce_byte_count_ + label_byte_count_); + + apsi::LabelKey key; + std::memcpy(key.data(), oprfOut.data() + hashedItem.value().size(), key.size()); + + // Decrypt the label + return decrypt_label(encrypted_label, key, nonce_byte_count_); +} + +/** +Writes the SenderDB bytes +*/ +void SenderDB::saveToBytes(bcos::bytes& _out) const +{ + // Lock the database for reading + auto lock = getReaderLock(); + LABELED_PSI_LOG(INFO) << LOG_DESC("start saving SenderDB"); + + ppctars::SenderDB tarsSenderDB; + for (auto& hashedItems : hashed_items_) + { + bcos::bytes item(sizeof(apsi::Item::value_type)); + std::memcpy(item.data(), hashedItems.value().data(), sizeof(apsi::Item::value_type)); + tarsSenderDB.hashedItems.emplace_back(item); + } + tarsSenderDB.psiParams = fromPSIParams(params_, 0); + tarsSenderDB.oprfKey = m_oprfServer->privateKey(); + tarsSenderDB.stripped = stripped_; + tarsSenderDB.compressed = compressed_; + tarsSenderDB.itemCount = item_count_; + tarsSenderDB.nonceByteCount = nonce_byte_count_; + tarsSenderDB.labelByteCount = label_byte_count_; + + for (auto& binBundles : bin_bundles_) + { + std::vector tarsBinBundles; + tarsBinBundles.reserve(binBundles.size()); + for (auto& binBundle : binBundles) + { + tarsBinBundles.emplace_back(binBundle.saveToTarsBinBundle()); + } + tarsSenderDB.binBundles.emplace_back(tarsBinBundles); + } + + _out.clear(); + ppctars::serialize::encode(tarsSenderDB, _out); + + LABELED_PSI_LOG(INFO) << LOG_DESC("finish saving SenderDB"); +} + +/** +Reads the SenderDB from bytes. +*/ +SenderDB::Ptr SenderDB::loadFromBytes(crypto::OprfServer::Ptr _oprfServer, const bcos::bytes& _in) +{ + LABELED_PSI_LOG(INFO) << LOG_DESC("start loading SenderDB"); + + ppctars::SenderDB tarsSenderDB; + ppctars::serialize::decode(_in, tarsSenderDB); + + _oprfServer->setPrivateKey(tarsSenderDB.oprfKey); + SenderDB::Ptr ret = + std::make_shared(toPSIParams(tarsSenderDB.psiParams), std::move(_oprfServer), + tarsSenderDB.labelByteCount, tarsSenderDB.nonceByteCount, tarsSenderDB.compressed); + + ret->stripped_ = tarsSenderDB.stripped; + ret->item_count_ = tarsSenderDB.itemCount; + for (auto& tarsHashedItems : tarsSenderDB.hashedItems) + { + apsi::HashedItem hashedItem; + std::memcpy(hashedItem.value().data(), tarsHashedItems.data(), hashedItem.value().size()); + ret->hashed_items_.insert(hashedItem); + } + + ret->bin_bundles_.clear(); + for (auto& tarsBinBundles : tarsSenderDB.binBundles) + { + std::vector binBundles; + binBundles.reserve(tarsBinBundles.size()); + for (auto& tarsBinBundle : tarsBinBundles) + { + binBundles.emplace_back( + BinBundle::loadFromTarsBinBundle(ret->crypto_context_, tarsBinBundle)); + } + ret->bin_bundles_.emplace_back(std::move(binBundles)); + } + + LABELED_PSI_LOG(INFO) << LOG_DESC("finish loading SenderDB"); + return ret; +} \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-psi/src/labeled-psi/core/SenderDB.h b/cpp/wedpr-computing/ppc-psi/src/labeled-psi/core/SenderDB.h new file mode 100644 index 00000000..a84c6935 --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/labeled-psi/core/SenderDB.h @@ -0,0 +1,374 @@ +/** + * Copyright (C) 2022 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. + * + * @reference https://github.com/microsoft/APSI/sender/sender_db.h + * @license MIT license + * @change optimize the implementation of some functions & replace the instance of oprf + * + * @file SenderDB.h + * @author: shawnhe + * @date 2022-11-7 + * + */ + +#pragma once + +// STD +#include +#include +#include +#include +#include +#include +#include +#include + +// GSL +#include + +// APSI +#include +#include +#include + +// SEAL +#include "seal/plaintext.h" +#include "seal/util/locks.h" + + +#include "ppc-framework/crypto/Oprf.h" + +#include "ppc-framework/io/DataBatch.h" + +#include "../protocol/Protocol.h" +#include "BinBundle.h" +#include "SenderCache.h" +#include "wedpr-protocol/tars/TarsSerialize.h" + +namespace ppc::psi +{ +/** +A SenderDB maintains an in-memory representation of the sender's set of items +and labels (in labeled mode). This data is not simply copied into the SenderDB +data structures, but also preprocessed heavily to allow for faster online +computation time. Since inserting a large number of new items into a SenderDB +can take time, it is not recommended to recreate the SenderDB when the database +changes a little bit. Instead, the class supports fast update and deletion +operations that should be preferred: SenderDB::InsertOrAssign and +SenderDB::remove. + +The SenderDB constructor allows the label byte count to be specified; unlabeled +mode is activated by setting the label byte count to zero. It is possible to +optionally specify the size of the nonce used in encrypting the labels, but this +is best left to its default value unless the user is absolutely sure of what +they are doing. + +The SenderDB requires substantially more memory than the raw data would. Part of +that memory can automatically be compressed when it is not in use; this feature +is enabled by default, and can be disabled when constructing the SenderDB. The +downside of in-memory compression is a performance reduction from decompressing +parts of the data when they are used, and recompressing them if they are +updated. +*/ + +class SenderDB : public std::enable_shared_from_this +{ +public: + using Ptr = std::shared_ptr; + virtual ~SenderDB() = default; + + /** + Creates a new SenderDB. + */ + SenderDB(const apsi::PSIParams& params, crypto::OprfServer::Ptr _oprfServer, + std::size_t label_byte_count = 0, std::size_t nonce_byte_count = 16, + bool compressed = true); + /** + Creates a new SenderDB by moving from an existing one. + */ + SenderDB(SenderDB&& source); + + /** + Moves an existing SenderDB to the current one. + */ + SenderDB& operator=(SenderDB&& source); + + /** + Clears the database. Every item and label will be removed. The OPRF key is + unchanged. + */ + void clear(); + + /** + Returns whether this is a labeled SenderDB. + */ + bool isLabeled() const { return 0 != label_byte_count_; } + + /** + Returns the label byte count. A zero value indicates an unlabeled SenderDB. + */ + std::size_t getLabelByteCount() const { return label_byte_count_; } + + /** + Returns the nonce byte count used for encrypting labels. + */ + std::size_t getNonceByteCount() const { return nonce_byte_count_; } + + /** + Indicates whether SEAL plaintexts are compressed in memory. + */ + bool isCompressed() const { return compressed_; } + + /** + Indicates whether the SenderDB has been stripped of all information not needed + for serving a query. + */ + bool isStripped() const { return stripped_; } + + /** + Strips the SenderDB of all information not needed for serving a query. Returns + a copy of the OPRF key and clears it from the SenderDB. + */ + void strip(); + + /** + Inserts the given data into the database. This function can be used only on a + labeled SenderDB instance. If an item already exists in the database, its + label is overwritten with the new label. + */ + void insertOrAssign(const std::vector>& data); + + void insertOrAssign(ppc::io::DataBatch::Ptr _items, ppc::io::DataBatch::Ptr _labels); + + // hashedData will be cleared + void doInsertOrAssign( + std::vector>& _hashedData); + + /** + Inserts the given (hashed) item-label pair into the database. This function + can be used only on a labeled SenderDB instance. If the item already exists in + the database, its label is overwritten with the new label. + */ + void insertOrAssign(const std::pair& data) + { + std::vector> data_singleton{data}; + insertOrAssign(data_singleton); + } + + /** + Inserts the given data into the database. This function can be used only on an + unlabeled SenderDB instance. + */ + void insertOrAssign(const std::vector& data); + + /** + Inserts the given (hashed) item into the database. This function can be used + only on an unlabeled SenderDB instance. + */ + void insertOrAssign(const apsi::Item& data) + { + std::vector data_singleton{data}; + insertOrAssign(data_singleton); + } + + /** + Clears the database and inserts the given data. This function can be used only + on a labeled SenderDB instance. + */ + void setData(const std::vector>& data) + { + clear(); + insertOrAssign(data); + } + + void setData(ppc::io::DataBatch::Ptr _items, ppc::io::DataBatch::Ptr _labels) + { + clear(); + insertOrAssign(std::move(_items), std::move(_labels)); + } + + /** + Clears the database and inserts the given data. This function can be used only + on an unlabeled SenderDB instance. + */ + void setData(const std::vector& data) + { + clear(); + insertOrAssign(data); + } + + /** + Removes the given data from the database, using at most thread_count threads. + */ + void remove(const std::vector& data); + + /** + Removes the given (hashed) item from the database. + */ + void remove(const apsi::Item& data) + { + std::vector data_singleton{data}; + remove(data_singleton); + } + + /** + Returns whether the given item has been inserted in the SenderDB. + */ + bool hasItem(const apsi::Item& item) const; + + /** + Returns the label associated to the given item in the database. Throws + std::invalid_argument if the item does not appear in the database. + */ + apsi::Label getLabel(const apsi::Item& item) const; + + /** + Returns a set of cache references corresponding to the bundles at the given + bundle index. Even though this function returns a vector, the order has no + significance. This function is meant for internal use. + */ + auto getCacheAt(std::uint32_t bundle_idx) + -> std::vector>; + + /** + Returns a reference to the PSI parameters for this SenderDB. + */ + const apsi::PSIParams& getParams() const { return params_; } + + /** + Returns a reference to the CryptoContext for this SenderDB. + */ + const apsi::CryptoContext& getCryptoContext() const { return crypto_context_; } + + /** + Returns a reference to the SEALContext for this SenderDB. + */ + std::shared_ptr getSealContext() const + { + return crypto_context_.seal_context(); + } + + /** + Returns a reference to a set of item hashes already existing in the SenderDB. + */ + const std::unordered_set& getHashedItems() const { return hashed_items_; } + + /** + Returns the number of items in this SenderDB. + */ + size_t getItemCount() const { return item_count_; } + + /** + Returns the total number of bin bundles at a specific bundle index. + */ + std::size_t getBinBundleCount(std::uint32_t bundle_idx) const; + + /** + Returns the total number of bin bundles. + */ + std::size_t getBinBundleCount() const; + + /** + Returns how efficiently the SenderDB is packaged. A higher rate indicates + better performance and a lower communication cost in a query execution. + */ + double getPackingRate() const; + + /** + Obtains a scoped lock preventing the SenderDB from being changed. + */ + seal::util::ReaderLock getReaderLock() const { return db_lock_.acquire_read(); } + + /** + Writes the SenderDB bytes + */ + void saveToBytes(bcos::bytes& _out) const; + + /** + Reads the SenderDB from bytes. + */ + static SenderDB::Ptr loadFromBytes(crypto::OprfServer::Ptr _oprfServer, const bcos::bytes& _in); + +private: + SenderDB(const SenderDB& copy) = delete; + + seal::util::WriterLock getWriterLock() { return db_lock_.acquire_write(); } + + void clearInternal(); + + void generateCaches(); + + /** + The set of all items that have been inserted into the database + */ + std::unordered_set hashed_items_; + + /** + The PSI parameters define the SEAL parameters, base field, item size, table + size, etc. + */ + apsi::PSIParams params_; + + /** + Necessary for evaluating polynomials of Plaintexts. + */ + apsi::CryptoContext crypto_context_; + + /** + A read-write lock to protect the database from modification while in use. + */ + mutable seal::util::ReaderWriterLocker db_lock_; + + /** + Indicates the size of the label in bytes. A zero value indicates an unlabeled + SenderDB. + */ + std::size_t label_byte_count_; + + /** + Indicates the number of bytes of the effective label reserved for a randomly + sampled nonce. The effective label byte count is the sum of label_byte_count + and nonce_byte_count. The value can range between 0 and 16. If + label_byte_count is zero, nonce_byte_count has no effect. + */ + std::size_t nonce_byte_count_; + + /** + The number of items currently in the SenderDB. + */ + std::size_t item_count_; + + /** + Indicates whether SEAL plaintexts are compressed in memory. + */ + bool compressed_; + + /** + Indicates whether the SenderDB has been stripped of all information not needed + for serving a query. + */ + bool stripped_; + + /** + All the BinBundles in the database, indexed by bundle index. The set + (represented by a vector internally) at bundle index i contains all the + BinBundles with bundle index i. + */ + std::vector> bin_bundles_; + + crypto::OprfServer::Ptr m_oprfServer; +}; // class SenderDB + +} // namespace ppc::psi diff --git a/cpp/wedpr-computing/ppc-psi/src/labeled-psi/core/TaskCommand.h b/cpp/wedpr-computing/ppc-psi/src/labeled-psi/core/TaskCommand.h new file mode 100644 index 00000000..dd830896 --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/labeled-psi/core/TaskCommand.h @@ -0,0 +1,95 @@ +/** + * Copyright (C) 2022 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 TaskCommand.h + * @author: shawnhe + * @date 2022-11-14 + */ + +#pragma once +#include "../Common.h" +#include +#include + +namespace ppc::psi +{ +class TaskCommand +{ +public: + using Ptr = std::shared_ptr; + TaskCommand(std::string_view _param) + { + Json::Reader reader; + Json::Value result; + if (!reader.parse(_param.begin(), _param.end(), result)) + { + BOOST_THROW_EXCEPTION(BCOS_ERROR( + (int)LabeledPSIRetCode::INVALID_TASK_PARAM, "invalid task param: invalid json")); + } + if (!result.isArray() || result.empty()) + { + BOOST_THROW_EXCEPTION(BCOS_ERROR((int)LabeledPSIRetCode::INVALID_TASK_PARAM, + "invalid task param:: the param must be array")); + } + auto command = result[0].asString(); + if (command == CMD_SETUP_SENDER_DB) + { + m_command = (int)LabeledPSICommand::SETUP_SENDER_DB; + if (result.size() < 2) + { + BOOST_THROW_EXCEPTION(BCOS_ERROR((int)LabeledPSIRetCode::INVALID_TASK_PARAM, + "must set label_byte_count for command: " + command)); + } + m_args.emplace_back(std::stoi(result[1].asString())); + } + else if (command == CMD_RUN_LABELED_PSI) + { + m_command = (int)LabeledPSICommand::RUN_LABELED_PSI; + } + else if (command == CMD_SAVE_SENDER_CACHE) + { + m_command = (int)LabeledPSICommand::SAVE_SENDER_CACHE; + } + else if (command == CMD_LOAD_SENDER_CACHE) + { + m_command = (int)LabeledPSICommand::LOAD_SENDER_CACHE; + } + else if (command == CMD_ADD_ITEMS) + { + m_command = (int)LabeledPSICommand::ADD_ITEMS; + } + else if (command == CMD_DELETE_ITEMS) + { + m_command = (int)LabeledPSICommand::DELETE_ITEMS; + } + else if (command == CMD_UPDATE_LABELS) + { + m_command = (int)LabeledPSICommand::UPDATE_LABELS; + } + else + { + BOOST_THROW_EXCEPTION(BCOS_ERROR( + (int)LabeledPSIRetCode::UNDEFINED_COMMAND, "unsupported command: " + command)); + } + } + + int command() const { return m_command; } + std::vector const& args() const { return m_args; } + +private: + int m_command; + std::vector m_args; +}; +} // namespace ppc::psi diff --git a/cpp/wedpr-computing/ppc-psi/src/labeled-psi/protocol/LabeledPSI.tars b/cpp/wedpr-computing/ppc-psi/src/labeled-psi/protocol/LabeledPSI.tars new file mode 100644 index 00000000..28fb7935 --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/labeled-psi/protocol/LabeledPSI.tars @@ -0,0 +1,45 @@ +module ppctars { + struct SealParams { + 1 require unsigned int polyModulusDegree; + 2 require unsigned int plainModulus; + 3 require vector coeffModulus; + }; + + struct PsiParams + { + 1 require unsigned int hashFuncCount; + 2 require unsigned int tableSize; + 3 require unsigned int maxItemsPerBin; + 4 require unsigned int feltsPerItem; + 5 require unsigned int psLowDegree; + 6 require vector queryPowers; + 7 require SealParams sealParams; + 8 require unsigned int binBundleCount; + }; + + struct OprfData + { + 1 require vector> data; + }; + + struct EncryptedPowers + { + 1 require unsigned int power; + 2 require vector> ciphertexts; + }; + + struct QueryRequest + { + 1 require vector relinKeys; + 2 require vector encryptedPowers; + }; + + struct QueryResponse + { + 1 require unsigned int bundleIdx; + 2 require vector ciphertext; + 3 require unsigned int labelByteCount; + 4 require unsigned int nonceByteCount; + 5 require vector> labelResults; + }; +}; diff --git a/cpp/wedpr-computing/ppc-psi/src/labeled-psi/protocol/LabeledPSIResult.h b/cpp/wedpr-computing/ppc-psi/src/labeled-psi/protocol/LabeledPSIResult.h new file mode 100644 index 00000000..bc0dc1de --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/labeled-psi/protocol/LabeledPSIResult.h @@ -0,0 +1,93 @@ +/** + * Copyright (C) 2022 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 LabeledPSIResult.h + * @author: shawnhe + * @date 2022-11-13 + */ +#pragma once + +#include +#include +#include +#include +#include +#include + +#include "ppc-framework/protocol/Task.h" + +namespace ppc::psi +{ +// Note: can extend on demand +class LabeledPSIResult : public protocol::TaskResult +{ +public: + using Ptr = std::shared_ptr; + LabeledPSIResult(std::string const& _taskID) : TaskResult(_taskID) {} + virtual ~LabeledPSIResult() = default; + + + void setOutputs(std::vector>&& _outputs) + { + m_outputs = std::move(_outputs); + } + + const std::vector>& getOutputs() { return m_outputs; } + + // serialize the taskResult to json + Json::Value serializeToJson() override + { + Json::Value response; + response["taskID"] = taskID(); + if (m_timeCost) + { + response["timeCost"] = std::to_string(m_timeCost) + "ms"; + } + if (error() && error()->errorCode()) + { + response["code"] = error()->errorCode(); + response["message"] = error()->errorMessage(); + response["status"] = protocol::toString(protocol::TaskStatus::FAILED); + } + else + { + response["code"] = 0; + response["message"] = "success"; + response["status"] = protocol::toString(protocol::TaskStatus::COMPLETED); + } + if (!m_outputs.empty()) + { + Json::Value jsonOutputs; + for (auto& outputVector : m_outputs) + { + Json::Value jsonOutput; + for (auto& output : outputVector) + { + jsonOutput.append(output); + } + jsonOutputs.append(jsonOutput); + } + Json::Value jsonData; + jsonData["outputs"] = jsonOutputs; + response["data"] = jsonData; + } + return response; + } + +private: + std::vector> m_outputs; +}; + +} // namespace ppc::psi diff --git a/cpp/wedpr-computing/ppc-psi/src/labeled-psi/protocol/Protocol.h b/cpp/wedpr-computing/ppc-psi/src/labeled-psi/protocol/Protocol.h new file mode 100644 index 00000000..4ef3aa02 --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/labeled-psi/protocol/Protocol.h @@ -0,0 +1,102 @@ +/** + * Copyright (C) 2022 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 Protocol.h + * @author: shawnhe + * @date 2022-11-6 + */ + +#pragma once +#include "LabeledPSI.h" +#include "ppc-framework/Common.h" + +#include +#include + +#include + +namespace ppc::psi +{ +inline apsi::PSIParams toPSIParams(const ppctars::PsiParams& _tarsParams) +{ + apsi::PSIParams::ItemParams itemParams{}; + apsi::PSIParams::TableParams tableParams{}; + apsi::PSIParams::QueryParams queryParams; + apsi::PSIParams::SEALParams sealParams; + + itemParams.felts_per_item = _tarsParams.feltsPerItem; + + tableParams.hash_func_count = _tarsParams.hashFuncCount; + tableParams.table_size = _tarsParams.tableSize; + tableParams.max_items_per_bin = _tarsParams.maxItemsPerBin; + + queryParams.ps_low_degree = _tarsParams.psLowDegree; + + if (!_tarsParams.queryPowers.empty()) + { + for (auto queryPower : _tarsParams.queryPowers) + { + queryParams.query_powers.insert(queryPower); + } + } + else + { + for (uint idx = 1; idx <= tableParams.max_items_per_bin; ++idx) + { + queryParams.query_powers.insert(idx); + } + } + + std::vector coeffModulus; + coeffModulus.insert(coeffModulus.end(), _tarsParams.sealParams.coeffModulus.begin(), + _tarsParams.sealParams.coeffModulus.end()); + + sealParams.set_coeff_modulus(coeffModulus); + sealParams.set_poly_modulus_degree(_tarsParams.sealParams.polyModulusDegree); + sealParams.set_plain_modulus(_tarsParams.sealParams.plainModulus); + + apsi::PSIParams psiParams(itemParams, tableParams, queryParams, sealParams); + return psiParams; +} + +inline ppctars::PsiParams fromPSIParams(const apsi::PSIParams& _psiParams, uint32_t _binBundleCount) +{ + ppctars::PsiParams tarsParams; + tarsParams.hashFuncCount = _psiParams.table_params().hash_func_count; + tarsParams.tableSize = _psiParams.table_params().table_size; + tarsParams.maxItemsPerBin = _psiParams.table_params().max_items_per_bin; + + tarsParams.feltsPerItem = _psiParams.item_params().felts_per_item; + + tarsParams.psLowDegree = _psiParams.query_params().ps_low_degree; + for (auto& power : _psiParams.query_params().query_powers) + { + tarsParams.queryPowers.emplace_back(power); + } + + ppctars::SealParams tarsSealParams; + tarsSealParams.plainModulus = _psiParams.seal_params().plain_modulus().value(); + tarsSealParams.polyModulusDegree = _psiParams.seal_params().poly_modulus_degree(); + for (auto& modulu : _psiParams.seal_params().coeff_modulus()) + { + tarsSealParams.coeffModulus.emplace_back(modulu.value()); + } + tarsParams.sealParams = tarsSealParams; + + tarsParams.binBundleCount = _binBundleCount; + return tarsParams; +} + +} // namespace ppc::psi diff --git a/cpp/wedpr-computing/ppc-psi/src/labeled-psi/protocol/SenderCache.tars b/cpp/wedpr-computing/ppc-psi/src/labeled-psi/protocol/SenderCache.tars new file mode 100644 index 00000000..76e7f5f0 --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/labeled-psi/protocol/SenderCache.tars @@ -0,0 +1,42 @@ +#include "LabeledPSI.tars" +module ppctars { + struct BatchedPlaintextPolyn + { + 1 require vector> batchedCoeffs; + }; + + struct BinBundleCache + { + 1 require vector> feltMatchingPolyns; + 2 require vector>> feltInterpPolyns; + 3 require BatchedPlaintextPolyn batchedMatchingPolyn; + 4 require vector batchedInterpPolyns; + }; + + struct BinBundle + { + 1 require bool cacheInvalid; + 2 require bool compressed; + 3 require bool stripped; + 4 require vector> itemBins; + 5 require vector>> labelBins; + 6 require BinBundleCache cache; + 7 require unsigned int labelSize; + 8 require unsigned int maxBinSize; + 9 require unsigned int psLowDegree; + 10 require unsigned int numBins; + }; + + struct SenderDB + { + 1 require vector oprfKey; + 2 require vector> binBundles; + 3 require bool stripped; + 4 require bool compressed; + 5 require unsigned int itemCount; + 6 require unsigned int nonceByteCount; + 7 require unsigned int labelByteCount; + 8 require vector> hashedItems; + 9 require PsiParams psiParams; + }; +}; diff --git a/cpp/wedpr-computing/ppc-psi/src/psi-framework/CMakeLists.txt b/cpp/wedpr-computing/ppc-psi/src/psi-framework/CMakeLists.txt new file mode 100644 index 00000000..74d893ce --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/psi-framework/CMakeLists.txt @@ -0,0 +1,29 @@ +# for tars generator +set(TARS_HEADER_DIR ${CMAKE_BINARY_DIR}/generated/ppc-psi/psi/tars) +find_program(TARS_TARS2CPP tars2cpp REQUIRED) + +file(GLOB_RECURSE TARS_INPUT "*.tars") +# generate tars +if(TARS_INPUT) + foreach(TARS_FILE ${TARS_INPUT}) + get_filename_component(TARS_NAME ${TARS_FILE} NAME_WE) + get_filename_component(TARS_PATH ${TARS_FILE} PATH) + add_custom_command( + OUTPUT ${TARS_HEADER_DIR}/${TARS_NAME}.h + WORKING_DIRECTORY ${TARS_PATH} + COMMAND ${TARS_TARS2CPP} ${TARS_FILE} --unjson --without-trace --dir=${TARS_HEADER_DIR} + COMMENT "generating ${TARS_FILE} to ${TARS_HEADER_DIR}" + VERBATIM + ) + + list(APPEND OUT_TARS_H_LIST ${TARS_HEADER_DIR}/${TARS_NAME}.h) + endforeach() +endif() +set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${OUT_TARS_H_LIST}") +include_directories(${TARS_HEADER_DIR}) + +file(GLOB_RECURSE SRCS *.cpp) +add_library(${PSI_FRAMEWORK_TARGET} ${SRCS} ${OUT_TARS_H_LIST}) +target_include_directories(${PSI_FRAMEWORK_TARGET} PUBLIC + $) +target_link_libraries(${PSI_FRAMEWORK_TARGET} PUBLIC TCMalloc ${FRONT_TARGET} ${PROTOCOL_TARGET} ${TARS_PROTOCOL_TARGET} ${IO_TARGET}) diff --git a/cpp/wedpr-computing/ppc-psi/src/psi-framework/PSIFramework.cpp b/cpp/wedpr-computing/ppc-psi/src/psi-framework/PSIFramework.cpp new file mode 100644 index 00000000..c7dbc3e1 --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/psi-framework/PSIFramework.cpp @@ -0,0 +1,770 @@ +/* + * Copyright (C) 2022 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 PSIFramework.cpp + * @author: yujiechen + * @date 2022-12-26 + */ +#include "PSIFramework.h" +#include "../Common.h" +#include "ppc-framework/protocol/Constant.h" +#include "ppc-framework/protocol/GlobalConfig.h" + +using namespace ppc::task; +using namespace ppc::psi; +using namespace ppc::io; +using namespace ppc::protocol; +using namespace bcos; +using namespace ppc::front; + +void PSIFramework::start() +{ + if (m_started) + { + PSI_FRAMEWORK_LOG(WARNING) << LOG_DESC("The PSI has already been started"); + return; + } + m_started = true; + m_taskSyncTimer->registerTimeoutHandler([this]() { syncTaskInfo(); }); + m_taskSyncTimer->start(); + PSI_FRAMEWORK_LOG(INFO) << LOG_DESC("Start the PSI"); + // start a thread to execute task + startWorking(); +} + +void PSIFramework::stop() +{ + if (m_started == false) + { + return; + } + PSI_FRAMEWORK_LOG(INFO) << LOG_DESC("Stop PSI"); + m_started = false; + if (m_taskSyncTimer) + { + m_taskSyncTimer->stop(); + } + finishWorker(); + if (isWorking()) + { + // stop the worker thread + stopWorking(); + terminate(); + } + PSI_FRAMEWORK_LOG(INFO) << LOG_DESC("PSI stopped"); +} + +void PSIFramework::executeWorker() +{ + handleLocalTask(); + checkAndNotifyTaskResult(); + auto result = m_msgQueue->tryPop(c_PopWaitMs); + if (result.first) + { + handlePSIMsg(result.second); + return; + } + waitSignal(); +} + +// handle the local task +void PSIFramework::handleLocalTask() +{ + bcos::ReadGuard l(x_pendingTasks); + if (m_pendingTasks.empty()) + { + return; + } + for (auto const& it : m_pendingTasks) + { + if (it.second->finished()) + { + continue; + } + // Note: executeWork should not occupy too-much time + it.second->executeWork(); + } +} + + +// check the task-finished-or-not and response the result of the finished task +void PSIFramework::checkAndNotifyTaskResult() +{ + std::set erasedResourceID; + { + bcos::UpgradableGuard l(x_pendingTasks); + // with-no-task + if (m_pendingTasks.empty()) + { + return; + } + for (auto it = m_pendingTasks.begin(); it != m_pendingTasks.end();) + { + auto taskState = it->second; + if (!taskState->finished()) + { + it++; + continue; + } + // notify the result to peer + auto dataResource = (taskState->task()->selfParty()->dataResource()); + if (dataResource) + { + erasedResourceID.insert(dataResource->resourceID()); + } + { + bcos::UpgradeGuard ul(l); + it = m_pendingTasks.erase(it); + } + notifyTaskResult(nullptr, taskState->peerID(), taskState->task()->id(), + dataResource ? dataResource->resourceID() : ""); + // notify the result to rpc response + taskState->onTaskFinished(); + } + } + // clear the dataResourceInfo related to the finished-task + batchRemoveDataResource(erasedResourceID); +} + +// Note: we should not block this function too much time +void PSIFramework::onReceiveMessage(PPCMessageFace::Ptr _msg) +{ + try + { + // decode the psi message and put it into to m_msgQueue + auto payLoad = _msg->data(); + auto psiMsg = + m_msgFactory->decodePSIMessage(bcos::bytesConstRef(payLoad->data(), payLoad->size())); + psiMsg->setFrom(_msg->sender()); + psiMsg->setTaskID(_msg->taskID()); + psiMsg->setSeq(_msg->seq()); + psiMsg->setUUID(_msg->uuid()); + psiMsg->setFromNode(_msg->senderNode()); + m_msgQueue->push(psiMsg); + PSI_FRAMEWORK_LOG(TRACE) << LOG_DESC("onReceiveMessage") << printPSIMessage(psiMsg) + << LOG_KV("uuid", _msg->uuid()); + // release the large payload immediately + if (payLoad && payLoad->size() >= ppc::protocol::LARGE_MSG_THRESHOLD) + { + PSI_FRAMEWORK_LOG(INFO) + << LOG_DESC("Release large message payload") << LOG_KV("size", payLoad->size()); + _msg->releasePayload(); + MallocExtension::instance()->ReleaseFreeMemory(); + } + // notify to handle the message + m_signalled.notify_all(); + } + catch (std::exception const& e) + { + PSI_FRAMEWORK_LOG(WARNING) << LOG_DESC("onReceiveMessage exception") << printPPCMsg(_msg) + << LOG_KV("error", boost::diagnostic_information(e)) + << LOG_KV("msgSize", _msg->data()->size()); + } +} + +void PSIFramework::onTaskError(std::string const& _desc, bcos::Error::Ptr&& _error, + std::string const& _peerID, std::string const& _taskID, std::string const& _resourceID) +{ + if (!_error) + { + PSI_FRAMEWORK_LOG(DEBUG) << LOG_DESC(_desc) << LOG_KV("peer", _peerID) + << LOG_KV("task", _taskID) << LOG_KV("resource", _resourceID); + return; + } + PSI_FRAMEWORK_LOG(WARNING) << LOG_DESC(_desc) << " error" << LOG_KV("peer", _peerID) + << LOG_KV("task", _taskID) << LOG_KV("resource", _resourceID) + << LOG_KV("code", _error->errorCode()) + << LOG_KV("msg", _error->errorMessage()); + // notify the peer that the task has been canceled + notifyTaskResult(_error, _peerID, _taskID, _resourceID); + // cancel the task + cancelTask(std::move(_error), _taskID); +} + + +// cancel the task and response to the user when error happens +void PSIFramework::cancelTask(bcos::Error::Ptr&& _error, std::string const& _task) +{ + PSI_FRAMEWORK_LOG(INFO) << LOG_DESC("cancelTask") << LOG_KV("task", _task) + << LOG_KV("code", _error->errorCode()) + << LOG_KV("msg", _error->errorMessage()); + TaskResponseCallback callback = nullptr; + std::function finalizeCallback = nullptr; + TaskState::Ptr taskState = nullptr; + { + // get and delete the pending-tasks + UpgradableGuard l(x_pendingTasks); + auto it = m_pendingTasks.find(_task); + // find in the pending-task + if (it != m_pendingTasks.end()) + { + taskState = it->second; + UpgradeGuard ul(l); + // take the callback in-case-of the callback been called more than once + callback = it->second->takeCallback(); + finalizeCallback = it->second->takeFinalizeHandler(); + // erase from the pending-tasks + m_pendingTasks.erase(it); + } + } + if (taskState && taskState->task()->selfParty()->dataResource()) + { + removeLockingResource(taskState->task()->selfParty()->dataResource()->resourceID()); + } + { + PSI_FRAMEWORK_LOG(INFO) << LOG_DESC("cancelTask: response task result") + << LOG_KV("task", _task) << LOG_KV("code", _error->errorCode()) + << LOG_KV("msg", _error->errorMessage()); + auto taskResult = std::make_shared(_task); + taskResult->setError(_error); + try + { + // calls the finalizeCallback to finalize when task failed + // make sure the resource has been released when the task failed + if (finalizeCallback) + { + finalizeCallback(); + } + + if (taskState) + { + auto reader = taskState->reader(); + if (reader) + { + reader->clean(); + } + + auto writer = taskState->writer(); + if (writer) + { + writer->clean(); + } + + if (writer && !_error->errorCode()) + { + writer->upload(); + } + } + } + catch (std::exception const& e) + { + PSI_LOG(WARNING) << LOG_DESC("cancelTask exception") + << LOG_KV("msg", boost::diagnostic_information(e)); + auto error = std::make_shared(-1, boost::diagnostic_information(e)); + taskResult->setError(std::move(error)); + } + if (callback) + { + callback(std::move(taskResult)); + } + } +} + +bool PSIFramework::checkDataResourceForSelf( + TaskState::Ptr const& _taskState, std::string const& _peerID, bool _requireOutput) +{ + auto task = _taskState->task(); + auto dataResource = task->selfParty()->dataResource(); + // check the dataResource + if (!dataResource || !dataResource->desc()) + { + std::string errorMessage = "runPSI failed: Must specified the input data-resource"; + auto error = + std::make_shared((int)PSIRetCode::NotSpecifyInputDataResource, errorMessage); + onTaskError("runPSI", std::move(error), _peerID, task->id(), + dataResource ? dataResource->resourceID() : "empty"); + PSI_LOG(WARNING) << LOG_DESC("runPSI error: ") << errorMessage; + return false; + } + if (_requireOutput && !dataResource->outputDesc()) + { + std::string errorMessage = "Must specified the output data-resource"; + auto error = + std::make_shared((int)PSIRetCode::NotSpecifyOutputDataResource, errorMessage); + onTaskError("runPSI", std::move(error), _peerID, task->id(), dataResource->resourceID()); + PSI_LOG(WARNING) << LOG_DESC("runPSI error: ") << errorMessage; + return false; + } + return true; +} + +bcos::Error::Ptr PSIFramework::lockResourceAndRecordTaskState( + int _command, TaskState::Ptr const& _taskState) +{ + // should notify the worker to check the task-status when the sub-task finished + _taskState->registerSubTaskFinishedHandler([this]() { wakeupWorker(); }); + auto const& task = _taskState->task(); + bcos::Error::Ptr error = nullptr; + { + // check the task-in-progressing or not + bcos::UpgradableGuard l(x_pendingTasks); + if (m_pendingTasks.count(task->id())) + { + error = BCOS_ERROR_PTR( + (int)PSIRetCode::TaskInProcessing, "The task " + task->id() + " is in-processing!"); + } + else + { + // insert the task into pending-task-pool + bcos::UpgradeGuard ul(l); + m_pendingTasks[task->id()] = _taskState; + } + } + auto ret = error; + if (error) + { + // trigger the callback + // Note: here can not calls cancel task for cancelTask will cancel the processing task + auto taskResult = std::make_shared(task->id()); + PSI_FRAMEWORK_LOG(INFO) << LOG_DESC("lockResourceAndRecordTaskState: cancel task") + << LOG_KV("task", task) << LOG_KV("code", error->errorCode()) + << LOG_KV("msg", error->errorMessage()); + taskResult->setError(std::move(error)); + auto callback = _taskState->takeCallback(); + callback(std::move(taskResult)); + return ret; + } + // Note: not all type tasks has resourceID + auto partyIndex = task->selfParty()->partyIndex(); + auto const& dataResource = task->selfParty()->dataResource(); + auto resourceID = dataResource ? dataResource->resourceID() : "empty"; + if (dataResource && needLockResource(_command, partyIndex)) + { + // Note: can't process the same data-resource in the same time + bcos::UpgradableGuard l(x_processingDataResource); + if (m_processingDataResource.count(resourceID)) + { + error = BCOS_ERROR_PTR((int)PSIRetCode::DataResourceOccupied, + "The dataResource " + resourceID + " is in-processing!"); + } + else + { + bcos::UpgradeGuard ul(l); + m_processingDataResource.insert(resourceID); + } + } + // Note: cancelTask will try to occupy lock x_processingDataResource and x_pendingTasks + // we should be careful when use cancelTask with locking x_processingDataResource or + // x_pendingTasks + ret = error; + if (error) + { + cancelTask(std::move(error), task->id()); + return ret; + } + return nullptr; +} + +ppc::protocol::PartyResource::Ptr PSIFramework::checkAndSetPeerInfo( + TaskState::Ptr const& _taskState, bool _enforcePeerResource) +{ + auto const& task = _taskState->task(); + auto const& dataResource = task->selfParty()->dataResource(); + // check the peer + auto const& peerParties = task->getAllPeerParties(); + if (peerParties.size() != 1) + { + std::string errorMessage = + "PSI only support two-party, please limit the party to 1, passed party count " + "is " + + std::to_string(peerParties.size()); + auto error = std::make_shared((int)PSIRetCode::OnlySupportOnePeer, errorMessage); + cancelTask(std::move(error), task->id()); + PSI_FRAMEWORK_LOG(WARNING) + << LOG_DESC("runPSI error for invalid peer ") << errorMessage << printTaskInfo(task); + return nullptr; + } + auto peerParty = peerParties.begin()->second; + _taskState->setPeerID(peerParty->id()); + if (!_enforcePeerResource) + { + return peerParty; + } + // check the peerDataResource + if (!peerParty->dataResource()) + { + std::string errorMessage = "runPSI failed: Must specified the peer data-resource-id"; + auto error = + std::make_shared((int)PSIRetCode::NotSpecifyPeerDataResource, errorMessage); + onTaskError( + "runPSI", std::move(error), peerParty->id(), task->id(), dataResource->resourceID()); + PSI_FRAMEWORK_LOG(WARNING) << LOG_DESC("runPSI error: ") << errorMessage; + return nullptr; + } + return peerParty; +} + +bool PSIFramework::checkPSIMsg(PSIMessageInterface::Ptr const& _msg) +{ + if (_msg->packetType() != (int)PSIPacketType::CancelTaskNotification && + _msg->packetType() != (int)PSIPacketType::TaskSyncMsg) + { + ReadGuard l(x_pendingTasks); + if (!m_pendingTasks.count(_msg->taskID())) + { + PSI_FRAMEWORK_LOG(WARNING) + << LOG_DESC("The task is not in the pendingPool") << printPSIMessage(_msg); + // notify the peer the task canceled + auto error = std::make_shared((int)PSIRetCode::TaskNotFound, + "Task " + _msg->taskID() + " not found in " + m_psiConfig->selfParty() + " !"); + notifyTaskResult(error, _msg->from(), _msg->taskID(), _msg->resourceID()); + return false; + } + } + return true; +} + +// notify the peer the task has been canceled for some error +void PSIFramework::notifyTaskResult(bcos::Error::Ptr const& _error, std::string const& _peerID, + std::string const& _taskID, std::string const& _resourceID) +{ + if (_peerID.empty() || _taskID.empty()) + { + return; + } + PSI_FRAMEWORK_LOG(INFO) << LOG_DESC("notifyTaskResult") << LOG_KV("peer", _peerID) + << LOG_KV("taskID", _taskID); + auto taskNotificationMsg = m_msgFactory->createTaskNotificationMessage( + (uint32_t)PSIPacketType::CancelTaskNotification); + taskNotificationMsg->setResourceID(_resourceID); + taskNotificationMsg->setErrorCode(_error ? _error->errorCode() : 0); + taskNotificationMsg->setErrorMessage(_error ? _error->errorMessage() : "success"); + taskNotificationMsg->setTaskID(_taskID); + taskNotificationMsg->setFrom(m_psiConfig->selfParty()); + m_psiConfig->generateAndSendPPCMessage(_peerID, _taskID, taskNotificationMsg, + [this, taskNotificationMsg](bcos::Error::Ptr&& _error) { + if (!_error || _error->errorCode() == 0) + { + return; + } + PSI_FRAMEWORK_LOG(WARNING) + << LOG_DESC("notifyTaskResult send error") << printPSIMessage(taskNotificationMsg) + << LOG_KV("code", _error->errorCode()) << LOG_KV("msg", _error->errorMessage()); + }); +} + + +// broadcast the sync-task-information to all nodes of the given peerID +void PSIFramework::broadcastSyncTaskInfo( + std::string const& _peerID, std::vector const& _taskList) +{ + // Note: the empty task-id means that broadcast the message to all nodes + std::string targetTaskID = ""; + auto taskSyncMsg = m_msgFactory->createTaskInfoMessage((uint32_t)PSIPacketType::TaskSyncMsg); + taskSyncMsg->setTaskList(_taskList); + // the partyID to using to differentiate psi nodes + taskSyncMsg->setPartyID(m_psiConfig->front()->selfEndPoint()); + // broadcast the taskSyncMsg to all nodes + m_psiConfig->generateAndSendPPCMessage( + _peerID, targetTaskID, taskSyncMsg, [this, _peerID, _taskList](bcos::Error::Ptr&& _error) { + if (!_error) + { + return; + } + // PSI_FRAMEWORK_LOG(WARNING) + // << LOG_DESC( + // "broadcastSyncTaskInfo: send message error, cancel all tasks + // related to the " "peer") + // << LOG_KV("peer", _peerID) << LOG_KV("tasks", _taskList.size()) + // << LOG_KV("code", _error->errorCode()) << LOG_KV("msg", + // _error->errorMessage()); + // cancel all the tasks + for (auto const& task : _taskList) + { + auto error = BCOS_ERROR_PTR((int)PSIRetCode::TaskNotFound, + "Cancel task " + task + " for network error between peer-party!"); + PSI_FRAMEWORK_LOG(INFO) << LOG_DESC("syncTaskInfo: cancel tasks for network error") + << LOG_KV("task", task); + cancelTask(std::move(error), task); + } + }); +} + +// sync the task-information to the peers periodically +void PSIFramework::syncTaskInfo() +{ + // get the pendingTasks + std::map> pendingTasks; + std::set syncedPeers; + { + bcos::ReadGuard l(x_pendingTasks); + for (auto const& it : m_pendingTasks) + { + auto const& peer = it.second->peerID(); + if (peer.empty()) + { + continue; + } + pendingTasks[peer].emplace_back(it.first); + syncedPeers.insert(peer); + } + PSI_FRAMEWORK_LOG(TRACE) << LOG_DESC("syncTaskInfo") + << LOG_KV("totalPendingTasks", m_pendingTasks.size()); + } + ////// sync the pending-tasks information to the peer + // sync empty taskList to the peers without local-task corresponding-to + auto agencyList = m_psiConfig->agencyList(); + for (auto const& it : agencyList) + { + if (syncedPeers.count(it)) + { + continue; + } + if (it == m_psiConfig->selfParty()) + { + continue; + } + PSI_FRAMEWORK_LOG(TRACE) << LOG_DESC("syncTaskInfo: sync empty task") << LOG_KV("peer", it); + std::vector emptyTaskList; + broadcastSyncTaskInfo(it, emptyTaskList); + } + + // sync tasks to peers with pendingTasks corresponding-to + for (auto const& it : pendingTasks) + { + auto peerID = it.first; + if (peerID.empty()) + { + continue; + } + auto const& taskList = it.second; + PSI_FRAMEWORK_LOG(TRACE) << LOG_DESC("syncTaskInfo") + << LOG_KV("pendingTasks", taskList.size()) + << LOG_KV("peer", peerID); + broadcastSyncTaskInfo(peerID, taskList); + } + m_taskSyncTimer->restart(); +} + +// receive the taskSync message, delete tasks that no longer exist in-peer +void PSIFramework::handleTaskSyncInfo(PSIMessageInterface::Ptr _msg) +{ + auto taskInfoMsg = std::dynamic_pointer_cast(_msg); + auto const& taskList = taskInfoMsg->taskList(); + std::set peerTaskSet(taskList.begin(), taskList.end()); + updatePeerTasks(_msg->from(), _msg->partyID(), peerTaskSet); + // get the local task list corresponding to the peer + std::vector localExpiredTaskList; + { + bcos::ReadGuard l(x_pendingTasks); + for (auto const& it : m_pendingTasks) + { + auto const& peerID = it.second->peerID(); + if (peerID != _msg->from()) + { + continue; + } + // only add the expired task to the localExpiredTaskList + if (it.second->taskPendingTime() <= (uint64_t)m_psiConfig->taskExpireTime()) + { + continue; + } + localExpiredTaskList.emplace_back(it.first); + } + } + // compare and erase the task + std::vector tasksToCancel; + auto peerTasks = getPeerTasks(_msg->from()); + for (auto const& it : localExpiredTaskList) + { + bool taskExists = false; + for (auto const& taskSet : peerTasks) + { + if (taskSet.second.count(it)) + { + taskExists = true; + break; + } + } + if (!taskExists) + { + tasksToCancel.emplace_back(it); + } + } + PSI_FRAMEWORK_LOG(TRACE) << LOG_DESC("handleTaskSyncInfo") << printPSIMessage(_msg) + << LOG_KV("peerTaskSize", taskList.size()) + << LOG_KV("localExpiredTaskList", localExpiredTaskList.size()) + << LOG_KV("tasksToCancel", tasksToCancel.size()); + // cancel the tasks + for (auto const& it : tasksToCancel) + { + PSI_FRAMEWORK_LOG(INFO) + << LOG_DESC("handleTaskSyncInfo: cancel task that no longer exist in-peer") + << LOG_KV("task", it); + auto error = BCOS_ERROR_PTR((int)PSIRetCode::TaskNotFound, + "Cancel task " + it + " for task no longer exists in the peer-party!"); + cancelTask(std::move(error), it); + } +} + +void PSIFramework::handleTaskNotificationMsg(PSIMessageInterface::Ptr _msg) +{ + auto notificationResult = std::dynamic_pointer_cast(_msg); + PSI_FRAMEWORK_LOG(INFO) << LOG_DESC("handleTaskNotificationMsg") << printPSIMessage(_msg) + << LOG_KV("code", notificationResult->errorCode()) + << LOG_KV("msg", notificationResult->errorMessage()); + // cancel the local task + auto error = std::make_shared( + notificationResult->errorCode(), notificationResult->errorMessage()); + cancelTask(std::move(error), notificationResult->taskID()); +} + +bool PSIFramework::handlePSIFrameworkMsg(PSIMessageInterface::Ptr _msg) +{ + // Note: exception should been catched by the caller + switch (_msg->packetType()) + { + case (uint32_t)PSIPacketType::CancelTaskNotification: + { + handleTaskNotificationMsg(_msg); + break; + } + case (uint32_t)PSIPacketType::TaskSyncMsg: + { + handleTaskSyncInfo(_msg); + break; + } + case (uint32_t)PSIPacketType::HandshakeResponse: + { + onHandshakeResponse(_msg); + break; + } + case (uint32_t)PSIPacketType::HandshakeRequest: + { + onHandshakeRequest(_msg); + break; + } + case (uint32_t)PSIPacketType::PSIResultSyncMsg: + { + handlePSIResultSyncMsg(_msg); + break; + } + default: + { + return false; + } + } + return true; +} + +LineReader::Ptr PSIFramework::loadData(DataResourceLoader::Ptr _dataResourceLoader, + std::string const& _taskID, DataResource::ConstPtr const& _dataResource) +{ + // load data from the data-source(TODO: loadReader use async-interface) + auto reader = + _dataResourceLoader->loadReader(_dataResource->desc(), ppc::io::DataSchema::Bytes, true); + // only support one-column + if (reader->columnSize() == 0 || reader->columnSize() > 1) + { + auto errorMsg = "load data for task " + _taskID + + "failed, PSI dataSourcemust be on column, current column size is " + + std::to_string(reader->columnSize()); + BOOST_THROW_EXCEPTION(BCOS_ERROR((int)PSIRetCode::LoadDataFailed, errorMsg)); + } + return reader; +} + +void PSIFramework::sendHandshakeRequest(TaskState::Ptr const& _taskState) +{ + if (_taskState->peerID().empty()) + { + return; + } + PSI_FRAMEWORK_LOG(INFO) << LOG_DESC("sendHandshakeRequest") + << printTaskInfo(_taskState->task()); + auto handshakeReq = + m_msgFactory->createHandshakeRequest((uint32_t)PSIPacketType::HandshakeRequest); + handshakeReq->setCurves( + g_PPCConfig.supportedCurves((uint8_t)TaskType::PSI, (uint8_t)m_psiConfig->algorithmType())); + handshakeReq->setHashList(g_PPCConfig.supportedHashList( + (uint8_t)TaskType::PSI, (uint8_t)m_psiConfig->algorithmType())); + handshakeReq->setTaskID(_taskState->task()->id()); + handshakeReq->setFrom(m_psiConfig->selfParty()); + m_psiConfig->generateAndSendPPCMessage(_taskState->peerID(), _taskState->task()->id(), + handshakeReq, [this, _taskState, handshakeReq](bcos::Error::Ptr&& _error) { + if (!_error || _error->errorCode() == 0) + { + return; + } + PSI_FRAMEWORK_LOG(WARNING) + << LOG_DESC("sendHandshakeRequest error") << LOG_KV("code", _error->errorCode()) + << LOG_KV("msg", _error->errorMessage()); + auto resource = _taskState->task()->selfParty()->dataResource(); + onTaskError("sendHandshakeRequest", std::move(_error), _taskState->peerID(), + _taskState->task()->id(), resource ? resource->resourceID() : "emptyResource"); + }); +} + + +void PSIFramework::responsePSIResultSyncStatus(int32_t _code, std::string const& _msg, + bcos::bytes const& _peer, std::string const& _taskID, std::string const& _uuid, uint32_t _seq) +{ + // response to the client + auto psiMsg = + m_msgFactory->createTaskNotificationMessage((uint32_t)PSIPacketType::PSIResultSyncResponse); + psiMsg->setErrorCode(_code); + psiMsg->setErrorMessage(_msg); + m_psiConfig->asyncSendResponse( + _peer, _taskID, _uuid, psiMsg, + [this](bcos::Error::Ptr _error) { + if (!_error || _error->errorCode() == 0) + { + return; + } + PSI_FRAMEWORK_LOG(WARNING) + << LOG_DESC("responsePSIResultSyncStatus error") + << LOG_KV("code", _error->errorCode()) << LOG_KV("msg", _error->errorMessage()); + }, + _seq); +} + +void PSIFramework::handlePSIResultSyncMsg(PSIMessageInterface::Ptr _resultSyncMsg) +{ + PSI_FRAMEWORK_LOG(INFO) << LOG_DESC("handlePSIResultSyncMsg") + << printPSIMessage(_resultSyncMsg); + auto taskState = getTaskByID(_resultSyncMsg->taskID()); + if (!taskState) + { + PSI_FRAMEWORK_LOG(WARNING) + << LOG_DESC("handlePSIResultSyncMsg error for the task not found") + << printPSIMessage(_resultSyncMsg); + std::string msg = + "sync psi result for task " + _resultSyncMsg->taskID() + " failed for task not found!"; + responsePSIResultSyncStatus((int32_t)PSIRetCode::TaskNotFound, msg, + _resultSyncMsg->fromNode(), _resultSyncMsg->taskID(), _resultSyncMsg->uuid(), + _resultSyncMsg->seq()); + return; + } + try + { + taskState->storePSIResult(m_dataResourceLoader, _resultSyncMsg->takeData()); + responsePSIResultSyncStatus((int32_t)PSIRetCode::Success, "success", + _resultSyncMsg->fromNode(), _resultSyncMsg->taskID(), _resultSyncMsg->uuid(), + _resultSyncMsg->seq()); + } + catch (std::exception const& e) + { + PSI_FRAMEWORK_LOG(WARNING) << LOG_DESC("handlePSIResultSyncMsg exception") + << LOG_KV("error", boost::diagnostic_information(e)); + auto errorMessage = "sync psi result for " + _resultSyncMsg->taskID() + + " failed, error: " + std::string(boost::diagnostic_information(e)); + responsePSIResultSyncStatus((int32_t)PSIRetCode::SyncPSIResultFailed, errorMessage, + _resultSyncMsg->fromNode(), _resultSyncMsg->taskID(), _resultSyncMsg->uuid(), + _resultSyncMsg->seq()); + // cancel the task + auto error = BCOS_ERROR_PTR((int32_t)PSIRetCode::SyncPSIResultFailed, errorMessage); + cancelTask(std::move(error), _resultSyncMsg->taskID()); + } +} \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-psi/src/psi-framework/PSIFramework.h b/cpp/wedpr-computing/ppc-psi/src/psi-framework/PSIFramework.h new file mode 100644 index 00000000..bea4974e --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/psi-framework/PSIFramework.h @@ -0,0 +1,249 @@ +/* + * Copyright (C) 2022 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 PSIFramework.h + * @author: yujiechen + * @date 2022-12-26 + */ +#pragma once +#include "../PSIConfig.h" +#include "TaskState.h" +#include "interfaces/PSIMessageFactory.h" +#include "interfaces/PSIMessageInterface.h" +#include "ppc-framework/io/DataResourceLoader.h" +#include "ppc-framework/task/TaskFrameworkInterface.h" +#include +#include +#include +#include +#include + +#define PSI_FRAMEWORK_LOG(LEVEL) \ + BCOS_LOG(LEVEL) << LOG_BADGE("PSI") \ + << LOG_BADGE((ppc::protocol::TaskAlgorithmType)m_psiConfig->algorithmType()) +namespace ppc::psi +{ +using PSIMsgQueue = bcos::ConcurrentQueue; +using PSIMsgQueuePtr = std::shared_ptr; +class PSIFramework : public bcos::Worker, public ppc::task::TaskFrameworkInterface +{ +public: + using Ptr = std::shared_ptr; + PSIFramework(PSIMessageFactory::Ptr const& _msgFactory, + ppc::io::DataResourceLoader::Ptr const& _dataResourceLoader, PSIConfig::Ptr const& _config, + std::string const& _workerName = "psi-base", unsigned _idleTimeMs = 0) + : Worker(_workerName, _idleTimeMs), + m_msgFactory(_msgFactory), + m_dataResourceLoader(_dataResourceLoader), + m_psiConfig(_config), + m_taskStateFactory(std::make_shared()), + m_msgQueue(std::make_shared()) + { + // Note: c_taskSyncTimerPeriod is inited after PSIFramework created, so the timer should + // been created after construct PSIFramework + m_taskSyncTimer = std::make_shared(c_taskSyncTimerPeriod, "taskSyncTimer"); + } + virtual ~PSIFramework() = default; + + void start() override; + void stop() override; + + // psi main processing function + // for ut to make this function public + void executeWorker() override; + + // register to the front to get the message related to + void onReceiveMessage(ppc::front::PPCMessageFace::Ptr _msg) override; + + uint64_t lockingResourceSize() const + { + bcos::ReadGuard l(x_processingDataResource); + return m_processingDataResource.size(); + } + + uint64_t pendingTasksSize() const + { + bcos::ReadGuard l(x_pendingTasks); + return m_pendingTasks.size(); + } + + inline void removePendingTask(std::string const& _taskID) + { + bcos::WriteGuard l(x_pendingTasks); + m_pendingTasks.erase(_taskID); + } + + TaskState::Ptr getTaskByID(std::string const& _taskID) + { + bcos::ReadGuard l(x_pendingTasks); + auto it = m_pendingTasks.find(_taskID); + if (it != m_pendingTasks.end()) + { + return it->second; + } + return nullptr; + } + + bool checkPSIMsg(PSIMessageInterface::Ptr const& _msg); + + bool checkDataResourceForSelf( + TaskState::Ptr const& _taskState, std::string const& _peerID, bool _requireOutput = false); + + PSIConfig::Ptr const& psiConfig() const { return m_psiConfig; } + +protected: + // handle the psi message + virtual void handlePSIMsg(PSIMessageInterface::Ptr _msg) = 0; + // should lock the party resource or not + virtual bool needLockResource(int _command, int _partyIndex) = 0; + // receive the handshake response + virtual void onHandshakeResponse(PSIMessageInterface::Ptr const& _msg) = 0; + // receive the handshake request + virtual void onHandshakeRequest(PSIMessageInterface::Ptr const& _msg) = 0; + + // handle the taskNotification and taskInfos related messages + virtual bool handlePSIFrameworkMsg(PSIMessageInterface::Ptr _msg); + + virtual bcos::Error::Ptr lockResourceAndRecordTaskState( + int _command, TaskState::Ptr const& _taskState); + + // notify error-result to the peer and cancel-task + void onTaskError(std::string const& _desc, bcos::Error::Ptr&& _error, + std::string const& _peerID, std::string const& _taskID, std::string const& _resourceID); + // cancel the task and response to the user when error happens + virtual void cancelTask(bcos::Error::Ptr&& _error, std::string const& _task); + + + // handle the local task looply + virtual void handleLocalTask(); + virtual void checkAndNotifyTaskResult(); + + // sync the task information and erase the task already deleted from peer + virtual void syncTaskInfo(); + virtual void handleTaskSyncInfo(PSIMessageInterface::Ptr _msg); + + // receive the task-cancel-msg + virtual void handleTaskNotificationMsg(PSIMessageInterface::Ptr _msg); + + /////// the common function + // notify the peer the task has been canceled for some error + virtual void notifyTaskResult(bcos::Error::Ptr const& _error, std::string const& _peerID, + std::string const& _taskID, std::string const& _resourceID); + + template + inline void batchRemoveDataResource(T const& _resourceList) + { + if (_resourceList.empty()) + { + return; + } + bcos::WriteGuard l(x_processingDataResource); + for (auto const& it : _resourceList) + { + m_processingDataResource.erase(it); + } + } + + virtual void removeLockingResource(std::string const& _resourceID) + { + // update the processing-data-resource + bcos::UpgradableGuard l(x_processingDataResource); + auto it = m_processingDataResource.find(_resourceID); + if (it != m_processingDataResource.end()) + { + bcos::UpgradeGuard ul(l); + m_processingDataResource.erase(it); + } + } + + void wakeupWorker() { m_signalled.notify_all(); } + + virtual ppc::protocol::PartyResource::Ptr checkAndSetPeerInfo( + TaskState::Ptr const& _taskState, bool _enforcePeerResource); + ppc::io::LineReader::Ptr loadData(ppc::io::DataResourceLoader::Ptr _dataResourceLoader, + std::string const& _taskID, ppc::protocol::DataResource::ConstPtr const& _dataResource); + + // the client send the handshakeRequest to the server + virtual void sendHandshakeRequest(TaskState::Ptr const& _taskState); + + // handle the PSIResultSyncMsg + virtual void handlePSIResultSyncMsg(PSIMessageInterface::Ptr _resultSyncMsg); + +private: + // utility functions + void waitSignal() + { + boost::unique_lock l(x_signalled); + m_signalled.wait_for(l, boost::chrono::milliseconds(5)); + } + void responsePSIResultSyncStatus(int32_t _code, std::string const& _msg, + bcos::bytes const& _peer, std::string const& _taskID, std::string const& _uuid, + uint32_t _seq); + + void broadcastSyncTaskInfo( + std::string const& _peerID, std::vector const& _taskList); + + void updatePeerTasks(std::string const& _agencyID, std::string const& _partyID, + std::set const& _tasks) + { + bcos::WriteGuard l(x_peerTasks); + m_peerTasks[_agencyID][_partyID] = _tasks; + } + + std::map> getPeerTasks(std::string const& _agencyID) const + { + bcos::ReadGuard l(x_peerTasks); + if (m_peerTasks.count(_agencyID)) + { + return m_peerTasks.at(_agencyID); + } + return std::map>(); + } + +protected: + PSIMessageFactory::Ptr m_msgFactory; + ppc::io::DataResourceLoader::Ptr m_dataResourceLoader; + PSIConfig::Ptr m_psiConfig; + // the task-state factory + TaskStateFactory::Ptr m_taskStateFactory; + + bool m_started = false; + + boost::condition_variable m_signalled; + boost::mutex x_signalled; + + mutable bcos::Mutex m_mutex; + + // the processing data resource + std::set m_processingDataResource; + mutable bcos::SharedMutex x_processingDataResource; + + // record the pending tasks(Note: only psi task recorded here) + std::unordered_map m_pendingTasks; + mutable bcos::SharedMutex x_pendingTasks; + + PSIMsgQueuePtr m_msgQueue; + const unsigned c_PopWaitMs = 5; + + // the timer used to sync the task-information and evict the expired or exceptioned task + // periodically + std::shared_ptr m_taskSyncTimer; + const unsigned int c_taskSyncTimerPeriod = 10000; + + // record the tasks of the peer + std::map>> m_peerTasks; + mutable bcos::SharedMutex x_peerTasks; +}; +} // namespace ppc::psi \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-psi/src/psi-framework/TaskGuarder.cpp b/cpp/wedpr-computing/ppc-psi/src/psi-framework/TaskGuarder.cpp new file mode 100644 index 00000000..208602b9 --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/psi-framework/TaskGuarder.cpp @@ -0,0 +1,275 @@ +/** + * Copyright (C) 2022 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 TaskGuarder.cpp + * @author: shawnhe + * @date 2022-01-07 + */ +#include "TaskGuarder.h" + +using namespace ppc::psi; +using namespace ppc::protocol; +using namespace ppc::io; + + +bcos::Error::Ptr TaskGuarder::checkTask(const Task::ConstPtr& _task, uint16_t _partiesCount, + bool _enforceSelfInput, bool _enforceSelfOutput, bool _enforcePeerResource, + bool _enforceSelfResource) +{ + { + // check task id + bcos::ReadGuard l(x_pendingTasks); + if (m_pendingTasks.contains(_task->id())) + { + return std::make_shared( + (int)PSIRetCode::DuplicatedTask, "task already exists"); + } + } + + // check self party + auto const& selfParty = _task->selfParty(); + if (!selfParty) + { + return std::make_shared( + (int)PSIRetCode::TaskParamsError, "must specify self party info"); + } + if (selfParty->partyIndex() == (uint16_t)protocol::PartyType::Client) + { + _enforceSelfInput = true; + _enforceSelfOutput = true; + } + + // check self data resource + if (_enforceSelfResource) + { + auto const& dataResource = selfParty->dataResource(); + if (!dataResource) + { + return std::make_shared( + (int)PSIRetCode::TaskParamsError, "no data resource specified for self party"); + } + auto originData = dataResource->rawData(); + if (_enforceSelfInput && originData.empty() && !dataResource->desc()) + { + return std::make_shared( + (int)PSIRetCode::TaskParamsError, "no input resource specified for self party"); + } + if (_enforceSelfOutput && originData.empty() && !dataResource->outputDesc()) + { + return std::make_shared( + (int)PSIRetCode::TaskParamsError, "no output resource specified for self party"); + } + } + + // check party index + std::set indexSet; + auto index = selfParty->partyIndex(); + if (_partiesCount > 1 && index >= _partiesCount) + { + return std::make_shared( + (int)PSIRetCode::TaskParamsError, "invalid partyIndex: " + std::to_string(index)); + } + indexSet.insert(index); + + // check the peer size + auto const& peerParties = _task->getAllPeerParties(); + if (peerParties.size() != uint(_partiesCount - 1)) + { + std::string errorMessage = "expected parties count: " + std::to_string(_partiesCount) + + ", current is " + std::to_string(peerParties.size()); + return std::make_shared((int)PSIRetCode::TaskParamsError, errorMessage); + } + + // check the party index of peers + for (auto& it : peerParties) + { + index = it.second->partyIndex(); + if (_partiesCount > 1 && index >= _partiesCount) + { + return std::make_shared( + (int)PSIRetCode::TaskParamsError, "invalid partyIndex: " + std::to_string(index)); + } + if (indexSet.contains(index)) + { + return std::make_shared( + (int)PSIRetCode::TaskParamsError, "repeated party index: " + std::to_string(index)); + } + indexSet.insert(index); + } + + // check the data resource of peer + if (!_enforcePeerResource) + { + return nullptr; + } + for (auto& it : peerParties) + { + if (!it.second->dataResource()) + { + return std::make_shared( + (int)PSIRetCode::NotSpecifyPeerDataResource, "must specify the peer data resource"); + } + } + return nullptr; +} + + +void TaskGuarder::noticePeerToFinish(const Task::ConstPtr& _task) +{ + auto const& peerParties = _task->getAllPeerParties(); + if (peerParties.empty()) + { + return; + } + + for (const auto& peer : peerParties) + { + noticePeerToFinish(_task->id(), peer.first); + } +} + +void TaskGuarder::noticePeerToFinish(const std::string& _taskID, const std::string& _peer) +{ + PSI_LOG(INFO) << LOG_DESC("noticePeerToFinish") << LOG_KV("task", _taskID) + << LOG_KV("peer", _peer); + try + { + if (_peer.empty()) + { + return; + } + + auto message = m_config->ppcMsgFactory()->buildPPCMessage(uint8_t(protocol::TaskType::PSI), + uint8_t(m_type), _taskID, std::make_shared()); + message->setMessageType(uint8_t(CommonMessageType::ErrorNotification)); + m_config->front()->asyncSendMessage( + _peer, message, m_config->networkTimeout(), [](const bcos::Error::Ptr&) {}, nullptr); + } + catch (std::exception& e) + { + PSI_LOG(ERROR) << LOG_DESC("noticePeerToFinish") + << LOG_KV("exception", boost::diagnostic_information(e)); + } +} + +void TaskGuarder::checkPeerActivity() +{ + bcos::ReadGuard l(x_pendingTasks); + for (auto const& it : m_pendingTasks) + { + if (it.second->onlySelfRun()) + { + // no need to check peer + continue; + } + + auto task = it.second->task(); + auto const& peerParties = task->getAllPeerParties(); + if (peerParties.empty()) + { + continue; + } + + for (const auto& peer : peerParties) + { + auto message = + m_config->ppcMsgFactory()->buildPPCMessage(uint8_t(protocol::TaskType::PSI), + uint8_t(m_type), task->id(), std::make_shared()); + message->setMessageType(uint8_t(CommonMessageType::PingPeer)); + m_config->front()->asyncSendMessage( + peer.first, message, m_config->networkTimeout(), + [this, task, peerID = peer.first](bcos::Error::Ptr&& _error) { + if (!_error || _error->errorCode() == 0) + { + return; + } + onSelfError(task->id(), + std::make_shared( + (int)PSIRetCode::PeerNodeDown, "peer node is down, id: " + peerID), + false); + PSI_LOG(INFO) << LOG_DESC("checkPeerActivity: peer node-down") + << LOG_KV("peer", peerID) << LOG_KV("task", task->id()); + }, + nullptr); + } + } + m_pingTimer->restart(); +} + + +LineReader::Ptr TaskGuarder::loadReader(std::string const& _taskID, + protocol::DataResource::ConstPtr const& _dataResource, DataSchema _dataSchema, + uint32_t _columnSize) +{ + if (!_dataResource->rawData().empty()) + { + return nullptr; + } + auto reader = + m_config->dataResourceLoader()->loadReader(_dataResource->desc(), _dataSchema, true); + + if (reader->columnSize() == 0 || + (reader->type() == DataResourceType::MySQL && reader->columnSize() != _columnSize)) + { + auto errorMsg = "load data for task " + _taskID + "failed, expect " + + std::to_string(_columnSize) + " column, current column size is " + + std::to_string(reader->columnSize()); + BOOST_THROW_EXCEPTION(BCOS_ERROR((int)PSIRetCode::LoadDataFailed, errorMsg)); + } + return reader; +} + +LineWriter::Ptr TaskGuarder::loadWriter(std::string const& _taskID, + DataResource::ConstPtr const& _dataResource, bool _enableOutputExists) +{ + if (!_dataResource->rawData().empty()) + { + return nullptr; + } + if (!_enableOutputExists) + { + // Note: if the output-resource already exists, will throw exception + m_config->dataResourceLoader()->checkResourceExists(_dataResource->outputDesc()); + } + return m_config->dataResourceLoader()->loadWriter(_dataResource->outputDesc(), true); +} + +TaskState::Ptr TaskGuarder::findPendingTask(const std::string& _taskID) +{ + bcos::ReadGuard l(x_pendingTasks); + auto it = m_pendingTasks.find(_taskID); + if (it == m_pendingTasks.end()) + { + return nullptr; + } + return it->second; +} + +void TaskGuarder::addPendingTask(TaskState::Ptr _taskState) +{ + bcos::WriteGuard l(x_pendingTasks); + auto id = _taskState->task()->id(); + m_pendingTasks[id] = std::move(_taskState); +} + +void TaskGuarder::removePendingTask(const std::string& _taskID) +{ + bcos::WriteGuard l(x_pendingTasks); + auto it = m_pendingTasks.find(_taskID); + if (it != m_pendingTasks.end()) + { + m_pendingTasks.erase(it); + } +} diff --git a/cpp/wedpr-computing/ppc-psi/src/psi-framework/TaskGuarder.h b/cpp/wedpr-computing/ppc-psi/src/psi-framework/TaskGuarder.h new file mode 100644 index 00000000..8587d23c --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/psi-framework/TaskGuarder.h @@ -0,0 +1,110 @@ +/** + * Copyright (C) 2022 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 TaskGuarder.h + * @author: shawnhe + * @date 2022-01-07 + */ + +#pragma once + +#include "../Common.h" +#include "../PSIConfig.h" +#include "TaskState.h" +#include "ppc-framework/protocol/Protocol.h" +#include "protocol/src/PPCMessage.h" +#include + +namespace ppc::psi +{ +class TaskGuarder +{ +public: + using Ptr = std::shared_ptr; + explicit TaskGuarder(PSIConfig::Ptr _config) : m_config(std::move(_config)) {} + TaskGuarder( + PSIConfig::Ptr _config, protocol::TaskAlgorithmType _type, const std::string& _timerName) + : m_config(std::move(_config)), + m_type(_type), + m_taskStateFactory(std::make_shared()) + { + m_pingTimer = std::make_shared(c_pingTimerPeriod, _timerName); + } + virtual ~TaskGuarder() = default; + + virtual void onReceivedErrorNotification(ppc::front::PPCMessageFace::Ptr const&){}; + virtual void onSelfError( + const std::string& _taskID, bcos::Error::Ptr _error, bool _noticePeer){}; + + void startPingTimer() + { + m_pingTimer->registerTimeoutHandler([this]() { checkPeerActivity(); }); + m_pingTimer->start(); + } + void stopPingTimer() + { + if (m_pingTimer) + { + m_pingTimer->stop(); + } + } + + bcos::Error::Ptr checkTask(const ppc::protocol::Task::ConstPtr& _task, uint16_t _partiesCount, + bool _enforceSelfInput, bool _enforceSelfOutput, bool _enforcePeerResource, + bool _enforceSelfResource = true); + + // this only work for two-party task + static std::string getPeerID(ppc::protocol::Task::ConstPtr _task) + { + auto const& peerParties = _task->getAllPeerParties(); + if (peerParties.empty()) + { + return ""; + } + return peerParties.begin()->second->id(); + } + + void noticePeerToFinish(const ppc::protocol::Task::ConstPtr& _task); + void noticePeerToFinish(const std::string& _taskID, const std::string& _peer); + + void checkPeerActivity(); + + io::LineReader::Ptr loadReader(std::string const& _taskID, + protocol::DataResource::ConstPtr const& _dataResource, io::DataSchema _dataSchema, + uint32_t _columnSize = 1); + + io::LineWriter::Ptr loadWriter(std::string const& _taskID, + protocol::DataResource::ConstPtr const& _dataResource, bool _enableOutputExists); + + TaskState::Ptr findPendingTask(const std::string& _taskID); + + void addPendingTask(TaskState::Ptr _taskState); + + void removePendingTask(const std::string& _taskID); + +protected: + PSIConfig::Ptr m_config; + protocol::TaskAlgorithmType m_type; + TaskStateFactory::Ptr m_taskStateFactory; + // the timer used to check the activity of peer node + std::shared_ptr m_pingTimer; + + const unsigned int c_pingTimerPeriod = 60000; + + std::unordered_map m_pendingTasks; + mutable bcos::SharedMutex x_pendingTasks; +}; + +} // namespace ppc::psi \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-psi/src/psi-framework/TaskState.cpp b/cpp/wedpr-computing/ppc-psi/src/psi-framework/TaskState.cpp new file mode 100644 index 00000000..1ea77322 --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/psi-framework/TaskState.cpp @@ -0,0 +1,373 @@ +/** + * Copyright (C) 2022 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 TaskState.cpp + * @author: yujiechen + * @date 2022-11-11 + */ +#include "TaskState.h" +using namespace ppc::psi; +using namespace ppc::io; +using namespace ppc::protocol; + + +DataBatch::Ptr TaskState::loadAllData() +{ + DataBatch::Ptr results; + auto originData = m_task->selfParty()->dataResource()->rawData(); + if (!originData.empty()) + { + results = std::make_shared(); + results->setDataSchema(DataSchema::Bytes); + + std::vector data; + for (auto& line : originData[0]) + { + data.emplace_back(bcos::bytes(line.begin(), line.end())); + } + results->setData(std::move(data)); + } + else + { + if (m_reader) + { + int64_t nextParam = m_sqlReader ? 0 : -1; + results = m_reader->next(nextParam, io::DataSchema::Bytes); + } + } + if (!results) + { + results = std::make_shared(); + } + return results; +} + +void TaskState::writeLines(const DataBatch::Ptr& _data, DataSchema _schema) +{ + if (m_writer) + { + m_writer->writeLine(_data, _schema); + m_writer->flush(); + m_writer->close(); + m_writer->upload(); + m_uploaded = true; + } +} + +void TaskState::writeBytes(bcos::bytesConstRef _data) +{ + if (m_writer) + { + m_writer->writeBytes(_data); + m_writer->flush(); + m_writer->close(); + m_writer->upload(); + m_uploaded = true; + } +} + +int32_t TaskState::allocateSeq() +{ + bcos::RecursiveGuard l(m_mutex); + m_currentSeq.store(m_currentSeq.load() + 1); + { + bcos::WriteGuard l(x_seqList); + m_seqList.insert(m_currentSeq.load()); + } + return m_currentSeq; +} + +void TaskState::eraseFinishedTaskSeq(uint32_t _seq, bool _success) +{ + { + bcos::UpgradableGuard l(x_seqList); + auto it = m_seqList.find(_seq); + if (it == m_seqList.end()) + { + return; + } + bcos::UpgradeGuard ul(l); + m_seqList.erase(it); + if (_success) + { + m_successCount++; + } + else + { + m_failedCount++; + } + } + try + { + // trigger the callback when the sub-task finished + // Note: the subTaskHandler may go wrong + if (m_onSubTaskFinished) + { + m_onSubTaskFinished(); + } + PSI_LOG(INFO) << LOG_DESC("eraseFinishedTaskSeq") << LOG_KV("task", m_task->id()) + << LOG_KV("seq", _seq) << LOG_KV("success", _success) + << LOG_KV("seqs", m_seqList.size()) << LOG_KV("successCount", m_successCount) + << LOG_KV("failedCount", m_failedCount); + } + catch (std::exception const& e) + { + PSI_LOG(WARNING) << LOG_DESC( + "eraseFinishedTaskSeq error for calls the sub-task-finalize " + "handler exception") + << LOG_KV("msg", boost::diagnostic_information(e)); + onTaskException(boost::diagnostic_information(e)); + } +} + + +// trigger the callback to response +void TaskState::onTaskFinished() +{ + // avoid repeated calls + if (m_taskDone.exchange(true)) + { + return; + } + PSI_LOG(INFO) << LOG_DESC("* onTaskFinished") << LOG_KV("task", m_task->id()) + << LOG_KV("success", m_successCount) << LOG_KV("failed", m_failedCount) + << LOG_KV("loadFinished", m_finished.load()) + << LOG_KV("callback", m_callback ? "withCallback" : "emptyCallback") + << LOG_KV("taskTimecost", taskPendingTime()); + auto result = std::make_shared(m_task->id()); + try + { + // upload the psi-result + if (m_writer && !m_uploaded) + { + m_writer->upload(); + m_uploaded = true; + } + if (m_finalizeHandler) + { + m_finalizeHandler(); + } + if (m_failedCount > 0) + { + auto error = std::make_shared( + -1, "task " + m_task->id() + " failed for " + + boost::lexical_cast(m_failedCount) + " error!"); + result->setError(std::move(error)); + result->setStatus(toString(TaskStatus::FAILED)); + // remove the generated output files if run failed + removeGeneratedOutputFile(); + } + else + { + result->setStatus(toString(TaskStatus::COMPLETED)); + } + + // clear file + if (m_reader) + { + m_reader->clean(); + } + } + catch (std::exception const& e) + { + PSI_LOG(WARNING) << LOG_DESC("* onTaskFinished exception") + << LOG_KV("taskTimeCost", taskPendingTime()) + << LOG_KV("msg", boost::diagnostic_information(e)); + auto error = std::make_shared(-1, boost::diagnostic_information(e)); + result->setError(std::move(error)); + result->setStatus(toString(TaskStatus::FAILED)); + } + if (m_callback) + { + m_callback(std::move(result)); + } +} + +void TaskState::removeGeneratedOutputFile() +{ + if (!m_task || !m_task->selfParty() || !m_task->selfParty()->dataResource()) + { + return; + } + if (!m_writer) + { + return; + } + auto outputDataResource = m_task->selfParty()->dataResource(); + if (!outputDataResource->desc()) + { + return; + } + PSI_LOG(INFO) << LOG_DESC("removeGeneratedOutputFile") << LOG_KV("task", printTaskInfo(m_task)); + m_config->dataResourceLoader()->deleteResource(outputDataResource->desc()); +} + +void TaskState::onTaskFinished(TaskResult::Ptr _result, bool _noticePeer) +{ + // avoid repeated calls + if (m_taskDone.exchange(true)) + { + return; + } + PSI_LOG(INFO) << LOG_DESC("onTaskFinished") << LOG_KV("task", m_task->id()) + << LOG_KV("success", m_successCount) << LOG_KV("onlySelfRun", m_onlySelfRun) + << LOG_KV("finished", m_finished.load()) << LOG_KV("noticePeer", _noticePeer); + if (!_result) + { + _result = std::make_shared(m_task->id()); + } + try + { + _result->setStatus(toString(TaskStatus::COMPLETED)); + if (_result->error() && _result->error()->errorCode() != 0) + { + _result->setStatus(toString(TaskStatus::FAILED)); + // remove the generated output files if run failed + removeGeneratedOutputFile(); + } + // Note: we consider that the task success even if the handler exception + if (_noticePeer && !m_onlySelfRun && _result->error() && _result->error()->errorCode() && + m_notifyPeerFinishHandler) + { + m_notifyPeerFinishHandler(); + } + + if (m_finalizeHandler) + { + m_finalizeHandler(); + } + + m_finished.exchange(true); + + // clear file + if (m_reader) + { + m_reader->clean(); + } + } + catch (std::exception const& e) + { + PSI_LOG(WARNING) << LOG_DESC("onTaskFinished exception") + << LOG_KV("msg", boost::diagnostic_information(e)); + auto error = std::make_shared(-1, boost::diagnostic_information(e)); + _result->setError(std::move(error)); + _result->setStatus(toString(TaskStatus::FAILED)); + } + if (m_callback) + { + m_callback(std::move(_result)); + } +} + +void TaskState::onPeerNotifyFinish() +{ + PSI_LOG(WARNING) << LOG_BADGE("onReceivePeerError") << LOG_KV("taskID", m_task->id()); + auto result = std::make_shared(task()->id()); + result->setError(std::make_shared( + (int)PSIRetCode::PeerNotifyFinish, "job participant sent an error")); + onTaskFinished(std::move(result), false); + removeGeneratedOutputFile(); +} + +// Note: must store the result serially +void TaskState::storePSIResult( + DataResourceLoader::Ptr const& _resourceLoader, std::vector const& _data) +{ + bcos::RecursiveGuard l(m_mutex); + // try to generate-default-output-desc to make sure the server output exists even if not + // specified + tryToGenerateDefaultOutputDesc(); + auto dataResource = m_task->selfParty()->dataResource(); + // load the writer + if (!m_writer) + { + m_writer = _resourceLoader->loadWriter(dataResource->outputDesc()); + } + auto dataBatch = std::make_shared(); + dataBatch->setData(_data); + m_writer->writeLine(dataBatch, DataSchema::Bytes); + m_writer->flush(); + PSI_LOG(INFO) << LOG_DESC("**** storePSIResult success ****") << LOG_KV("* task", m_task->id()) + << LOG_KV("* IntersectionCount", _data.size()) + << LOG_KV("* TaskTimecost", taskPendingTime()); +} + +void TaskState::onTaskException(std::string const& _errorMsg) +{ + // set the task finished + setFinished(true); + { + bcos::WriteGuard l(x_seqList); + m_seqList.clear(); + } + if (!m_callback) + { + return; + } + // should been called even when exception + if (m_finalizeHandler) + { + try + { + m_finalizeHandler(); + } + catch (std::exception const& e) + { + PSI_LOG(WARNING) << LOG_DESC("finalize task exception") + << LOG_KV("taskID", m_task->id()) + << LOG_KV("msg", boost::diagnostic_information(e)); + } + } + if (m_notifyPeerFinishHandler) + { + try + { + m_notifyPeerFinishHandler(); + } + catch (std::exception const& e) + { + PSI_LOG(WARNING) << LOG_DESC("notifyPeerFinish exception") + << LOG_KV("taskID", m_task->id()) + << LOG_KV("msg", boost::diagnostic_information(e)); + } + } + auto taskResult = std::make_shared(m_task->id()); + auto msg = "Task " + m_task->id() + " exception, error : " + _errorMsg; + auto error = std::make_shared(-1, msg); + taskResult->setError(std::move(error)); + m_callback(std::move(taskResult)); + PSI_LOG(WARNING) << LOG_DESC(msg); +} + +void TaskState::tryToGenerateDefaultOutputDesc() +{ + auto dataResource = m_task->selfParty()->mutableDataResource(); + if (!dataResource) + { + dataResource = std::make_shared(); + m_task->mutableSelfParty()->setDataResource(dataResource); + } + if (dataResource->outputDesc()) + { + return; + } + auto outputDesc = std::make_shared(); + auto dstPath = c_resultPath + "/" + m_task->id() + ".result"; + outputDesc->setPath(dstPath); + outputDesc->setType((uint16_t)(DataResourceType::FILE)); + dataResource->setOutputDesc(outputDesc); + PSI_LOG(INFO) << LOG_DESC("GenerateDefaultOutputDesc for the output-desc not specified") + << LOG_KV("task", m_task->id()) << LOG_KV("path", dstPath); +} diff --git a/cpp/wedpr-computing/ppc-psi/src/psi-framework/TaskState.h b/cpp/wedpr-computing/ppc-psi/src/psi-framework/TaskState.h new file mode 100644 index 00000000..a06d1ab8 --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/psi-framework/TaskState.h @@ -0,0 +1,209 @@ +/** + * Copyright (C) 2022 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 TaskState.h + * @author: yujiechen + * @date 2022-11-11 + */ +#pragma once +#include "../Common.h" +#include "../PSIConfig.h" +#include "ppc-framework/io/DataResourceLoader.h" +#include "ppc-framework/io/LineReader.h" +#include "ppc-framework/protocol/Protocol.h" +#include "ppc-framework/protocol/Task.h" +#include "ppc-framework/task/TaskFrameworkInterface.h" +#include +#include +#include +#include +#include + +namespace ppc::psi +{ +class TaskState : public std::enable_shared_from_this +{ +public: + using Ptr = std::shared_ptr; + TaskState(ppc::protocol::Task::ConstPtr const& _task, + ppc::task::TaskResponseCallback&& _callback, bool _onlySelfRun = false, + PSIConfig::Ptr _config = nullptr) + : m_task(_task), + m_callback(std::move(_callback)), + m_onlySelfRun(_onlySelfRun), + m_config(std::move(_config)) + { + m_taskStartTime = bcos::utcSteadyTime(); + } + + virtual ~TaskState() + { + PSI_LOG(INFO) << LOG_DESC("** TaskState Destructor") << LOG_KV("task", m_task->id()); + } + + ppc::task::TaskResponseCallback const& callback() { return m_callback; } + ppc::task::TaskResponseCallback takeCallback() { return std::move(m_callback); } + bool onlySelfRun() { return m_onlySelfRun; } + void setReader(io::LineReader::Ptr _reader, int64_t _readerParam) + { + m_reader = std::move(_reader); + m_readerParam = _readerParam; + if (m_reader) + { + m_sqlReader = (m_reader->type() == protocol::DataResourceType::MySQL); + } + } + void setWriter(io::LineWriter::Ptr _writer) { m_writer = std::move(_writer); } + protocol::Task::ConstPtr const& task() const { return m_task; } + + io::LineReader::Ptr const& reader() const { return m_reader; } + io::LineWriter::Ptr const& writer() const { return m_writer; } + + int64_t readerParam() const { return m_readerParam; } + bool sqlReader() const { return m_sqlReader; } + + io::DataBatch::Ptr loadAllData(); + void writeLines(const io::DataBatch::Ptr& _data, io::DataSchema _schema); + void writeBytes(bcos::bytesConstRef _data); + + int32_t allocateSeq(); + + void eraseFinishedTaskSeq(uint32_t _seq, bool _success); + + virtual void setFinished(bool _finished) { m_finished.store(_finished); } + + virtual std::string peerID() const { return m_peerID; } + virtual void setPeerID(std::string const& _peerID) { m_peerID = _peerID; } + + virtual bool taskDone() { return m_taskDone; } + + // represent that the task has been finished or not + virtual bool finished() const + { + bcos::ReadGuard l(x_seqList); + return m_finished.load() && m_seqList.empty(); + } + + // trigger the callback to response + virtual void onTaskFinished(); + + virtual void onTaskFinished(ppc::protocol::TaskResult::Ptr _result, bool _noticePeer); + + virtual void onPeerNotifyFinish(); + void setWorker(std::function const& _worker) { m_worker = _worker; } + void executeWork() + { + if (!m_worker) + { + return; + } + m_worker(); + } + + // set handler called when the task-finished + // Note: the finalize-handler maybe called no matter task success or failed + void registerFinalizeHandler(std::function const& _finalizeHandler) + { + m_finalizeHandler = _finalizeHandler; + } + + void registerSubTaskFinishedHandler(std::function const& _onSubTaskFinished) + { + m_onSubTaskFinished = _onSubTaskFinished; + } + + void registerNotifyPeerFinishHandler(std::function const& _notifyPeerFinishHandler) + { + m_notifyPeerFinishHandler = _notifyPeerFinishHandler; + } + + // Note: must store the result serially + void storePSIResult(ppc::io::DataResourceLoader::Ptr const& _resourceLoader, + std::vector const& _data); + + std::function takeFinalizeHandler() { return std::move(m_finalizeHandler); } + + void onTaskException(std::string const& _errorMsg); + bool loadFinished() const { return m_finished.load(); } + + // generate default output-desc for given task + void tryToGenerateDefaultOutputDesc(); + uint64_t taskPendingTime() { return (bcos::utcSteadyTime() - m_taskStartTime); } + + uint32_t sendedDataBatchSize() const { return m_seqList.size(); } + +private: + void removeGeneratedOutputFile(); + +protected: + ppc::protocol::Task::ConstPtr m_task; + ppc::task::TaskResponseCallback m_callback; + bool m_onlySelfRun{false}; + PSIConfig::Ptr m_config; + uint64_t m_taskStartTime = 0; + + // record the task-peer + std::string m_peerID; + + std::function m_worker; + // handler called after the task-finished + std::function m_finalizeHandler; + + // handler called when the sub-task corresponding to the given seq completed + std::function m_onSubTaskFinished; + + std::function m_notifyPeerFinishHandler; + + // the reader + ppc::io::LineReader::Ptr m_reader; + int64_t m_readerParam; + bool m_sqlReader; + io::LineWriter::Ptr m_writer = nullptr; + + // to load logic in segments, prevent memory from filling up + // Note: only file has the segment logic + std::atomic m_currentSeq = {0}; + std::set m_seqList; + mutable bcos::SharedMutex x_seqList; + + uint64_t m_successCount = 0; + uint64_t m_failedCount = 0; + + std::atomic m_taskDone{false}; + std::atomic m_finished = {false}; + + mutable bcos::RecursiveMutex m_mutex; + + const std::string c_resultPath = "result"; + bool m_uploaded = false; +}; + +class TaskStateFactory +{ +public: + using Ptr = std::shared_ptr; + TaskStateFactory() = default; + virtual ~TaskStateFactory() = default; + + virtual TaskState::Ptr createTaskState(ppc::protocol::Task::ConstPtr const& _task, + ppc::task::TaskResponseCallback&& _callback, bool _onlySelfRun = false, + PSIConfig::Ptr _config = nullptr) + { + return std::make_shared( + _task, std::move(_callback), _onlySelfRun, std::move(_config)); + } +}; + +} // namespace ppc::psi diff --git a/cpp/wedpr-computing/ppc-psi/src/psi-framework/interfaces/PSIMessageFactory.h b/cpp/wedpr-computing/ppc-psi/src/psi-framework/interfaces/PSIMessageFactory.h new file mode 100644 index 00000000..e573d05f --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/psi-framework/interfaces/PSIMessageFactory.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2022 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 PSIMessageFactory.h + * @author: yujiechen + * @date 2022-11-9 + */ +#pragma once +#include "PSIMessageInterface.h" +#include +namespace ppc::psi +{ +class PSIMessageFactory +{ +public: + using Ptr = std::shared_ptr; + PSIMessageFactory() = default; + virtual ~PSIMessageFactory() = default; + + virtual PSIMessageInterface::Ptr decodePSIMessage(bcos::bytesConstRef _data) = 0; + virtual PSIMessageInterface::Ptr createPSIMessage(uint32_t _packetType) = 0; + + virtual PSIHandshakeRequest::Ptr createHandshakeRequest(uint32_t _packetType) = 0; + virtual PSIHandshakeResponse::Ptr createHandshakeResponse(uint32_t _packetType) = 0; + + virtual PSITaskNotificationMessage::Ptr createTaskNotificationMessage(uint32_t _packetType) = 0; + virtual PSITaskInfoMsg::Ptr createTaskInfoMessage(uint32_t _packetType) = 0; +}; +} // namespace ppc::psi \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-psi/src/psi-framework/interfaces/PSIMessageInterface.h b/cpp/wedpr-computing/ppc-psi/src/psi-framework/interfaces/PSIMessageInterface.h new file mode 100644 index 00000000..1f779927 --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/psi-framework/interfaces/PSIMessageInterface.h @@ -0,0 +1,169 @@ +/* + * Copyright (C) 2022 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 PSIMessageInterface.h + * @author: yujiechen + * @date 2022-11-9 + */ +#pragma once +#include "ppc-framework/io/DataBatch.h" +#include +#include + +namespace ppc::psi +{ +// the base message +class PSIMessageInterface +{ +public: + using Ptr = std::shared_ptr; + PSIMessageInterface() = default; + virtual ~PSIMessageInterface() = default; + + // the packet-type + virtual uint32_t packetType() const = 0; + // the partyID(the current version is not used, but this field is added to facilitate other + // things in the future (such as permission control, etc.)) + virtual std::string const& partyID() const = 0; + // the resourceID + virtual std::string const& resourceID() const = 0; + + // for compatibility in the future + virtual int32_t version() const = 0; + // get all the data + virtual std::vector takeData() = 0; + virtual void constructData(std::vector const& data, uint64_t startIndex) = 0; + virtual std::vector const& dataIndex() const = 0; + // Note: can't call this after takeData + virtual uint64_t dataSize() const = 0; + // get the data item + // Note: must ensure the object will not released before access the function + virtual bcos::bytesConstRef getData(uint64_t _index) = 0; + virtual uint64_t getDataCount() const = 0; + + virtual void setPartyID(std::string const& _partyID) = 0; + virtual void setResourceID(std::string const& _resourceID) = 0; + virtual void setVersion(int32_t _version) = 0; + virtual void setData(std::vector const& _data) = 0; + virtual void setData(std::vector&& _data) = 0; + virtual void setDataPair(uint64_t pos, uint64_t dataIndex, bcos::bytes const& data) = 0; + virtual void resizeData(uint64_t size) = 0; + // copy [_offset, _offset + _len) into the data-field + virtual void setData( + std::vector const& _data, uint64_t _offset, uint64_t _len) = 0; + + virtual void appendData(bcos::bytes const& _dataItem) = 0; + + virtual void setPacketType(uint32_t _packetType) = 0; + // the dataBatchSize + virtual void setDataBatchCount(uint32_t _dataBatchCount) = 0; + virtual uint32_t dataBatchCount() const = 0; + // encode the PSIMessage + virtual bcos::bytesPointer encode() const = 0; + // decode the PSIMessage + virtual void decode(bcos::bytesConstRef _data) = 0; + + // the field that should not serialized/deserialized, exist only in memory + virtual void setTaskID(std::string const& _taskID) { m_taskID = _taskID; } + virtual void setSeq(uint32_t _seq) { m_seq = _seq; } + virtual void setFrom(std::string const& _from) { m_from = _from; } + virtual void setFromNode(bcos::bytes const& fromNode) { m_fromNode = fromNode; } + virtual bcos::bytes fromNode() const { return m_fromNode; } + + virtual std::string const& taskID() const { return m_taskID; } + virtual uint32_t seq() const { return m_seq; } + virtual std::string const& from() const { return m_from; } + + virtual std::string const& uuid() const { return m_uuid; } + virtual void setUUID(std::string const& _uuid) { m_uuid = _uuid; } + +private: + std::string m_taskID; + int32_t m_seq; + // the agency + std::string m_from; + // the fromNode + bcos::bytes m_fromNode; + + std::string m_uuid; +}; + + +// the psi-task-notification message interface +class PSITaskNotificationMessage : virtual public PSIMessageInterface +{ +public: + using Ptr = std::shared_ptr; + PSITaskNotificationMessage() = default; + ~PSITaskNotificationMessage() override = default; + + virtual void setErrorCode(int32_t _code) = 0; + virtual void setErrorMessage(std::string const& _errorMsg) = 0; + + virtual int32_t errorCode() const = 0; + virtual std::string const& errorMessage() const = 0; +}; + +class PSITaskInfoMsg : virtual public PSIMessageInterface +{ +public: + using Ptr = std::shared_ptr; + PSITaskInfoMsg() = default; + ~PSITaskInfoMsg() override = default; + + virtual std::vector taskList() const = 0; + virtual void setTaskList(std::vector&& _taskList) = 0; + virtual void setTaskList(std::vector const& _taskList) = 0; +}; + +// the psi handshake-request +class PSIHandshakeRequest : virtual public PSIMessageInterface +{ +public: + using Ptr = std::shared_ptr; + PSIHandshakeRequest() = default; + ~PSIHandshakeRequest() override = default; + + virtual void setCurves(std::vector&& _curves) = 0; + virtual void setHashList(std::vector&& _hashList) = 0; + + virtual std::vector const& curves() const = 0; + virtual std::vector const& hashList() const = 0; +}; + +// the psi handshake-response +class PSIHandshakeResponse : virtual public PSIMessageInterface +{ +public: + using Ptr = std::shared_ptr; + PSIHandshakeResponse() = default; + ~PSIHandshakeResponse() override = default; + + virtual void setHashType(int _hashType) = 0; + virtual void setCurve(int _curve) = 0; + + virtual int hashType() const = 0; + virtual int curve() const = 0; +}; + +inline std::string printPSIMessage(PSIMessageInterface::Ptr _msg) +{ + std::ostringstream stringstream; + stringstream << LOG_KV("from", _msg->from()) << LOG_KV("party", _msg->partyID()) + << LOG_KV("task", _msg->taskID()) << LOG_KV("seq", _msg->seq()) + << LOG_KV("resource", _msg->resourceID()) << LOG_KV("type", _msg->packetType()); + return stringstream.str(); +} +} // namespace ppc::psi \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-psi/src/psi-framework/protocol/PSI.tars b/cpp/wedpr-computing/ppc-psi/src/psi-framework/protocol/PSI.tars new file mode 100644 index 00000000..a1f459d5 --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/psi-framework/protocol/PSI.tars @@ -0,0 +1,28 @@ +module ppctars{ + struct TarsCuckooFilter + { + 1 optional int id; + 2 optional vector hash; + 3 optional vector data; + }; + + struct PSIMessage + { + 1 optional int version; + 2 require int packetType; + 3 optional string partyID; + 4 optional string resourceID; + 5 optional vector> data; + 6 optional vector dataIndex; + 7 optional int errorCode; + 8 optional string errorMessage; + 9 optional vector taskList; + 10 optional vector cuckooFilterInfo; + 11 optional int cuckooFilterSize; + 12 optional int dataBatchCount; + 13 optional vector curves; // for PSIHandshakeRequest + 14 optional vector hashList; // for PSIHandshakeRequest + 15 optional int curve; // for PSIHandshakeResponse + 16 optional int hashType; // for PSIHandshakeResponse + }; +}; \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-psi/src/psi-framework/protocol/PSIMessage.cpp b/cpp/wedpr-computing/ppc-psi/src/psi-framework/protocol/PSIMessage.cpp new file mode 100644 index 00000000..336bafdf --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/psi-framework/protocol/PSIMessage.cpp @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2022 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 PSIMessage.cpp + * @author: yujiechen + * @date 2022-11-9 + */ +#include "PSIMessage.h" +#include "wedpr-protocol/tars/Common.h" +#include + +using namespace ppc::psi; +using namespace bcos; + +// destructor the psi message +PSIMessage::~PSIMessage() +{ + m_inner()->data.clear(); + m_inner()->dataIndex.clear(); + std::vector>().swap(m_inner()->data); + std::vector().swap(m_inner()->dataIndex); + MallocExtension::instance()->ReleaseFreeMemory(); +} +// encode the PSIMessage +bytesPointer PSIMessage::encode() const +{ + auto encodedData = std::make_shared(); + tars::TarsOutputStream output; + m_inner()->writeTo(output); + output.getByteBuffer().swap(*encodedData); + return encodedData; +} + +// decode the PSIMessage +void PSIMessage::decode(bytesConstRef _data) +{ + tars::TarsInputStream input; + input.setBuffer((const char*)_data.data(), _data.size()); + m_inner()->readFrom(input); +} \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-psi/src/psi-framework/protocol/PSIMessage.h b/cpp/wedpr-computing/ppc-psi/src/psi-framework/protocol/PSIMessage.h new file mode 100644 index 00000000..ed34d6c9 --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/psi-framework/protocol/PSIMessage.h @@ -0,0 +1,303 @@ +/* + * Copyright (C) 2022 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 PSIMessage.h + * @author: yujiechen + * @date 2022-11-9 + */ +#pragma once +#include "../../Common.h" +#include "../interfaces/PSIMessageFactory.h" +#include "../interfaces/PSIMessageInterface.h" +#include "PSI.h" +#include + +namespace ppc::psi +{ +// Note: this implementation is not thread-safe +class PSIMessage : virtual public PSIMessageInterface +{ +public: + using Ptr = std::shared_ptr; + PSIMessage() : m_inner([inner = ppctars::PSIMessage()]() mutable { return &inner; }) {} + explicit PSIMessage(uint32_t _type) : PSIMessage() { setPacketType(_type); } + explicit PSIMessage(bcos::bytesConstRef _data) : PSIMessage() { decode(_data); } + explicit PSIMessage(std::function _inner) : m_inner(std::move(_inner)) + {} + ~PSIMessage(); + + // the packet-type + uint32_t packetType() const override { return m_inner()->packetType; } + // the partyID(the current version is not used, but this field is added to facilitate other + // things in the future (such as permission control, etc.)) + std::string const& partyID() const override { return m_inner()->partyID; } + std::string const& resourceID() const override { return m_inner()->resourceID; } + // for compatibility in the future + int32_t version() const override { return m_inner()->version; } + // get all the data: not recommend to use this method(only used for ut) + uint64_t dataSize() const override { return m_inner()->data.size(); } + + std::vector takeData() override + { + auto dataSize = m_inner()->data.size(); + std::vector result; + result.resize(dataSize); + for (uint64_t i = 0; i < dataSize; i++) + { + std::move(m_inner()->data[i].begin(), m_inner()->data[i].end(), + std::back_inserter(result[i])); + } + return result; + } + + std::vector const& dataIndex() const override { return m_inner()->dataIndex; } + + void resizeData(uint64_t size) override + { + m_inner()->data.resize(size); + m_inner()->dataIndex.resize(size); + } + + void setDataPair(uint64_t pos, uint64_t dataIndex, bcos::bytes const& data) override + { + m_inner()->dataIndex[pos] = dataIndex; + m_inner()->data[pos].assign(data.begin(), data.end()); + } + + // Note: must ensure the object will not released before access the function + bcos::bytesConstRef getData(uint64_t _index) override + { + auto const& dataItem = m_inner()->data.at(_index); + return bcos::bytesConstRef((const bcos::byte*)(dataItem.data()), dataItem.size()); + } + + uint64_t getDataCount() const override { return m_inner()->data.size(); } + void setPartyID(std::string const& _partyID) override { m_inner()->partyID = _partyID; } + void setResourceID(std::string const& _resourceID) override + { + m_inner()->resourceID = _resourceID; + } + + void setVersion(int32_t _version) override { m_inner()->version = _version; } + void setData(std::vector const& _data) override + { + setData(_data, 0, _data.size()); + } + + void setData(std::vector const& _data, uint64_t _offset, uint64_t _len) override + { + m_inner()->data.clear(); + uint64_t endPos = std::min(_offset + _len, (uint64_t)_data.size()); + m_inner()->data.resize((endPos - _offset)); + uint64_t j = 0; + for (uint64_t i = _offset; i < endPos; i++) + { + m_inner()->data[j].assign(_data.at(i).begin(), _data.at(i).end()); + j++; + } + } + + void setData(std::vector&& _data) override + { + auto dataSize = _data.size(); + m_inner()->data.clear(); + m_inner()->data.resize(dataSize); + for (uint64_t i = 0; i < dataSize; i++) + { + std::move(_data[i].begin(), _data[i].end(), std::back_inserter(m_inner()->data[i])); + } + } + + void constructData(std::vector const& data, uint64_t startIndex) override + { + m_inner()->dataIndex.clear(); + int64_t i = startIndex; + for (auto const& it : data) + { + m_inner()->dataIndex.emplace_back(i); + i++; + } + setData(data); + } + + void appendData(bcos::bytes const& _dataItem) override + { + m_inner()->data.emplace_back(_dataItem.begin(), _dataItem.end()); + } + void setPacketType(uint32_t _packetType) override { m_inner()->packetType = _packetType; } + + void setDataBatchCount(uint32_t _dataBatchCount) override + { + m_inner()->dataBatchCount = _dataBatchCount; + } + uint32_t dataBatchCount() const override { return m_inner()->dataBatchCount; } + + // encode the PSIMessage + bcos::bytesPointer encode() const override; + // decode the PSIMessage + void decode(bcos::bytesConstRef _data) override; + +protected: + std::function m_inner; +}; + +class PSITaskNotificationMessageImpl : virtual public PSITaskNotificationMessage, public PSIMessage +{ +public: + using Ptr = std::shared_ptr; + PSITaskNotificationMessageImpl() : PSIMessage() {} + explicit PSITaskNotificationMessageImpl(uint32_t _type) : PSIMessage(_type) {} + explicit PSITaskNotificationMessageImpl(std::function _inner) + : PSIMessage(std::move(_inner)) + {} + + ~PSITaskNotificationMessageImpl() override = default; + + virtual void setErrorCode(int32_t _code) override { m_inner()->errorCode = _code; } + virtual void setErrorMessage(std::string const& _errorMsg) override + { + m_inner()->errorMessage = _errorMsg; + } + + virtual int32_t errorCode() const override { return m_inner()->errorCode; } + virtual std::string const& errorMessage() const override { return m_inner()->errorMessage; } +}; + +class PSITaskInfoMsgImpl : public PSITaskInfoMsg, public PSIMessage +{ +public: + using Ptr = std::shared_ptr; + PSITaskInfoMsgImpl() : PSIMessage() {} + PSITaskInfoMsgImpl(uint32_t _type) : PSIMessage(_type) {} + explicit PSITaskInfoMsgImpl(std::function _inner) + : PSIMessage(std::move(_inner)) + {} + + ~PSITaskInfoMsgImpl() override = default; + + std::vector taskList() const override { return m_inner()->taskList; } + + void setTaskList(std::vector&& _taskList) override + { + m_inner()->taskList = std::move(_taskList); + } + + void setTaskList(std::vector const& _taskList) override + { + m_inner()->taskList = _taskList; + } +}; + +class PSIHandshakeRequestImpl : public PSIHandshakeRequest, public PSIMessage +{ +public: + using Ptr = std::shared_ptr; + PSIHandshakeRequestImpl() : PSIMessage() {} + PSIHandshakeRequestImpl(uint32_t _type) : PSIMessage(_type) {} + PSIHandshakeRequestImpl(std::function _inner) + : PSIMessage(std::move(_inner)) + {} + ~PSIHandshakeRequestImpl() override = default; + + void setCurves(std::vector&& _curves) override { m_inner()->curves = std::move(_curves); } + void setHashList(std::vector&& _hashList) override + { + m_inner()->hashList = std::move(_hashList); + } + + std::vector const& curves() const override { return m_inner()->curves; } + std::vector const& hashList() const override { return m_inner()->hashList; } +}; + +// the psi handshake-response +class PSIHandshakeResponseImpl : public PSIHandshakeResponse, public PSIMessage +{ +public: + using Ptr = std::shared_ptr; + PSIHandshakeResponseImpl() : PSIMessage() {} + PSIHandshakeResponseImpl(uint32_t _type) : PSIMessage(_type) {} + PSIHandshakeResponseImpl(std::function _inner) + : PSIMessage(std::move(_inner)) + {} + + ~PSIHandshakeResponseImpl() override = default; + + void setHashType(int _hashType) override { m_inner()->hashType = _hashType; } + void setCurve(int _curve) override { m_inner()->curve = _curve; } + + // the selected hash algorithm + int hashType() const override { return m_inner()->hashType; } + // the selected curve + int curve() const override { return m_inner()->curve; } +}; + +// the factory implementation +class PSIMessageFactoryImpl : virtual public PSIMessageFactory +{ +public: + using Ptr = std::shared_ptr; + PSIMessageFactoryImpl() = default; + ~PSIMessageFactoryImpl() override {} + + PSIMessageInterface::Ptr createPSIMessage(uint32_t _packetType) override + { + return std::make_shared(_packetType); + } + + PSITaskNotificationMessage::Ptr createTaskNotificationMessage(uint32_t _packetType) override + { + return std::make_shared(_packetType); + } + + PSITaskInfoMsg::Ptr createTaskInfoMessage(uint32_t _packetType) override + { + return std::make_shared(_packetType); + } + + PSIHandshakeRequest::Ptr createHandshakeRequest(uint32_t _packetType) override + { + return std::make_shared(_packetType); + } + + PSIHandshakeResponse::Ptr createHandshakeResponse(uint32_t _packetType) override + { + return std::make_shared(_packetType); + } + +protected: + virtual PSIMessageInterface::Ptr decodePSIBaseMessage( + std::function _inner) + { + switch (_inner()->packetType) + { + case (uint32_t)PSIPacketType::PSIResultSyncMsg: + return std::make_shared(_inner); + case (uint32_t)PSIPacketType::CancelTaskNotification: + case (uint32_t)PSIPacketType::PSIResultSyncResponse: + case (uint32_t)PSIPacketType::HandshakeSuccess: + return std::make_shared(_inner); + case (uint32_t)PSIPacketType::TaskSyncMsg: + return std::make_shared(_inner); + case (uint32_t)PSIPacketType::HandshakeRequest: + return std::make_shared(_inner); + case (uint32_t)PSIPacketType::HandshakeResponse: + return std::make_shared(_inner); + default: + BOOST_THROW_EXCEPTION(BCOS_ERROR((int)PSIRetCode::UnknownPSIPacketType, + "unknown psi-message-type " + std::to_string(_inner()->packetType))); + } + } +}; +} // namespace ppc::psi \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-psi/src/ra2018-psi/CMakeLists.txt b/cpp/wedpr-computing/ppc-psi/src/ra2018-psi/CMakeLists.txt new file mode 100644 index 00000000..0d00d3ca --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/ra2018-psi/CMakeLists.txt @@ -0,0 +1,3 @@ +file(GLOB_RECURSE SRCS *.cpp) +add_library(${RA2018_PSI_TARGET} ${SRCS}) +target_link_libraries(${RA2018_PSI_TARGET} PUBLIC ${PSI_FRAMEWORK_TARGET} ${TOOLS_TARGET}) \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-psi/src/ra2018-psi/Common.h b/cpp/wedpr-computing/ppc-psi/src/ra2018-psi/Common.h new file mode 100644 index 00000000..b5996cdb --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/ra2018-psi/Common.h @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2022 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 Common.h + * @author: yujiechen + * @date 2022-10-27 + */ +#pragma once +#include "../Common.h" +#include "ppc-framework/Common.h" +#include "ppc-framework/protocol/Task.h" +#include "ppc-tools/src/cuckoo/Cuckoofilter.h" +#include +#include + +#define RA2018_LOG(LEVEL) BCOS_LOG(LEVEL) << LOG_BADGE("PSI: RA2018") + +namespace ppc::psi +{ +using DefaultCukooFilter = + ppc::tools::Cuckoofilter; +using DefaultCukooFilterPtr = + std::shared_ptr>; +// the data-preprocessing command +constexpr static std::string_view DATA_PREPROCESSING_CMD = "data_preprocessing"; +// the psi command +constexpr static std::string_view RUN_PSI_CMD = "ra2018_psi"; + +enum DataPreProcessingOption : int +{ + Insert, + Delete, +}; +inline std::ostream& operator<<(std::ostream& _out, DataPreProcessingOption const& _option) +{ + switch (_option) + { + case DataPreProcessingOption::Insert: + _out << "Insert"; + break; + case DataPreProcessingOption::Delete: + _out << "Delete"; + break; + default: + _out << "UnknownDataPreProcessingOption"; + break; + } + return _out; +} + +enum RA2018Command : int +{ + DATA_PREPROCESSING, + RUN_PSI, +}; +inline std::ostream& operator<<(std::ostream& _out, RA2018Command const& _command) +{ + switch (_command) + { + case RA2018Command::DATA_PREPROCESSING: + _out << "DATA_PREPROCESSING"; + break; + case RA2018Command::RUN_PSI: + _out << "RUN_PSI"; + break; + default: + _out << "UnknownRA2018PSICommand"; + break; + } + return _out; +} +} // namespace ppc::psi \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-psi/src/ra2018-psi/RA2018PSIConfig.h b/cpp/wedpr-computing/ppc-psi/src/ra2018-psi/RA2018PSIConfig.h new file mode 100644 index 00000000..4f79010b --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/ra2018-psi/RA2018PSIConfig.h @@ -0,0 +1,124 @@ +/* + * Copyright (C) 2022 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 RA2018PSIConfig.h + * @author: yujiechen + * @date 2022-10-25 + */ +#pragma once +#include "../PSIConfig.h" +#include "Common.h" +#include "ppc-framework/crypto/Hash.h" +#include "ppc-framework/crypto/RA2018OprfInterface.h" +#include "ppc-framework/protocol/PPCMessageFace.h" +#include "ppc-framework/storage/SQLStorage.h" +#include "protocol/RA2018Message.h" +#include + +namespace ppc::psi +{ +class RA2018PSIConfig : public PSIConfig +{ +public: + using Ptr = std::shared_ptr; + RA2018PSIConfig(std::string const& _selfParty, ppc::front::FrontInterface::Ptr _front, + ppc::crypto::RA2018OprfInterface::Ptr _oprf, ppc::crypto::Hash::Ptr _binHashImpl, + ppc::front::PPCMessageFaceFactory::Ptr _ppcMsgFactory, + ppc::tools::CuckoofilterOption::Ptr _cuckooFilterOption, bcos::ThreadPool::Ptr _threadPool, + ppc::storage::SQLStorage::Ptr _storage, ppc::storage::FileStorage::Ptr _fileStorage, + ppc::io::DataResourceLoader::Ptr _dataResourceLoader, int _holdingMessageMinutes, + uint32_t minNeededMemoryGB = 1, std::string const& _dbName = "ra2018", + uint64_t _cuckooFilterCacheSize = 255 * 1024 * 1024, + uint64_t _ra2018CacheCapacity = 1024 * 1024 * 1024, int _dataBatchSize = -1, + int _threadPoolSize = std::thread::hardware_concurrency()) + : PSIConfig(ppc::protocol::TaskAlgorithmType::RA_PSI_2PC, _selfParty, _front, _ppcMsgFactory, + _dataResourceLoader, _holdingMessageMinutes, minNeededMemoryGB), + m_oprf(std::move(_oprf)), + m_binHashImpl(std::move(_binHashImpl)), + m_ra2018MsgFactory(std::make_shared()), + m_threadPool(std::move(_threadPool)), + m_storage(std::move(_storage)), + m_fileStorage(std::move(_fileStorage)), + m_dbName(_dbName), + m_cuckooFilterOption(std::move(_cuckooFilterOption)), + m_cuckooFilterCacheSize(_cuckooFilterCacheSize), + m_ra2018CacheCapacity(_ra2018CacheCapacity), + m_dataBatchSize(_dataBatchSize) + { + if (!m_threadPool) + { + m_threadPool = std::make_shared("ra2018", _threadPoolSize); + } + } + ~RA2018PSIConfig() override = default; + + std::string const& dbName() const { return m_dbName; } + std::string const& cuckooFilterTableName() const { return m_cuckooFilterTableName; } + void setCukooFilterTableName(std::string const& _tableName) + { + m_cuckooFilterTableName = _tableName; + } + + ppc::storage::SQLStorage::Ptr const& storage() { return m_storage; } + ppc::storage::FileStorage::Ptr const& fileStorage() { return m_fileStorage; } + + bcos::ThreadPool::Ptr const& threadPool() { return m_threadPool; } + + ppc::io::DataResourceLoader::Ptr const& dataResourceLoader() { return m_dataResourceLoader; } + ppc::crypto::RA2018OprfInterface::Ptr const& oprf() const { return m_oprf; } + ppc::crypto::Hash::Ptr const& binHashImpl() const { return m_binHashImpl; } + + // the ra2018 message factory + RA2018MessageFactory::Ptr const& ra2018MsgFactory() const { return m_ra2018MsgFactory; } + ppc::tools::CuckoofilterOption::Ptr const& cuckooFilterOption() const + { + return m_cuckooFilterOption; + } + int64_t dataBatchSize() const { return m_dataBatchSize; } + + uint64_t cuckooFilterCacheSize() const { return m_cuckooFilterCacheSize; } + uint64_t ra2018CacheCapacity() const { return m_ra2018CacheCapacity; } + std::string const& dataPath() const { return m_dataPath; } + +protected: + ppc::crypto::RA2018OprfInterface::Ptr m_oprf; + // the hash-impl used to calculate binary hash(for perf consideration, we default choose md5) + ppc::crypto::Hash::Ptr m_binHashImpl; + // the ra2018 message factory + RA2018MessageFactory::Ptr m_ra2018MsgFactory; + + // the threadPool used to computation + bcos::ThreadPool::Ptr m_threadPool; + // the ppc-privacy-service storage + ppc::storage::SQLStorage::Ptr m_storage; + // the file-storage + ppc::storage::FileStorage::Ptr m_fileStorage; + + // the db to store all data for RA2018 + std::string m_dbName = "ra2018"; + // the cuckoo-filter tableName, stores {data_resource-id, cuckoo-filter-id, cuckoo-filter-data} + std::string m_cuckooFilterTableName = "t_cuckoo"; + + // the cuckooFilterOption + ppc::tools::CuckoofilterOption::Ptr m_cuckooFilterOption; + + uint64_t m_cuckooFilterCacheSize; + uint64_t m_ra2018CacheCapacity = 0; + // default load all data + int64_t m_dataBatchSize = -1; + + std::string m_dataPath = "data"; +}; +} // namespace ppc::psi \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-psi/src/ra2018-psi/RA2018PSIFactory.cpp b/cpp/wedpr-computing/ppc-psi/src/ra2018-psi/RA2018PSIFactory.cpp new file mode 100644 index 00000000..75615833 --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/ra2018-psi/RA2018PSIFactory.cpp @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2022 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 RA2018PSIFactory.cpp + * @author: yujiechen + * @date 2022-11-14 + */ +#include "RA2018PSIFactory.h" +#include "ppc-tools/src/config/PPCConfig.h" + +using namespace ppc::psi; +using namespace ppc::front; +using namespace ppc::crypto; +using namespace ppc::storage; +using namespace ppc::tools; +using namespace ppc::io; + +RA2018PSIImpl::Ptr RA2018PSIFactory::createRA2018PSI(std::string const& _selfParty, + FrontInterface::Ptr _front, PPCConfig::Ptr const& _config, + RA2018OprfInterface::Ptr const& _oprf, Hash::Ptr _binHashImpl, + PPCMessageFaceFactory::Ptr _ppcMsgFactory, SQLStorage::Ptr _storage, + FileStorage::Ptr _fileStorage, bcos::ThreadPool::Ptr _threadPool, + DataResourceLoader::Ptr _dataResourceLoader, uint32_t minNeededMemoryGB) +{ + auto const& ra2018Config = _config->ra2018PSIConfig(); + + auto config = std::make_shared(_selfParty, _front, _oprf, _binHashImpl, + _ppcMsgFactory, ra2018Config.cuckooFilterOption, _threadPool, _storage, _fileStorage, + _dataResourceLoader, _config->holdingMessageMinutes(), minNeededMemoryGB, + ra2018Config.dbName, ra2018Config.cuckooFilterCacheSize, ra2018Config.cacheSize, + ra2018Config.dataBatchSize); + + RA2018PSIStorage::Ptr psiStorage = nullptr; + if (!_config->disableRA2018()) + { + psiStorage = std::make_shared(config); + // init the storage + psiStorage->init(); + } + return std::make_shared(config, psiStorage, 0, false, _config->disableRA2018()); +} diff --git a/cpp/wedpr-computing/ppc-psi/src/ra2018-psi/RA2018PSIFactory.h b/cpp/wedpr-computing/ppc-psi/src/ra2018-psi/RA2018PSIFactory.h new file mode 100644 index 00000000..ab6d2513 --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/ra2018-psi/RA2018PSIFactory.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2022 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 RA2018PSIFactory.h + * @author: yujiechen + * @date 2022-11-14 + */ +#pragma once +#include "RA2018PSIImpl.h" +#include "storage/RA2018PSIStorage.h" +namespace ppc::tools +{ +class PPCConfig; +} +namespace ppc::psi +{ +class RA2018PSIFactory +{ +public: + using Ptr = std::shared_ptr; + RA2018PSIFactory() = default; + virtual ~RA2018PSIFactory() = default; + + virtual RA2018PSIImpl::Ptr createRA2018PSI(std::string const& _selfParty, + ppc::front::FrontInterface::Ptr _front, + std::shared_ptr const& _config, + ppc::crypto::RA2018OprfInterface::Ptr const& _oprf, ppc::crypto::Hash::Ptr _binHashImpl, + ppc::front::PPCMessageFaceFactory::Ptr _ppcMsgFactory, + ppc::storage::SQLStorage::Ptr _storage, ppc::storage::FileStorage::Ptr _fileStorage, + bcos::ThreadPool::Ptr _threadPool, ppc::io::DataResourceLoader::Ptr _dataResourceLoader, + uint32_t minNeededMemoryGB = 1); +}; +} // namespace ppc::psi \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-psi/src/ra2018-psi/RA2018PSIImpl.cpp b/cpp/wedpr-computing/ppc-psi/src/ra2018-psi/RA2018PSIImpl.cpp new file mode 100644 index 00000000..38f19ddb --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/ra2018-psi/RA2018PSIImpl.cpp @@ -0,0 +1,1078 @@ +/* + * Copyright (C) 2022 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 RA2018PSIImpl.cpp + * @author: yujiechen + * @date 2022-10-25 + */ +#include "RA2018PSIImpl.h" +#include "core/CuckoofilterAllocator.h" +#include "core/Ra2018TaskParam.h" +#include "ppc-framework/front/FrontInterface.h" +#include "ppc-framework/protocol/PPCMessageFace.h" + +using namespace ppc::psi; +using namespace ppc::protocol; +using namespace bcos; +using namespace ppc::front; +using namespace ppc::io; +using namespace ppc::task; + +RA2018PSIImpl::RA2018PSIImpl(RA2018PSIConfig::Ptr const& _config, + RA2018PSIStorage::Ptr const& _storage, unsigned _idleTimeMs, bool _waitResult, bool _disabled) + : PSIFramework(_config->ra2018MsgFactory(), _config->dataResourceLoader(), _config, "ra2018psi", + _idleTimeMs), + m_disabled(_disabled), + m_config(_config), + m_storage(_storage), + m_server(std::make_shared(_config)), // create the RA2018PSIServer to support + // fullEvaluate/Evaluate + m_client(std::make_shared(_config, + _config->ra2018CacheCapacity())), // create the RA2018PSIClient to support + // blind/finalize/intersection, support multiple-tasks + m_cuckooFiltersCache(std::make_shared( + _storage, _config->cuckooFilterCacheSize())), // the cuckoo-filters-cache + m_worker(std::make_shared("offline-worker", 1)), + m_waitResult(_waitResult) // notify only when the task-finished or exceptioned +{ + m_notifier = m_client->onReady([&]() { wakeupWorker(); }); +} + +void RA2018PSIImpl::start() +{ + RA2018_LOG(INFO) << LOG_DESC("Start the RA2018PSI"); + // start a thread to execute task + PSIFramework::start(); +} + +void RA2018PSIImpl::stop() +{ + RA2018_LOG(INFO) << LOG_DESC("Stop RA2018PSI"); + if (m_config->threadPool()) + { + m_config->threadPool()->stop(); + } + PSIFramework::stop(); + RA2018_LOG(INFO) << LOG_DESC("RA2018PSI stopped"); +} + +void RA2018PSIImpl::asyncRunTask( + ppc::protocol::Task::ConstPtr _task, TaskResponseCallback&& _onTaskFinished) +{ + if (m_disabled) + { + m_config->front()->notifyTaskInfo(_task->id()); + auto taskResult = std::make_shared(_task->id()); + auto error = BCOS_ERROR_PTR( + (int)RA2018PSIDisabled, "The ra2018-psi has been disabled by this node!"); + RA2018_LOG(WARNING) << LOG_DESC("response task result") << LOG_KV("task", _task) + << LOG_KV("code", error->errorCode()) + << LOG_KV("msg", error->errorMessage()); + auto const& peerParties = _task->getAllPeerParties(); + + auto notifiedError = BCOS_ERROR_PTR( + (int)RA2018PSIDisabled, "The ra2018-psi has been disabled by the peer node!"); + for (auto const& it : peerParties) + { + notifyTaskResult(notifiedError, it.second->id(), _task->id(), "emptyResource"); + } + taskResult->setError(std::move(error)); + _onTaskFinished(std::move(taskResult)); + // erase the task id + m_config->front()->eraseTaskInfo(_task->id()); + return; + } + // parse the task command + auto taskParam = std::make_shared(_task->param()); + auto dataResource = _task->selfParty()->dataResource(); + auto resourceID = dataResource ? dataResource->resourceID() : "empty"; + auto self = weak_from_this(); + auto taskState = m_taskStateFactory->createTaskState( + _task, [self, _task, _onTaskFinished](TaskResult::Ptr&& _result) { + // record the task time + auto result = std::move(_result); + _onTaskFinished(std::move(result)); + RA2018_LOG(INFO) << LOG_DESC("asyncRunTask finished") << printTaskInfo(_task); + }); + auto const& taskID = _task->id(); + // Note: the finalizeHandler will be called no matter task success of failed + taskState->registerFinalizeHandler([self, taskID]() { + auto psi = self.lock(); + if (!psi) + { + return; + } + // erase the cache + psi->m_client->eraseTaskCache(taskID); + // erase task-info from the gateway + psi->m_config->front()->eraseTaskInfo(taskID); + }); + try + { + // Note: the psi-server no need to lock the resource and task + auto error = lockResourceAndRecordTaskState(taskParam->command(), taskState); + // response to the sdk + if (error) + { + // trigger the callback + auto taskResult = std::make_shared(_task->id()); + RA2018_LOG(WARNING) << LOG_DESC("response task result") << LOG_KV("task", _task) + << LOG_KV("code", error->errorCode()) + << LOG_KV("msg", error->errorMessage()); + taskResult->setError(std::move(error)); + _onTaskFinished(std::move(taskResult)); + return; + } + taskState->registerSubTaskFinishedHandler([self]() { + auto psi = self.lock(); + if (!psi) + { + return; + } + psi->m_client->checkAndStoreInterSectionResult(); + psi->wakeupWorker(); + }); + + switch (taskParam->command()) + { + // data-preprocessing + case (int)RA2018Command::DATA_PREPROCESSING: + { + asyncRunDataProcessing( + _task->id(), dataResource, taskParam->operation(), _onTaskFinished); + break; + } + case (int)RA2018Command::RUN_PSI: + { + runPSI(taskState); + break; + } + default: + { + BOOST_THROW_EXCEPTION(BCOS_ERROR((int)PSIRetCode::UnsupportedCommand, + "UnsupportedCommand " + std::to_string(taskParam->command()))); + break; + } + } + } + catch (bcos::Error const& e) + { + RA2018_LOG(WARNING) << LOG_DESC("asyncRunTask exception, cancel the task") + << printTaskInfo(_task) << LOG_KV("code", e.errorCode()) + << LOG_KV("msg", e.errorMessage()); + auto error = std::make_shared(e.errorCode(), e.errorMessage()); + onTaskError("asyncRunTask", std::move(error), taskState->peerID(), _task->id(), resourceID); + } + catch (std::exception const& e) + { + RA2018_LOG(WARNING) << LOG_DESC("asyncRunTask exception, cancel the task") + << printTaskInfo(_task) + << LOG_KV("msg", boost::diagnostic_information(e)); + auto error = std::make_shared(-1, boost::diagnostic_information(e)); + onTaskError("asyncRunTask", std::move(error), taskState->peerID(), _task->id(), resourceID); + } +} + +// run-psi +void RA2018PSIImpl::runPSI(TaskState::Ptr const& _taskState) +{ + auto task = _taskState->task(); + // notify the taskInfo to the front + m_config->front()->notifyTaskInfo(task->id()); + switch (task->selfParty()->partyIndex()) + { + case (int)ppc::protocol::PartyType::Client: + { + runClientPSI(_taskState); + break; + } + // the server do-nothing + case (int)ppc::protocol::PartyType::Server: + { + auto peerParty = checkAndSetPeerInfo(_taskState, false); + if (!peerParty) + { + return; + } + // check the output resource existence when syncResultToPeer + if (_taskState->task()->syncResultToPeer()) + { + _taskState->tryToGenerateDefaultOutputDesc(); + m_config->dataResourceLoader()->checkResourceExists( + task->selfParty()->dataResource()->outputDesc()); + } + RA2018_LOG(INFO) << LOG_DESC("runServerPSI") << LOG_KV("peer", peerParty->id()) + << printTaskInfo(task); + break; + } + default: + { + auto error = std::make_shared((int)PSIRetCode::UnsupportedPartyType, + "UnsupportedPartyType " + std::to_string(task->selfParty()->partyIndex()) + + ", task: " + task->id()); + cancelTask(std::move(error), task->id()); + break; + } + } +} + +void RA2018PSIImpl::asyncRunDataProcessing(std::string const& _taskID, + DataResource::ConstPtr const& _dataResource, int _operation, + TaskResponseCallback const& _callback) +{ + try + { + auto reader = loadData(m_config->dataResourceLoader(), _taskID, _dataResource); + // Note: consider the offline-full-evaluate task takes-long-time, we resonse the result when + // the task submit success + if (!m_waitResult) + { + auto taskResult = std::make_shared(_taskID); + _callback(std::move(taskResult)); + } + + RA2018_LOG(INFO) << LOG_DESC("asyncRunDataProcessing") << LOG_KV("task", _taskID) + << printDataResourceInfo(_dataResource); + // process offlineFullEvaluate + auto startT = utcSteadyTime(); + // Note: we use one worker to process offline-evaluate task in case of it occupies + // too-much cpu resource, and to release the rpc thread resource + auto self = weak_from_this(); + m_worker->enqueue([self, startT, _taskID, _dataResource, _operation, reader, + _callback]() mutable { + auto psi = self.lock(); + if (!psi) + { + return; + } + try + { + psi->offlineFullEvaluate(_dataResource->resourceID(), _operation, std::move(reader), + [self, startT, _dataResource, _taskID, _callback](Error::Ptr&& _error) { + if (_error) + { + RA2018_LOG(WARNING) << LOG_DESC("asyncRunDataProcessing error") + << LOG_KV("task", _taskID) + << LOG_KV("data", _dataResource->resourceID()) + << LOG_KV("code", _error->errorCode()) + << LOG_KV("msg", _error->errorMessage()); + } + auto psi = self.lock(); + if (!psi) + { + return; + } + // remove the dataResource from the processingDataResource pool, so that + // can accept the task related to the data-resource + psi->removeLockingResource(_dataResource->resourceID()); + // erase the task record + psi->removePendingTask(_taskID); + if (psi->m_waitResult) + { + auto taskResult = std::make_shared(_taskID); + _callback(std::move(taskResult)); + } + RA2018_LOG(INFO) + << LOG_DESC("asyncRunDataProcessing success") << LOG_KV("task", _taskID) + << LOG_KV("timecost", (utcSteadyTime() - startT)) + << printDataResourceInfo(_dataResource); + }); + } + catch (std::exception const& e) + { + RA2018_LOG(WARNING) + << LOG_DESC("asyncRunDataProcessing exception") + << LOG_KV("error", boost::diagnostic_information(e)) << LOG_KV("task", _taskID) + << LOG_KV("timecost", (utcSteadyTime() - startT)) + << printDataResourceInfo(_dataResource); + auto error = BCOS_ERROR_PTR(-1, "asyncRunDataProcessing exception: " + + std::string(boost::diagnostic_information(e))); + if (psi->m_waitResult) + { + auto taskResult = std::make_shared(_taskID); + taskResult->setError(error); + _callback(std::move(taskResult)); + } + psi->cancelTask(std::move(error), _taskID); + } + }); + } + catch (std::exception const& e) + { + RA2018_LOG(WARNING) << LOG_DESC("asyncRunDataProcessing exception") + << LOG_KV("error", boost::diagnostic_information(e)); + auto taskResult = std::make_shared(_taskID); + auto error = + BCOS_ERROR_PTR(-1, "asyncRunDataProcessing: " + boost::diagnostic_information(e)); + taskResult->setError(error); + _callback(std::move(taskResult)); + cancelTask(std::move(error), _taskID); + } +} + + +void RA2018PSIImpl::offlineFullEvaluate(std::string const& _resourceID, int _operation, + LineReader::Ptr _reader, std::function _callback) +{ + switch (_operation) + { + // offline data-insert + case DataPreProcessingOption::Insert: + { + // only obtain the cuckoo-filter not full + auto filterInfos = m_storage->getCuckooFilterInfos(_resourceID, true); + evaluateAndInsert(_resourceID, std::move(_reader), std::move(filterInfos), _callback); + break; + } + // offline data-delete + case DataPreProcessingOption::Delete: + { + // get all the filters specified by _resourceID + auto filterInfos = m_storage->getCuckooFilterInfos(_resourceID, false); + evaluateAndDelete(_resourceID, std::move(_reader), std::move(filterInfos), _callback); + break; + } + default: + { + _callback(BCOS_ERROR_PTR( + -1, "Unsupported data pre-processing operation " + std::to_string(_operation))); + break; + } + } +} + +// delete the full-evaluated-data from the cuckoo-filter +void RA2018PSIImpl::evaluateAndDelete(std::string const& _resourceID, LineReader::Ptr _reader, + CuckooFilterInfoSet&& _filterInfos, std::function _callback) +{ + auto sqlReader = (_reader->type() == ppc::protocol::DataResourceType::MySQL); + DataBatch::Ptr data; + if (sqlReader) + { + // load the first column data from the sql + data = _reader->next(0, DataSchema::Bytes); + } + else + { + // load all data from the file(Note: we assume that the amount of data deleted each time is + // not very large) + data = _reader->next(-1, DataSchema::Bytes); + } + + // the total filters expected to store + auto totalStoreCount = std::make_shared>(_filterInfos.size()); + auto callback = [totalStoreCount, _callback, + calledCount = std::make_shared>(0), + failed = std::make_shared>(0)](bcos::Error::Ptr _error) { + (*calledCount)++; + if (_error) + { + (*failed)++; + RA2018_LOG(WARNING) << LOG_DESC("evaluateAndDelete: update cuckoo-filter error") + << LOG_KV("code", _error->errorCode()) + << LOG_KV("msg", _error->errorMessage()); + } + // not all store operations have been finished + if (*calledCount != *totalStoreCount) + { + return; + } + // all the filters stored to backend successfully + if ((*failed) == 0) + { + _callback(nullptr); + return; + } + // with some-filters failed to store to the backend + _callback(BCOS_ERROR_PTR(-1, "evaluateAndDelete failed for update cuckoo-filter error")); + }; + + // evaluate the data + auto result = m_server->fullEvaluate(data); + // delete the result from all the filters + // here load and update cuckoo-filter by batch to decrease the memory overhead + int storeCount = 0; + + uint64_t i = 0; + for (auto const& filterInfo : _filterInfos) + { + auto const& filterID = filterInfo->filterID(); + auto filter = m_storage->loadCuckooFilter(_resourceID, filterID); + if (!filter) + { + i++; + continue; + } + auto orgSize = result.size(); + // delete some elment from the cuckoo-filter + filter->batchDeleteAndGetRemainKeys(result); + // update the modified filter + if (result.size() < orgSize) + { + storeCount++; + // Note: the data has been deleted or the last-cuckoo-filter + if (result.empty() || (i == (_filterInfos.size() - 1))) + { + // reset the totalStoreCount to the real-store-count + // Note: must ensure the real totalStoreCount setted before calls + // asyncUpdateCuckooFilter, otherwise the callback maybe never called + *totalStoreCount = storeCount; + } + auto updatedFilter = std::make_shared(filterID, filterInfo->hash()); + updatedFilter->setCuckooFilter(std::move(filter)); + m_storage->asyncUpdateCuckooFilter(_resourceID, updatedFilter, callback); + } + // all data has been deleted, break + if (result.empty()) + { + break; + } + i++; + } + RA2018_LOG(INFO) << LOG_DESC("evaluateAndDelete finish") << LOG_KV("resource", _resourceID) + << LOG_KV("filterSize", _filterInfos.size()) + << LOG_KV("storeCount", storeCount) << LOG_KV("failedCount", result.size()); +} + +// insert the full-evaluated-data into the cuckoo-filter +void RA2018PSIImpl::evaluateAndInsert(std::string const& _resourceID, LineReader::Ptr _reader, + CuckooFilterInfoSet&& _reusableFilters, std::function _callback) +{ + auto sqlReader = (_reader->type() == ppc::protocol::DataResourceType::MySQL); + // fileReader: load dataBatchSize() elements from the given file + // sqlReader: load the first column + auto nextParam = sqlReader ? 0 : m_config->cuckooFilterOption()->capacity; + // the allocator to create a new cuckoo-filter or load the reusable cuckoo-filter from the + // backend-db + auto allocator = std::make_shared( + m_config, m_storage, _resourceID, _callback, std::move(_reusableFilters)); + RA2018_LOG(INFO) << LOG_DESC("evaluateAndInsert") << LOG_KV("resourceID", _resourceID) + << LOG_KV("nextParam", nextParam); + // Note: should exit when stop + do + { + auto data = _reader->next(nextParam, DataSchema::Bytes); + // all data have been loaded + if (!data) + { + break; + } + // evaluate the data + auto result = m_server->fullEvaluate(data); + uint64_t offset = 0; + // TODO: optimize here without copy + std::set resultSet(result.begin(), result.end()); + // insert and store all the result into cuckoo-filter + do + { + // allocate cuckoo-filter to insert the result + auto filter = allocator->allocate(); + // all elements has been inserted into the cuckoo-filter + if (filter->batchInsert(resultSet)) + { + break; + } + } while (true && m_started); + } while (true && (!sqlReader) && m_started); // Note: the sql only has one-column, the file + // support load by batch + // flush all the memory cuckoo-filter into storage + allocator->flush(); +} + +// sync the cuckoo-filter from the server +// Note: this operation can be enqueue into the threadPool to increase perf +void RA2018PSIImpl::syncCuckooFilter( + std::string const& _peerID, std::string const& _taskID, DataResource::ConstPtr _dataResource) +{ + try + { + // load and init the cuckooFilterState + auto state = m_client->loadCuckooFilterState(_dataResource->resourceID(), true); + state->init(); + + auto filterInfos = m_storage->getCuckooFilterInfos(_dataResource->resourceID(), false); + RA2018_LOG(INFO) << LOG_DESC("syncCuckooFilter") << LOG_KV("task", _taskID) + << LOG_KV("peer", _peerID) << printDataResourceInfo(_dataResource) + << LOG_KV("filterInfos", filterInfos.size()); + requestCuckooFilters(_peerID, _taskID, _dataResource->resourceID(), filterInfos, + (uint32_t)RA2018PacketType::CuckooFilterRequest); + } + catch (std::exception const& e) + { + std::stringstream ss; + ss << LOG_DESC("runPSIClient: syncCuckooFilter exception") << LOG_KV("task", _taskID) + << LOG_KV("peer", _peerID) << printDataResourceInfo(_dataResource) + << LOG_KV("error", boost::diagnostic_information(e)); + auto errorMsg = ss.str(); + auto error = std::make_shared((int)PSIRetCode::syncCuckooFilterError, errorMsg); + RA2018_LOG(WARNING) << errorMsg; + // cancel the task + onTaskError( + "syncCuckooFilter", std::move(error), _peerID, _taskID, _dataResource->resourceID()); + } +} + +// handle the cuckoo-filter response +void RA2018PSIImpl::handleCuckooFilterResponse(PSIMessageInterface::Ptr _msg) +{ + auto ra2018FilterMsg = std::dynamic_pointer_cast(_msg); + RA2018_LOG(INFO) << LOG_DESC("handleCuckooFilterResponse") << printPSIMessage(ra2018FilterMsg) + << LOG_KV("cuckooFilterSize", ra2018FilterMsg->cuckooFilterSize()); + // Note: if the filter has not been changed, the filter will be nullptr + auto const& filterInfo = ra2018FilterMsg->mutableFilterInfo(); + auto state = m_client->loadCuckooFilterState(ra2018FilterMsg->resourceID(), false); + if (state) + { + state->setCuckooFilterSize(ra2018FilterMsg->cuckooFilterSize()); + } + for (auto const& it : filterInfo) + { + handleCuckooFilterResponseItem(ra2018FilterMsg, state, it); + } + m_client->computeIntersection(); + // try to store the result + m_client->checkAndStoreInterSectionResult(); +} + +// TODO: remove the erased cuckoo-filter of the client +bool RA2018PSIImpl::handleCuckooFilterResponseItem(RA2018FilterMessage::Ptr _msg, + CuckooFilterState::Ptr _cuckooFilterState, CuckooFilterInfo::Ptr const& _cuckooFilterInfo) +{ + auto self = weak_from_this(); + auto onHandleFailed = [self, _msg, _cuckooFilterInfo](std::string const& _desc) { + auto psi = self.lock(); + if (!psi) + { + return; + } + std::stringstream ss; + ss << LOG_DESC("handleCuckooFilterResponse failed: ") << _desc + << LOG_KV("task", _msg->taskID()) << LOG_KV("peer", _msg->partyID()) + << LOG_KV("resource", _msg->resourceID()) << _cuckooFilterInfo->desc(); + // not found the hitted cuckoo-filter + // cancel the task + auto errorMsg = ss.str(); + RA2018_LOG(WARNING) << errorMsg; + auto error = BCOS_ERROR_PTR(PSIRetCode::LoadCuckooFilterDataError, std::move(errorMsg)); + + psi->cancelTask(std::move(error), _msg->taskID()); + }; + RA2018_LOG(INFO) << LOG_DESC("handleCuckooFilterResponseItem: receive the cuckooFilter") + << printPSIMessage(_msg) << _cuckooFilterInfo->desc() + << LOG_KV("hit", _cuckooFilterInfo->cuckooFilter() ? false : true); + if (!_cuckooFilterState) + { + onHandleFailed("the task cuckoo-filter resources are not prepared"); + return false; + } + auto cuckooFilterInfo = _cuckooFilterInfo; + if (_cuckooFilterInfo->cuckooFilter()) + { + // filter changed, load into the cache + m_cuckooFiltersCache->insert(_msg->resourceID(), _cuckooFilterInfo); + } + else + { + // without change, load from local cuckoo-filter cache + cuckooFilterInfo = + m_cuckooFiltersCache->query(_msg->resourceID(), _cuckooFilterInfo->filterID()); + // request for the missed cuckoo-filter + // Note: if the server miss the requested cuckoo-filters(the msg type is + // MissingCuckooFilterResponse, no need to request again) + if (!cuckooFilterInfo) + { + if (_msg->packetType() != (uint32_t)RA2018PacketType::MissingCuckooFilterResponse) + { + RA2018_LOG(INFO) + << LOG_DESC( + "Query filter from local storage failed, try to request the " + "cuckoo filter from the server") + << LOG_KV("resourceID", _msg->resourceID()) + << LOG_KV("filterID", _cuckooFilterInfo->filterID()) << printPSIMessage(_msg); + std::set filters; + filters.insert(_cuckooFilterInfo); + // request the missed cuckoo-filter with given seq and cuckooFilterSize when + // local-cuckoo-filter miss or broken + requestCuckooFilters(_msg->from(), _msg->taskID(), _msg->resourceID(), filters, + (uint32_t)RA2018PacketType::MissingCuckooFilterRequest, + _msg->cuckooFilterSize(), _msg->seq()); + } + else + { + RA2018_LOG(INFO) << LOG_DESC( + "Query filter from server storage failed, set " + "load-cuckoo-filter finished") + << LOG_KV("resourceID", _msg->resourceID()) + << LOG_KV("filterID", _cuckooFilterInfo->filterID()) + << printPSIMessage(_msg); + _cuckooFilterState->decreaseCuckooFilterSize(1); + } + } + } + if (cuckooFilterInfo) + { + _cuckooFilterState->appendCuckooFilterInfo(_msg->seq(), std::move(cuckooFilterInfo)); + } + return true; +} + +// the client run-psi +void RA2018PSIImpl::runClientPSI(TaskState::Ptr const& _taskState) +{ + // Note: enforce the peer-data-resource + auto peerParty = checkAndSetPeerInfo(_taskState, true); + if (!peerParty) + { + return; + } + auto const& peerID = peerParty->id(); + auto const& task = _taskState->task(); + auto const& dataResource = task->selfParty()->dataResource(); + RA2018_LOG(INFO) << LOG_DESC("runClientPSI") << printTaskInfo(task) << LOG_KV("peer", peerID); + // check the dataResource + if (!checkDataResourceForSelf(_taskState, peerID, true)) + { + return; + } + if (!_taskState->task()->enableOutputExists()) + { + // Note: if the output-resource already exists, will throw exception + m_config->dataResourceLoader()->checkResourceExists(dataResource->outputDesc()); + } + else + { + m_config->dataResourceLoader()->loadWriter(dataResource->outputDesc(), true); + } + // load the data + auto reader = loadData(m_config->dataResourceLoader(), task->id(), dataResource); + auto sqlReader = (reader->type() == ppc::protocol::DataResourceType::MySQL); + // fileReader: load dataBatchSize() elements from the given file + // sqlReader: load the first column + auto nextParam = sqlReader ? 0 : m_config->dataBatchSize(); + _taskState->setReader(std::move(reader), nextParam); + + // sync the cuckooFilter + auto self = weak_from_this(); + m_config->threadPool()->enqueue([self, peerID, task, peerParty]() { + auto psi = self.lock(); + if (!psi) + { + return; + } + psi->syncCuckooFilter(peerID, task->id(), peerParty->dataResource()); + }); + // blind data + auto cuckooFilterResourceID = peerParty->dataResource()->resourceID(); + blindData(cuckooFilterResourceID, _taskState); + + if (!_taskState->sqlReader()) + { + // since one call to blindData may not handle all data of a task for cache limit + // add the blindData to taskState worker to execute looply + auto weakTaskState = std::weak_ptr(_taskState); + _taskState->setWorker([weakTaskState, cuckooFilterResourceID, self]() { + auto psi = self.lock(); + if (!psi) + { + return; + } + auto state = weakTaskState.lock(); + if (!state) + { + return; + } + psi->blindData(cuckooFilterResourceID, state); + }); + } +} + +// load data from DataResource and blind the plainData into cipher +// Note: the thread-pool executed function should not throw exception +bool RA2018PSIImpl::blindData( + std::string const& _cuckooFilterResourceID, TaskState::Ptr const& _taskState) +{ + if (m_client->isFull()) + { + return false; + } + auto dataResource = _taskState->task()->selfParty()->dataResource(); + auto self = weak_from_this(); + auto sendCallback = [self, _taskState, dataResource](Error::Ptr&& _error) { + if (!_error || _error->errorCode() == 0) + { + return; + } + auto psi = self.lock(); + if (!psi) + { + return; + } + RA2018_LOG(WARNING) << LOG_DESC("send evaluate request error") + << LOG_KV("peer", _taskState->peerID()) + << printTaskInfo(_taskState->task()) + << LOG_KV("code", _error->errorCode()) + << LOG_KV("msg", _error->errorMessage()); + psi->cancelTask(std::move(_error), _taskState->task()->id()); + }; + // put the task into the thread-pool + m_config->threadPool()->enqueue([self, _cuckooFilterResourceID, _taskState, dataResource, + sendCallback]() { + auto psi = self.lock(); + if (!psi) + { + return; + } + try + { + auto task = psi->getTaskByID(_taskState->task()->id()); + // the task has already been canceled + if (!task) + { + return; + } + if (_taskState->loadFinished()) + { + return; + } + do + { + int32_t seq = 0; + DataBatch::Ptr dataBatch = nullptr; + // Note: the setFinished/allocateSeq must be atomic, because they are used to + // judge whether the task is finished + { + bcos::Guard l(psi->m_mutex); + // Note: next is not thread-safe + dataBatch = + _taskState->reader()->next(_taskState->readerParam(), DataSchema::Bytes); + if (!dataBatch) + { + _taskState->setFinished(true); + break; + } + seq = _taskState->allocateSeq(); + if (_taskState->sqlReader()) + { + _taskState->setFinished(true); + } + } + auto dataBatchSize = dataBatch->size(); + auto ret = psi->m_client->insertCache(_cuckooFilterResourceID, + _taskState->task()->id(), _taskState, dataResource, seq, std::move(dataBatch)); + // blind error for insert the cache failed(the cache already exists) + if (!ret.first && ret.second != nullptr) + { + auto errorMsg = "The task " + _taskState->task()->id() + + " is in-processing! Cancel the repeated task!"; + auto error = BCOS_ERROR_PTR((int)PSIRetCode::TaskInProcessing, errorMsg); + psi->onTaskError("blindData", std::move(error), _taskState->peerID(), + _taskState->task()->id(), _cuckooFilterResourceID); + break; + } + auto cacheItem = ret.second; + RA2018_LOG(INFO) << LOG_DESC("blindData") << printTaskInfo(_taskState->task()) + << LOG_KV("seq", seq) << LOG_KV("dataSize", dataBatchSize) + << LOG_KV("cacheCapacity", psi->m_client->capacity()); + // the cache is full + if (!cacheItem) + { + break; + } + // trigger blind operation + auto blindedData = cacheItem->blind(); + // send the evaluate request + auto msg = psi->m_config->ra2018MsgFactory()->createRA2018FilterMessage( + (uint32_t)RA2018PacketType::EvaluateRequest); + RA2018_LOG(INFO) << LOG_DESC("EvaluateRequest") << printTaskInfo(_taskState->task()) + << LOG_KV("seq", seq) << LOG_KV("dataSize", blindedData.size()); + msg->setResourceID(dataResource->resourceID()); + msg->setData(std::move(blindedData)); + psi->m_config->generateAndSendPPCMessage( + _taskState->peerID(), _taskState->task()->id(), msg, sendCallback, seq); + } while (!_taskState->sqlReader() && psi->m_started); + } + catch (std::exception const& e) + { + std::stringstream ss; + ss << LOG_DESC("blindData exception") << printTaskInfo(_taskState->task()) + << LOG_KV("error", boost::diagnostic_information(e)); + auto errorMsg = ss.str(); + auto error = std::make_shared((int)PSIRetCode::BlindDataError, errorMsg); + RA2018_LOG(WARNING) << errorMsg; + // cancel the task + psi->onTaskError("blindData", std::move(error), _taskState->peerID(), + _taskState->task()->id(), + _taskState->task()->selfParty()->dataResource()->resourceID()); + } + }); + return true; +} + +// handle the evaluate data responsed from the server, try to finalize and intersection +void RA2018PSIImpl::handleEvaluateResponse(PSIMessageInterface::Ptr _msg) +{ + auto evaluatedData = _msg->takeData(); + RA2018_LOG(INFO) << LOG_DESC("handleEvaluateResponse") << printPSIMessage(_msg) + << LOG_KV("evaluatedSize", evaluatedData.size()); + auto clientCache = m_client->cache(_msg->taskID(), _msg->seq()); + // the task has been canceled + if (!clientCache) + { + return; + } + // finliaize the evaluated-data + clientCache->finalize(evaluatedData); + // try to intersection + clientCache->computeIntersection(); + // try to store the result + m_client->checkAndStoreInterSectionResult(); +} + +// the cuckoo-filter of the client has been missed or broken +void RA2018PSIImpl::handleMissedCuckooFilterRequest(PSIMessageInterface::Ptr _msg) +{ + RA2018_LOG(INFO) << LOG_DESC("handleMissedCuckooFilterRequest") << printPSIMessage(_msg); + auto cuckooFilterRequestMsg = std::dynamic_pointer_cast(_msg); + auto const& filterInfos = cuckooFilterRequestMsg->filterInfo(); + for (auto const& it : filterInfos) + { + auto filterData = m_storage->loadCuckooFilterData(_msg->resourceID(), it->filterID()); + RA2018_LOG(INFO) + << LOG_DESC("handleMissedCuckooFilterRequest: load cuckoo-filter from the storage") + << LOG_KV("resource", _msg->resourceID()) << it->desc() + << LOG_KV("size", filterData.size()); + it->setCuckooFilterData(std::move(filterData)); + responseCuckooFilter((uint32_t)(RA2018PacketType::MissingCuckooFilterResponse), _msg, it, + cuckooFilterRequestMsg->cuckooFilterSize(), _msg->seq()); + } +} + +// receive cuckoo-filter request, response the delta-cuckoo-filter +void RA2018PSIImpl::handleCuckooFilterRequest(PSIMessageInterface::Ptr _msg) +{ + auto startT = utcSteadyTime(); + auto cuckooFilterRequestMsg = std::dynamic_pointer_cast(_msg); + auto& filterInfo = cuckooFilterRequestMsg->mutableFilterInfo(); + // load the local cuckooFilterInfo + auto localCuckooFilterInfo = m_storage->getCuckooFilterInfos(_msg->resourceID(), false); + // server miss the cukoo-filter + if (localCuckooFilterInfo.empty()) + { + auto errorMessage = + "the server's data has not been processed offline, the intersection cannot be " + "performed at present! Please trigger the offline-data-process firstly!"; + RA2018_LOG(INFO) << LOG_DESC("handleCuckooFilterRequest:") << errorMessage + << printPSIMessage(_msg) << LOG_KV("clientFilterSize", filterInfo.size()) + << LOG_KV("localCuckooFilter", localCuckooFilterInfo.size()); + auto error = + std::make_shared((int)PSIRetCode::NotOfflineFullEvaluated, errorMessage); + // cancel the task and notify the peer + onTaskError("handleCuckooFilterRequest", std::move(error), _msg->from(), _msg->taskID(), + _msg->resourceID()); + return; + } + RA2018_LOG(INFO) << LOG_DESC("handleCuckooFilterRequest") << printPSIMessage(_msg) + << LOG_KV("clientFilterSize", filterInfo.size()) + << LOG_KV("localCuckooFilter", localCuckooFilterInfo.size()); + std::vector responseCuckooFilters; + for (auto const& filter : filterInfo) + { + auto it = localCuckooFilterInfo.find(filter); + // the filter is not change + if (it != localCuckooFilterInfo.end()) + { + // put the entry into the repsonse-filter-list with empty cuckoo-filter, which + // represented that the filter is not changed + responseCuckooFilters.emplace_back(*it); + // erase the hitted entry from the local + localCuckooFilterInfo.erase(it); + } + } + RA2018_LOG(INFO) << LOG_DESC( + "handleCuckooFilterRequest: load the missed filter from the storage") + << printPSIMessage(_msg) + << LOG_KV("hittedFilters", responseCuckooFilters.size()) + << LOG_KV("missedFilters", localCuckooFilterInfo.size()); + for (auto const& it : localCuckooFilterInfo) + { + auto filterData = m_storage->loadCuckooFilterData(_msg->resourceID(), it->filterID()); + if (filterData.empty()) + { + continue; + } + RA2018_LOG(INFO) << LOG_DESC( + "handleCuckooFilterRequest: load cuckoo-filter from the storage") + << LOG_KV("resource", _msg->resourceID()) << it->desc() + << LOG_KV("size", filterData.size()); + it->setCuckooFilterData(std::move(filterData)); + // the missed entry with cuckoo-filter-data + responseCuckooFilters.emplace_back(it); + } + // response to client + // Note: for the network-msg-size limit, we send the one-cuckoo-filter per-network-msg + size_t seq = 1; + for (uint64_t i = 0; i < responseCuckooFilters.size(); i++) + { + responseCuckooFilter((uint32_t)RA2018PacketType::CuckooFilterResponse, _msg, + responseCuckooFilters.at(i), responseCuckooFilters.size(), seq); + seq++; + } + RA2018_LOG(INFO) << LOG_DESC("handleCuckooFilterRequest success") + << LOG_KV("responsedCuckooFilters", responseCuckooFilters.size()) + << LOG_KV("timecost", (utcSteadyTime() - startT)) << printPSIMessage(_msg); +} + +void RA2018PSIImpl::responseCuckooFilter(uint32_t _responseType, + PSIMessageInterface::Ptr const& _msg, CuckooFilterInfo::Ptr const& _filterInfo, + uint64_t _filterInfoSize, size_t _seq) +{ + auto cuckooFilterResponseMsg = + m_config->ra2018MsgFactory()->createRA2018FilterMessage(_responseType); + cuckooFilterResponseMsg->appendFilterInfo(_filterInfo); + cuckooFilterResponseMsg->setResourceID(_msg->resourceID()); + cuckooFilterResponseMsg->setPartyID(m_config->selfParty()); + cuckooFilterResponseMsg->setCuckooFilterSize(_filterInfoSize); + RA2018_LOG(INFO) << LOG_DESC("handleCuckooFilterRequest: response cuckoo-filter") + << printPSIMessage(_msg) << LOG_KV("seq", _seq) << _filterInfo->desc(); + auto self = weak_from_this(); + m_config->generateAndSendPPCMessage( + _msg->from(), _msg->taskID(), cuckooFilterResponseMsg, + [self, _msg](bcos::Error::Ptr&& _error) { + if (!_error || _error->errorCode() == 0) + { + return; + } + auto psi = self.lock(); + if (!psi) + { + return; + } + // TODO: retry or cancel task + psi->onTaskError("handleCuckooFilterRequest: response cuckoo-filters", + std::move(_error), _msg->from(), _msg->taskID(), _msg->resourceID()); + }, + _seq); +} + +void RA2018PSIImpl::handleEvaluateRequest(PSIMessageInterface::Ptr _msg) +{ + auto startT = utcSteadyTime(); + auto&& blindedData = _msg->takeData(); + RA2018_LOG(INFO) << LOG_DESC("handleEvaluateRequest") << printPSIMessage(_msg) + << LOG_KV("blindDataItem", blindedData.size()); + // evaluate the blindedData + auto evaluatedData = m_server->evaluate(blindedData); + // generate ra2018-message, response the evaluated-data to the client + auto response = m_config->ra2018MsgFactory()->createPSIMessage( + (uint32_t)RA2018PacketType::EvaluateResponse); + response->setData(std::move(evaluatedData)); + response->setResourceID(_msg->resourceID()); + response->setPartyID(m_config->selfParty()); + auto self = weak_from_this(); + // Note: must specified the seq here + m_config->generateAndSendPPCMessage( + _msg->from(), _msg->taskID(), response, + [self, _msg](bcos::Error::Ptr&& _error) { + if (!_error || _error->errorCode() == 0) + { + return; + } + auto psi = self.lock(); + if (!psi) + { + return; + } + psi->onTaskError("handleEvaluateRequest: response evaluated-data", std::move(_error), + _msg->from(), _msg->taskID(), _msg->resourceID()); + }, + _msg->seq()); + RA2018_LOG(INFO) << LOG_DESC("handleEvaluateRequest success") << printPSIMessage(_msg) + << LOG_KV("timecost", (utcSteadyTime() - startT)); +} + +void RA2018PSIImpl::handlePSIMsg(PSIMessageInterface::Ptr _msg) +{ + if (m_disabled) + { + handlePSIFrameworkMsg(_msg); + return; + } + // check the task status + if (!checkPSIMsg(_msg)) + { + return; + } + // prioritize lightweight messages + if (handlePSIFrameworkMsg(_msg)) + { + return; + } + auto self = weak_from_this(); + m_config->threadPool()->enqueue([self, _msg]() { + auto psi = self.lock(); + if (!psi) + { + return; + } + try + { + switch (_msg->packetType()) + { + case (uint32_t)RA2018PacketType::CuckooFilterRequest: + { + psi->handleCuckooFilterRequest(_msg); + break; + } + case (uint32_t)RA2018PacketType::MissingCuckooFilterRequest: + { + psi->handleMissedCuckooFilterRequest(_msg); + break; + } + case (uint32_t)RA2018PacketType::MissingCuckooFilterResponse: + case (uint32_t)RA2018PacketType::CuckooFilterResponse: + { + psi->handleCuckooFilterResponse(_msg); + break; + } + case (uint32_t)RA2018PacketType::EvaluateRequest: + { + psi->handleEvaluateRequest(_msg); + break; + } + case (uint32_t)RA2018PacketType::EvaluateResponse: + { + psi->handleEvaluateResponse(_msg); + break; + } + default: + { + RA2018_LOG(WARNING) + << LOG_DESC("Unsupported packetType ") << (int)_msg->packetType(); + break; + } + } + } + catch (std::exception const& e) + { + RA2018_LOG(WARNING) << LOG_DESC("handlePSIMsg exception") + << LOG_KV("packetType", _msg->packetType()) << printPSIMessage(_msg) + << LOG_KV("error", boost::diagnostic_information(e)); + auto error = BCOS_ERROR_PTR((int)PSIRetCode::HandleTaskError, + "Task " + _msg->taskID() + " error for " + boost::diagnostic_information(e)); + psi->onTaskError("handlePSIMsg", std::move(error), _msg->from(), _msg->taskID(), + "emptyDataResource"); + } + }); +} \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-psi/src/ra2018-psi/RA2018PSIImpl.h b/cpp/wedpr-computing/ppc-psi/src/ra2018-psi/RA2018PSIImpl.h new file mode 100644 index 00000000..c3cf9a3c --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/ra2018-psi/RA2018PSIImpl.h @@ -0,0 +1,183 @@ +/* + * Copyright (C) 2022 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 RA2018PSIImpl.h + * @author: yujiechen + * @date 2022-10-25 + */ +// +// server client +// Offline +// FullEvaluate +// CF.insert(evaluated items) +// send CF +// -----------------------> +// ====================================================== +// Online +// Blind +// blinded items(batch_size) +// <---------------------- +// Evaluate +// evaluated items +// -----------------------> +// Finalize +// ======================================================= +// Intersection +#pragma once +#include "../psi-framework/PSIFramework.h" +#include "../psi-framework/TaskState.h" +#include "RA2018PSIConfig.h" +#include "core/CuckooFiltersCache.h" +#include "core/RA2018PSIClient.h" +#include "core/RA2018PSIServer.h" +#include "ppc-framework/protocol/Task.h" +#include "storage/RA2018PSIStorage.h" +#include +#include + +namespace ppc::psi +{ +class RA2018PSIImpl : public PSIFramework, public std::enable_shared_from_this +{ +public: + using Ptr = std::shared_ptr; + RA2018PSIImpl(RA2018PSIConfig::Ptr const& _config, RA2018PSIStorage::Ptr const& _storage, + unsigned _idleTimeMs = 0, bool _waitResult = false, bool _disabled = false); + ~RA2018PSIImpl() override = default; + + // run task + void asyncRunTask(ppc::protocol::Task::ConstPtr _task, + ppc::task::TaskResponseCallback&& _onTaskFinished) override; + + void start() override; + void stop() override; + +protected: + // run data-processing task to generate and store cuckoo-filter + void asyncRunDataProcessing(std::string const& _taskID, + ppc::protocol::DataResource::ConstPtr const& _dataResource, int _operation, + ppc::task::TaskResponseCallback const& _callback); + // run psi task to generate data-intersection + virtual void runPSI(TaskState::Ptr const& _taskState); + virtual void runClientPSI(TaskState::Ptr const& _taskState); + + virtual void offlineFullEvaluate(std::string const& _resourceID, int _operation, + ppc::io::LineReader::Ptr _reader, std::function _callback); + + virtual void evaluateAndInsert(std::string const& _resourceID, ppc::io::LineReader::Ptr _reader, + CuckooFilterInfoSet&& _reusableFilters, std::function _callback); + virtual void evaluateAndDelete(std::string const& _resourceID, ppc::io::LineReader::Ptr _reader, + CuckooFilterInfoSet&& _filterInfos, std::function _callback); + + /////// the function to handle all ra2018 mesage + void handlePSIMsg(PSIMessageInterface::Ptr _msg) override; + + /////// online PSI: client + // sync the cuckoo-filter from the server + virtual void syncCuckooFilter(std::string const& _peerID, std::string const& _taskID, + ppc::protocol::DataResource::ConstPtr _dataResource); + // handle the cuckoo-filter response + virtual void handleCuckooFilterResponse(PSIMessageInterface::Ptr _msg); + virtual bool handleCuckooFilterResponseItem(RA2018FilterMessage::Ptr _msg, + CuckooFilterState::Ptr _cuckooFilterState, CuckooFilterInfo::Ptr const& _cuckooFilterInfo); + // load data from DataResource and blind the plainData into cipher + virtual bool blindData( + std::string const& _cuckooFilterResourceID, TaskState::Ptr const& _taskState); + // handle the evaluate data responsed from the server, try to finalize and intersection + virtual void handleEvaluateResponse(PSIMessageInterface::Ptr _msg); + + + /////// online PSI: Server + // receive cuckoo-filter request, response the delta-cuckoo-filter + virtual void handleCuckooFilterRequest(PSIMessageInterface::Ptr _msg); + virtual void handleMissedCuckooFilterRequest(PSIMessageInterface::Ptr _msg); + // receive the evaluate request, evaluate and response + virtual void handleEvaluateRequest(PSIMessageInterface::Ptr _msg); + + // TODO: check this logic + bool needLockResource(int _command, int _partyType) override + { + // Note: the psi server no need to lock the resource and record the pendingTasks + if (_command == RA2018Command::RUN_PSI && + _partyType == (int)ppc::protocol::PartyType::Server) + { + return false; + } + return true; + } + + void responseCuckooFilter(uint32_t _responseType, PSIMessageInterface::Ptr const& _msg, + CuckooFilterInfo::Ptr const& _filterInfo, uint64_t _filterInfoSize, size_t _seq); + + template + void requestCuckooFilters(std::string const& _peerID, std::string const& _taskID, + std::string const& _resourceID, T const& _filterInfos, uint32_t _type, + int64_t _cuckooFilterSize = 0, uint32_t _seq = 0) + { + auto ra2018Msg = m_config->ra2018MsgFactory()->createRA2018FilterMessage(_type); + std::vector filterInfoList(_filterInfos.begin(), _filterInfos.end()); + ra2018Msg->setPartyID(m_config->selfParty()); + ra2018Msg->setFilterInfo(std::move(filterInfoList)); + ra2018Msg->setResourceID(_resourceID); + ra2018Msg->setCuckooFilterSize(_cuckooFilterSize); + auto self = weak_from_this(); + m_config->generateAndSendPPCMessage( + _peerID, _taskID, ra2018Msg, + [self, _peerID, _taskID, _resourceID](bcos::Error::Ptr&& _error) { + if (!_error || _error->errorCode() == 0) + { + return; + } + auto psi = self.lock(); + if (!psi) + { + return; + } + psi->onTaskError("requestCuckooFilters: send cuckoo-filter request", + std::move(_error), _peerID, _taskID, _resourceID); + }, + _seq); + } + + // receive the handshake response + void onHandshakeResponse(PSIMessageInterface::Ptr const& _msg) override + { + throw std::runtime_error("RA2018PSIImpl: unimplemented onHandshakeResponse!"); + } + // receive the handshake request + void onHandshakeRequest(PSIMessageInterface::Ptr const& _msg) override + { + throw std::runtime_error("RA2018PSIImpl: unimplemented onHandshakeRequest!"); + } + +protected: + bool m_disabled = false; + RA2018PSIConfig::Ptr m_config; + RA2018PSIStorage::Ptr m_storage; + RA2018PSIServer::Ptr m_server; + RA2018PSIClient::Ptr m_client; + // the cuckoo-filter cache + // cache for psi-client + CuckooFiltersCache::Ptr m_cuckooFiltersCache; + + // the handler triggered when the RA2018PSIClient capacity decreased or some tasks execute + // success + bcos::Handler<> m_notifier; + + bcos::ThreadPool::Ptr m_worker; + // the flag means that response to the sdk once handling the task or after the task completed + bool m_waitResult; +}; +} // namespace ppc::psi diff --git a/cpp/wedpr-computing/ppc-psi/src/ra2018-psi/core/CuckooFilterInfo.h b/cpp/wedpr-computing/ppc-psi/src/ra2018-psi/core/CuckooFilterInfo.h new file mode 100644 index 00000000..ceea025b --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/ra2018-psi/core/CuckooFilterInfo.h @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2022 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 CuckooFilterInfo.h + * @author: yujiechen + * @date 2022-11-10 + */ +#pragma once +#include "../Common.h" +#include +#include + +namespace ppc::psi +{ +class CuckooFilterInfo +{ +public: + using Ptr = std::shared_ptr; + CuckooFilterInfo(int32_t _filterID) : m_filterID(_filterID) {} + CuckooFilterInfo(int32_t _filterID, bcos::bytes const& _hash) + : m_filterID(_filterID), m_hash(_hash) + {} + + CuckooFilterInfo( + int32_t _filterID, bcos::bytes const& _hash, DefaultCukooFilterPtr const& _cuckooFilter) + : CuckooFilterInfo(_filterID, _hash) + { + m_cuckooFilter = _cuckooFilter; + } + + int32_t filterID() const { return m_filterID; } + bcos::bytes const& hash() const { return m_hash; } + + DefaultCukooFilterPtr cuckooFilter() const { return m_cuckooFilter; } + + bcos::bytes const& cuckooFilterData() const { return m_cuckooFilterData; } + + bool dirty() const { return m_dirty; } + + void setDirty(bool _dirty) { m_dirty = _dirty; } + void setCuckooFilter(DefaultCukooFilterPtr&& _cuckooFilter) + { + m_cuckooFilter = std::move(_cuckooFilter); + } + void setCuckooFilterData(bcos::bytes&& _data) { m_cuckooFilterData = std::move(_data); } + void setFilterID(int32_t _filterID) { m_filterID = _filterID; } + + void setHash(bcos::bytes const& _hash) { m_hash = _hash; } + void setHash(bcos::bytes&& _hash) { m_hash = std::move(_hash); } + + inline std::string desc() const + { + std::stringstream oss; + oss << LOG_KV("id", m_filterID) << LOG_KV("hash", bcos::toHex(m_hash)); + return oss.str(); + } + +private: + int32_t m_filterID; + bcos::bytes m_hash; + // Note: in some cases, no need to deserialize the cuckoo-filter + DefaultCukooFilterPtr m_cuckooFilter; + bcos::bytes m_cuckooFilterData; + + bool m_dirty = false; + + bcos::bytes m_emptyCuckooFilterData; +}; + +struct CuckooFilterInfoComparator +{ + bool operator()(const CuckooFilterInfo::Ptr& _left, const CuckooFilterInfo::Ptr& _right) const + { + if (_left->filterID() == _right->filterID()) + { + return _left->hash() < _right->hash(); + } + return (_left->filterID() < _right->filterID()); + } +}; +using CuckooFilterInfoSet = std::set; +} // namespace ppc::psi \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-psi/src/ra2018-psi/core/CuckooFilterState.h b/cpp/wedpr-computing/ppc-psi/src/ra2018-psi/core/CuckooFilterState.h new file mode 100644 index 00000000..d2632e11 --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/ra2018-psi/core/CuckooFilterState.h @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2022 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 CuckooFilterState.h + * @author: yujiechen + * @date 2022-11-8 + */ +#pragma once +#include "../Common.h" +#include + +namespace ppc::psi +{ +class CuckooFilterState +{ +public: + using Ptr = std::shared_ptr; + CuckooFilterState(std::string const& _resourceID) : m_resourceID(_resourceID) {} + virtual ~CuckooFilterState() = default; + + std::string const& resourceID() const { return m_resourceID; } + // Note: the state will only been accessed by one task with _resourceID + std::map const& cuckooFilterInfos() const + { + bcos::ReadGuard l(x_cuckooFilterInfos); + return m_cuckooFilterInfos; + } + // the resource fetched all cuckoo-filters or not + bool fetchFinish() const + { + if (m_cuckooFilterSize.load() == -1) + { + return false; + } + bcos::ReadGuard l(x_receivedCuckooFilter); + if ((int32_t)m_receivedCuckooFilter.size() == m_cuckooFilterSize.load()) + { + return true; + } + return false; + } + + void decreaseCuckooFilterSize(int32_t _decreasedCuckooFilterSize) + { + m_cuckooFilterSize -= _decreasedCuckooFilterSize; + } + + void init() + { + bcos::WriteGuard lock(x_receivedCuckooFilter); + m_receivedCuckooFilter.clear(); + m_cuckooFilterSize.store(-1); + } + + void appendCuckooFilterInfo(uint32_t _seq, CuckooFilterInfo::Ptr&& _cuckooFilterInfo) + { + { + bcos::WriteGuard lock(x_receivedCuckooFilter); + m_receivedCuckooFilter.insert(_seq); + RA2018_LOG(INFO) << LOG_DESC("appendCuckooFilterInfo") << LOG_KV("seq", _seq) + << LOG_KV("receivedSize", m_receivedCuckooFilter.size()) + << LOG_KV("expectedSize", m_cuckooFilterSize); + } + auto const& filterID = _cuckooFilterInfo->filterID(); + // Note: not update the old-cuckoo-filter when hit + bcos::UpgradableGuard l(x_cuckooFilterInfos); + if (m_cuckooFilterInfos.count(filterID) && + m_cuckooFilterInfos.at(filterID)->hash() == _cuckooFilterInfo->hash()) + { + return; + } + bcos::UpgradeGuard ul(l); + m_cuckooFilterInfos[filterID] = _cuckooFilterInfo; + } + + void setCuckooFilterSize(int32_t _cuckooFilterSize) + { + m_cuckooFilterSize.store(_cuckooFilterSize); + } + +private: + std::string m_resourceID; + // the total-cuckoo-filters of the given resourceID + std::atomic m_cuckooFilterSize = {0}; + + // record the loaded cuckoo-filters, update when the filterID hitted + std::map m_cuckooFilterInfos; + mutable bcos::SharedMutex x_cuckooFilterInfos; + + // record the fetched cuckoo-filter + std::set m_receivedCuckooFilter; + mutable bcos::SharedMutex x_receivedCuckooFilter; +}; +} // namespace ppc::psi \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-psi/src/ra2018-psi/core/CuckooFiltersCache.cpp b/cpp/wedpr-computing/ppc-psi/src/ra2018-psi/core/CuckooFiltersCache.cpp new file mode 100644 index 00000000..8bed4c14 --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/ra2018-psi/core/CuckooFiltersCache.cpp @@ -0,0 +1,223 @@ +/* + * Copyright (C) 2022 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 CuckooFiltersCache.cpp + * @author: yujiechen + * @date 2022-11-10 + */ +#include "CuckooFiltersCache.h" + +using namespace ppc::psi; +using namespace bcos; + +bool CuckooFiltersCache::insert( + std::string const& _resourceID, CuckooFilterInfo::Ptr const& _filter) +{ + insertWithoutEvict(_resourceID, std::move(_filter)); + return evict(); +} + +CuckooFilterInfo::Ptr CuckooFiltersCache::query(std::string const& _resourceID, int32_t _filterID) +{ + auto filterInfo = queryWithoutEvict(_resourceID, _filterID); + evict(); + return filterInfo; +} + +// insert a cuckoo-filter into the cache, flush the last-element from m_resourceQueue if cache-full +void CuckooFiltersCache::insertWithoutEvict( + std::string const& _resourceID, CuckooFilterInfo::Ptr const& _filter) +{ + UpgradableGuard l(x_mutex); + auto const& filterID = _filter->filterID(); + auto it = m_resourceToCuckooFilters.find(_resourceID); + if (it != m_resourceToCuckooFilters.end()) + { + auto pCuckooFilter = it->second.find(filterID); + if (pCuckooFilter != it->second.end()) + { + auto currentFilter = pCuckooFilter->second; + if (_filter->hash() == currentFilter->hash()) + { + RA2018_LOG(INFO) + << LOG_DESC("CuckooFiltersCache: insert return directly for hit the cache") + << LOG_KV("resource", _resourceID) << LOG_KV("filter", filterID) + << LOG_KV("capacity", m_capacity); + return; + } + // update the currentFilter if its-hash changed + RA2018_LOG(INFO) << LOG_DESC("CuckooFiltersCache: update the cuckoo-filter") + << LOG_KV("resource", _resourceID) << LOG_KV("filter", filterID) + << LOG_KV("capacity", m_capacity); + _filter->setDirty(true); + // update the capacity + m_capacity -= currentFilter->cuckooFilter()->capacity(); + m_capacity += _filter->cuckooFilter()->capacity(); + UpgradeGuard ul(l); + pCuckooFilter->second = _filter; + flush(_resourceID, filterID, _filter); + return; + } + } + UpgradeGuard ul(l); + // insert new cuckoo-filter + m_resourceToCuckooFilters[_resourceID][filterID] = _filter; + m_resourceQueue.push(std::make_pair(_resourceID, filterID)); + _filter->setDirty(true); + flush(_resourceID, filterID, _filter); + m_capacity += _filter->cuckooFilter()->capacity(); + RA2018_LOG(INFO) << LOG_DESC("CuckooFiltersCache: insert new cuckoo-filter") + << LOG_KV("resource", _resourceID) << LOG_KV("capacity", m_capacity); +} + +// query cuckoo-filter specified by hash, access the storage and update the +// m_resourceToCuckooFilters when miss +CuckooFilterInfo::Ptr CuckooFiltersCache::queryWithoutEvict( + std::string const& _resourceID, int32_t _filterID) +{ + { + ReadGuard l(x_mutex); + auto it = m_resourceToCuckooFilters.find(_resourceID); + if (it != m_resourceToCuckooFilters.end()) + { + auto pCuckooFilter = it->second.find(_filterID); + // hit the cache + if (pCuckooFilter != it->second.end()) + { + RA2018_LOG(INFO) << LOG_DESC("CuckooFiltersCache: query hit the cache") + << LOG_KV("resource", _resourceID) << LOG_KV("filter", _filterID) + << LOG_KV("capacity", m_capacity); + return pCuckooFilter->second; + } + } + } + return loadCuckooFilterFromStorage(_resourceID, _filterID); +} + +CuckooFilterInfo::Ptr CuckooFiltersCache::loadCuckooFilterFromStorage( + std::string const& _resourceID, int32_t _filterID) +{ + try + { + RA2018_LOG(INFO) << LOG_DESC("CuckooFiltersCache: loadCuckooFilterFromStorage") + << LOG_KV("resource", _resourceID) << LOG_KV("filter", _filterID) + << LOG_KV("capacity", m_capacity); + // miss the cache load the cuckoo-filter from the backend + // Note: since the load operation may occupy more time, we remove the lock here + auto filterInfo = m_storage->loadCuckooFilterDataInfo(_resourceID, _filterID, true); + // the filter non-exist + if (!filterInfo) + { + return nullptr; + } + UpgradableGuard l(x_mutex); + // check the existance again, in case of the filter been inserted + if (!m_resourceToCuckooFilters.count(_resourceID) || + !m_resourceToCuckooFilters.at(_resourceID).count(_filterID)) + { + UpgradeGuard ul(l); + filterInfo->setFilterID(_filterID); + m_resourceToCuckooFilters[_resourceID][_filterID] = filterInfo; + m_resourceQueue.push(std::make_pair(_resourceID, _filterID)); + m_capacity += filterInfo->cuckooFilter()->capacity(); + return filterInfo; + } + return m_resourceToCuckooFilters.at(_resourceID).at(_filterID); + } + catch (std::exception const& e) + { + // load cuckoo-filter failed + RA2018_LOG(WARNING) << LOG_DESC("loadCuckooFilterFromStorage exception") + << LOG_KV("resource", _resourceID) << LOG_KV("filter", _filterID) + << LOG_KV("error", boost::diagnostic_information(e)); + return nullptr; + } +} + +bool CuckooFiltersCache::evict() +{ + // the cache is not full + if (m_capacity <= m_maxCapacity) + { + return false; + } + // the cache is full + bcos::WriteGuard l(x_mutex); + while (m_capacity > m_maxCapacity) + { + // find out the element to evict + auto element = m_resourceQueue.back(); + m_resourceQueue.pop(); + auto it = m_resourceToCuckooFilters.find(element.first); + if (it == m_resourceToCuckooFilters.end()) + { + continue; + } + auto pFilter = it->second.find(element.second); + if (pFilter == it->second.end()) + { + continue; + } + auto evictedCuckooFilter = pFilter->second; + it->second.erase(pFilter); + m_capacity -= evictedCuckooFilter->cuckooFilter()->capacity(); + RA2018_LOG(INFO) << LOG_DESC("CuckooFiltersCache evict") + << LOG_KV("resource", element.first) << LOG_KV("filter", element.second) + << LOG_KV("evictedSize", evictedCuckooFilter->cuckooFilter()->capacity()) + << LOG_KV("capacity", m_capacity); + flush(element.first, element.second, evictedCuckooFilter); + } + return true; +} + +void CuckooFiltersCache::flushAll() +{ + ReadGuard l(x_mutex); + for (auto const& it : m_resourceToCuckooFilters) + { + auto const& resourceID = it.first; + for (auto const& cuckooItem : it.second) + { + flush(resourceID, cuckooItem.first, cuckooItem.second); + } + } +} + +void CuckooFiltersCache::flush( + std::string const& _resourceID, int32_t _filterID, CuckooFilterInfo::Ptr _filter) +{ + if (!_filter->dirty()) + { + return; + } + // insert + RA2018_LOG(INFO) << LOG_DESC("CuckooFiltersCache flush: insert new cuckoo-filter") + << LOG_KV("resource", _resourceID) << _filter->desc(); + // Note: since every cuckoo-filter-fetch-process will check the cuckoo-filter between + // server and client, storage failure has no effect + m_storage->asyncInsertCuckooFilter( + _resourceID, _filter->cuckooFilter(), + [_resourceID](Error::Ptr&& _error) { + if (!_error) + { + return; + } + RA2018_LOG(WARNING) + << LOG_DESC("CuckooFiltersCache evict: insert cuckoo-filter to storage failed") + << LOG_KV("resource", _resourceID) << LOG_KV("code", _error->errorCode()) + << LOG_KV("msg", _error->errorMessage()); + }, + _filterID); +} diff --git a/cpp/wedpr-computing/ppc-psi/src/ra2018-psi/core/CuckooFiltersCache.h b/cpp/wedpr-computing/ppc-psi/src/ra2018-psi/core/CuckooFiltersCache.h new file mode 100644 index 00000000..359801e7 --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/ra2018-psi/core/CuckooFiltersCache.h @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2022 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 CuckooFiltersCache.h + * @author: yujiechen + * @date 2022-11-10 + */ +#pragma once +#include "../storage/RA2018PSIStorage.h" +#include "CuckooFilterInfo.h" +#include +#include +namespace ppc::psi +{ +// Note: the cuckoo-filter is useful for the client +// we access the storage directly when the save insert/update/load cuckoo-filter +class CuckooFiltersCache +{ +public: + using Ptr = std::shared_ptr; + // default cache size is 255MB + CuckooFiltersCache( + RA2018PSIStorage::Ptr const& _storage, uint64_t _maxCapacity = 255 * 1024 * 1024) + : m_storage(_storage), m_maxCapacity(_maxCapacity) + {} + virtual ~CuckooFiltersCache() {} + + // insert a cuckoo-filter into the cache, flush the last-element from m_resourceQueue if + // cache-full, return the cache is full or not + virtual bool insert(std::string const& _resourceID, CuckooFilterInfo::Ptr const& _filter); + + // query cuckoo-filter specified by hash, access the storage and update the + // m_resourceToCuckooFilters when miss + virtual CuckooFilterInfo::Ptr query(std::string const& _resourceID, int32_t _filterID); + + // flush the updated/dirty cuckoo-filter into the db + // we can call this periodly + virtual void flushAll(); + + uint64_t capacity() const { return m_capacity; } + bool full() const { return m_capacity >= m_maxCapacity; } + +protected: + // Note: only flush the dirty-cuckoo-filter to the backend when evict + virtual bool evict(); + // insert the cuckoo-filter into the db + virtual void insertWithoutEvict( + std::string const& _resourceID, CuckooFilterInfo::Ptr const& _filter); + + // query the cuckoo-filter according to the resourceID and filterID + virtual CuckooFilterInfo::Ptr queryWithoutEvict( + std::string const& _resourceID, int32_t _filterID); + + // load the cuckoo-filter from the backend-storage + virtual CuckooFilterInfo::Ptr loadCuckooFilterFromStorage( + std::string const& _resourceID, int32_t _filterID); + + // flush the dirty/inserted cuckoo-filter to the storage + virtual void flush( + std::string const& _resourceID, int32_t _filterID, CuckooFilterInfo::Ptr _filter); + +private: + RA2018PSIStorage::Ptr m_storage; + uint64_t m_maxCapacity; + std::atomic m_capacity = {0}; + + // for FIFO cache-policy + // (resourceID, filter ID) + std::queue> m_resourceQueue; + // the resourceID to cuckoo-filters + // resourceID => filter id => cuckoo-filter + std::map> m_resourceToCuckooFilters; + mutable bcos::SharedMutex x_mutex; +}; +} // namespace ppc::psi \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-psi/src/ra2018-psi/core/CuckoofilterAllocator.cpp b/cpp/wedpr-computing/ppc-psi/src/ra2018-psi/core/CuckoofilterAllocator.cpp new file mode 100644 index 00000000..a4e072fb --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/ra2018-psi/core/CuckoofilterAllocator.cpp @@ -0,0 +1,150 @@ +/* + * Copyright (C) 2022 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 CuckoofilterAllocator.cpp + * @author: yujiechen + * @date 2022-11-7 + */ +#include "CuckoofilterAllocator.h" + +using namespace ppc::psi; + +// Note: all allocate call will trigger allocate the used-up cuckoo-filter +DefaultCukooFilterPtr CuckoofilterAllocator::allocate() +{ + // with cuckoo-filter and the cuckoo-filter underload + if (m_currentCuckooFilter) + { + if (!m_currentCuckooFilter->cuckooFilter()->full()) + { + return m_currentCuckooFilter->cuckooFilter(); + } + else + { + // if the cuckoo-filter overload, try to flush to backend + saveOverLoadedCuckooFilter(false); + } + } + // load the reusable-cuckoo-filter from the backend + while (!m_currentCuckooFilter && !m_reusableFilters.empty()) + { + auto const& filterID = m_reusableFilters.back()->filterID(); + try + { + // Note: the cuckoo-filter files maybe deleted which will cause exception + m_currentCuckooFilter = + m_storage->loadCuckooFilterDataInfo(m_resourceID, filterID, true); + } + catch (std::exception const& e) + { + RA2018_LOG(WARNING) + << LOG_DESC("CuckoofilterAllocator: loadCuckooFilterInfo error when allocate") + << LOG_KV("error", boost::diagnostic_information(e)) + << LOG_KV("resource", m_resourceID) << LOG_KV("filter", filterID); + } + m_reusableFilters.pop_back(); + } + + // allocate a new cuckoo-filter + if (m_reusableFilters.empty() && !m_currentCuckooFilter) + { + auto allocatedCuckooFilter = + std::make_shared(m_config->cuckooFilterOption()); + // the id of the new cuckoo-filter is -1 + m_currentCuckooFilter = std::make_shared(-1); + m_currentCuckooFilter->setCuckooFilter(std::move(allocatedCuckooFilter)); + RA2018_LOG(INFO) << LOG_DESC("CuckoofilterAllocator: allocate new cuckoofilter"); + } + else + { + RA2018_LOG(INFO) << LOG_DESC("CuckoofilterAllocator: reuse old cuckoofilter: ") + << m_currentCuckooFilter->filterID(); + } + return m_currentCuckooFilter->cuckooFilter(); +} + +void CuckoofilterAllocator::flush() +{ + RA2018_LOG(INFO) << LOG_DESC("CuckoofilterAllocator flush") << LOG_KV("resource", m_resourceID); + // Note: the last cuckoo-filter must store to the backend + saveOverLoadedCuckooFilter(true); +} + +void CuckoofilterAllocator::saveOverLoadedCuckooFilter(bool _flush) +{ + // without cuckoo-filter + if (!m_currentCuckooFilter) + { + if (m_flush) + { + m_callback(nullptr); + } + return; + } + m_total++; + // Note: must set m_total to the real-store-count before trigger the last + // cuckoo-filter-store-operation + if (_flush) + { + m_flush = true; + } + // TODO: check will this cause memory leak here? + auto allocator = shared_from_this(); + auto callback = [allocator](bcos::Error::Ptr _error) { + allocator->m_total--; + if (_error) + { + allocator->m_failed++; + } + RA2018_LOG(INFO) << LOG_DESC("saveOverLoadedCuckooFilter") + << LOG_KV("code", _error ? _error->errorCode() : 0) + << LOG_KV("msg", _error ? _error->errorMessage() : "success") + << LOG_KV("resource", allocator->m_resourceID); + // not all data has been stored into backend + if (allocator->m_total > 0) + { + return; + } + // not calls flush yet + if (!allocator->m_flush) + { + return; + } + // with error + if (allocator->m_failed) + { + allocator->m_callback(std::make_shared(-1, "store cuckoo-filter error!")); + return; + } + // success + allocator->m_callback(nullptr); + }; + // insert a new-overloaded-cuckoo-filter + // Note: the m_currentCuckooFilter will be re-allocated later + auto cuckooFilter = std::move(m_currentCuckooFilter); + if (-1 == cuckooFilter->filterID()) + { + RA2018_LOG(INFO) << LOG_DESC( + "CuckoofilterAllocator: saveOverLoadedCuckooFilter with insert") + << LOG_KV("resourceID", m_resourceID); + m_storage->asyncInsertCuckooFilter(m_resourceID, cuckooFilter->cuckooFilter(), callback); + return; + } + RA2018_LOG(INFO) << LOG_DESC("CuckoofilterAllocator: saveOverLoadedCuckooFilter with update") + << LOG_KV("resourceID", m_resourceID) << cuckooFilter->desc() + << LOG_KV("total", m_total); + // update the old-overloaded-cuckoo-filter + m_storage->asyncUpdateCuckooFilter(m_resourceID, cuckooFilter, callback); +} \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-psi/src/ra2018-psi/core/CuckoofilterAllocator.h b/cpp/wedpr-computing/ppc-psi/src/ra2018-psi/core/CuckoofilterAllocator.h new file mode 100644 index 00000000..38ae5988 --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/ra2018-psi/core/CuckoofilterAllocator.h @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2022 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 CuckoofilterAllocator.h + * @author: yujiechen + * @date 2022-11-7 + */ +#pragma once +#include "../Common.h" +#include "../RA2018PSIConfig.h" +#include "../storage/RA2018PSIStorage.h" + +namespace ppc::psi +{ +class CuckoofilterAllocator : public std::enable_shared_from_this +{ +public: + // the _reusableFilters record the cuckoo-filter ids that not full + CuckoofilterAllocator(RA2018PSIConfig::Ptr _config, RA2018PSIStorage::Ptr _storage, + std::string const& _resourceID, std::function _callback, + CuckooFilterInfoSet&& _reusableFilters) + : m_config(std::move(_config)), + m_storage(std::move(_storage)), + m_resourceID(_resourceID), + m_callback(std::move(_callback)), + m_reusableFilters(_reusableFilters.begin(), _reusableFilters.end()) + {} + virtual ~CuckoofilterAllocator() = default; + + // allocate the underload cuckoo-filter + virtual DefaultCukooFilterPtr allocate(); + // flush the updated/new cuckoo-filter into the backend-storage + // Note: the callback can'be called only after flush + virtual void flush(); + +private: + void saveOverLoadedCuckooFilter(bool _flush); + +private: + RA2018PSIConfig::Ptr m_config; + RA2018PSIStorage::Ptr m_storage; + std::string m_resourceID; + std::function m_callback; + + std::vector m_reusableFilters; + + // the current allocated cuckoo-filter + CuckooFilterInfo::Ptr m_currentCuckooFilter = nullptr; + + // for determine store the cuckoo-filter success or not + std::atomic m_total = {0}; + std::atomic m_failed = {0}; + std::atomic m_flush = {false}; +}; +} // namespace ppc::psi \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-psi/src/ra2018-psi/core/RA2018PSIClient.cpp b/cpp/wedpr-computing/ppc-psi/src/ra2018-psi/core/RA2018PSIClient.cpp new file mode 100644 index 00000000..54d1ac8d --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/ra2018-psi/core/RA2018PSIClient.cpp @@ -0,0 +1,212 @@ +/* + * Copyright (C) 2022 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 RA2018PSIClient.cpp + * @author: yujiechen + * @date 2022-11-8 + */ +#include "RA2018PSIClient.h" +#include + +using namespace ppc::psi; +using namespace ppc::protocol; +using namespace bcos; + +// insert new RA2018PSIClientCache for given task and seq +std::pair RA2018PSIClient::insertCache( + std::string const& _cuckooFilterResourceID, std::string const& _taskID, + TaskState::Ptr const& _taskState, DataResource::ConstPtr const& _dataResource, uint32_t _seq, + ppc::io::DataBatch::Ptr&& _plainData) +{ + if (isFull()) + { + return std::make_pair(false, nullptr); + } + bcos::UpgradableGuard l(x_caches); + auto it = m_caches.find(_taskID); + if (it != m_caches.end()) + { + auto pItem = it->second.find(_seq); + if (pItem != it->second.end()) + { + RA2018_LOG(WARNING) << LOG_DESC("insertCache return for the cache already exists") + << LOG_KV("task", _taskID) << LOG_KV("seq", _seq); + return std::make_pair(false, pItem->second); + } + } + bcos::UpgradeGuard ul(l); + // TODO: Be careful of the memory expansion caused by the evaluated-data and intersection-data + // stored in the RA2018PSIClientCache + m_capacity += _plainData->capacityBytes(); + auto state = loadCuckooFilterState(_cuckooFilterResourceID, false); + auto cacheItem = std::make_shared( + m_config, state, _taskID, _taskState, _dataResource, _seq, std::move(_plainData)); + m_caches[_taskID][_seq] = cacheItem; + RA2018_LOG(INFO) << LOG_DESC("insertCache success") << LOG_KV("task", _taskID) + << LOG_KV("seq", _seq); + return std::make_pair(true, cacheItem); +} + +// obtain the cache according to the taskID and seq +RA2018PSIClientCache::Ptr RA2018PSIClient::cache(std::string const& _taskID, uint32_t _seq) const +{ + bcos::ReadGuard l(x_caches); + if (!m_caches.count(_taskID) || !m_caches.at(_taskID).count(_seq)) + { + return nullptr; + } + return m_caches.at(_taskID).at(_seq); +} + +// Serially write the results of each (task, seq) to the result file +// erase the finished (task, seq) cache from the m_caches +void RA2018PSIClient::checkAndStoreInterSectionResult() +{ + bcos::WriteGuard l(x_caches); + for (auto it = m_caches.begin(); it != m_caches.end();) + { + auto& taskCache = it->second; + for (auto ptaskCache = taskCache.begin(); ptaskCache != taskCache.end();) + { + // commit the psi-result and erase the intersectioned cache + auto state = ptaskCache->second->state(); + if (state == CacheState::Intersectioned) + { + // Note: commit for the same-task must be seq when the output-data-resource is file + commitPSIResult(ptaskCache->second); + auto plainDataSize = ptaskCache->second->plainData()->capacityBytes(); + if (plainDataSize > m_capacity) + { + m_capacity = 0; + } + else + { + m_capacity -= plainDataSize; + } + // notify to wakeup the worker when the capacity decreased + m_onReady(); + } + // Note: only the can erase cache with synced state + if (state == CacheState::Synced) + { + ptaskCache = taskCache.erase(ptaskCache); + continue; + } + ptaskCache++; + } + // all seq-data of the task has been handled finished + if (taskCache.empty()) + { + it = m_caches.erase(it); + continue; + } + it++; + } +} + +// trigger computeIntersection when receive the cuckoo-filter-response +void RA2018PSIClient::computeIntersection() +{ + auto self = weak_from_this(); + ReadGuard l(x_caches); + for (auto const& it : m_caches) + { + auto clientCaches = it.second; + for (auto const& item : clientCaches) + { + auto clientCache = item.second; + auto state = clientCache->state(); + // only trigger intersection when finalized + // trigger psi-store when intersectioned + if (state != CacheState::Finalized && state != CacheState::Intersectioned) + { + continue; + } + m_config->threadPool()->enqueue([self, clientCache]() { + auto client = self.lock(); + if (!client) + { + return; + } + try + { + clientCache->computeIntersection(); + client->checkAndStoreInterSectionResult(); + } + catch (std::exception const& e) + { + RA2018_LOG(WARNING) + << LOG_DESC("computeIntersection exception, cancel the task") + << LOG_KV("exception", boost::diagnostic_information(e)) + << printTaskInfo(clientCache->taskState()->task()); + clientCache->taskState()->onTaskException(boost::diagnostic_information(e)); + } + }); + } + } +} + +// TODO: optimize the commit Performance with multiple thread +void RA2018PSIClient::commitPSIResult(RA2018PSIClientCache::Ptr _cache) +{ + // in-case of store the result multiple times + auto self = weak_from_this(); + m_commitWorker->enqueue([_cache, self]() { + auto client = self.lock(); + if (!client) + { + return; + } + try + { + auto startT = utcSteadyTime(); + _cache->storePSIResult(); + // notify to check the task-result + RA2018_LOG(INFO) << LOG_DESC("commitPSIResult success") + << LOG_KV("timecost", (utcSteadyTime() - startT)) + << LOG_KV("task", _cache->taskID()) << LOG_KV("seq", _cache->seq()); + } + catch (std::exception const& e) + { + // commit error + _cache->taskState()->eraseFinishedTaskSeq(_cache->seq(), false); + RA2018_LOG(WARNING) << LOG_DESC("commitPSIResult error") + << LOG_KV("task", _cache->taskID()) << LOG_KV("seq", _cache->seq()) + << LOG_KV("msg", boost::diagnostic_information(e)); + } + }); +} + +CuckooFilterState::Ptr RA2018PSIClient::loadCuckooFilterState( + std::string const& _resourceID, bool _create) +{ + bcos::UpgradableGuard l(x_resourceCuckooFilterState); + auto it = m_resourceCuckooFilterState.find(_resourceID); + if (it != m_resourceCuckooFilterState.end()) + { + return it->second; + } + if (!_create) + { + return nullptr; + } + // create and insert a new cuckoo-filter-state + auto state = std::make_shared(_resourceID); + RA2018_LOG(INFO) << LOG_DESC("loadCuckooFilterState: create cuckooFilterState") + << LOG_KV("resource", _resourceID); + bcos::UpgradeGuard ul(l); + m_resourceCuckooFilterState[_resourceID] = state; + return state; +} diff --git a/cpp/wedpr-computing/ppc-psi/src/ra2018-psi/core/RA2018PSIClient.h b/cpp/wedpr-computing/ppc-psi/src/ra2018-psi/core/RA2018PSIClient.h new file mode 100644 index 00000000..fc230bb2 --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/ra2018-psi/core/RA2018PSIClient.h @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2022 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 RA2018PSIClient.h + * @author: yujiechen + * @date 2022-11-8 + */ + +#pragma once +#include "../RA2018PSIConfig.h" +#include "CuckooFilterState.h" +#include "RA2018PSIClientCache.h" +#include +#include +#include +namespace ppc::psi +{ +class RA2018PSIClient : public std::enable_shared_from_this +{ +public: + using Ptr = std::shared_ptr; + RA2018PSIClient(RA2018PSIConfig::Ptr const& _config, uint64_t maxCacheSize = 1024 * 1024 * 1024) + : m_config(_config), + m_commitWorker(std::make_shared("committer", 1)), + m_maxCacheSize(maxCacheSize) + {} + virtual ~RA2018PSIClient() = default; + + // insert new RA2018PSIClientCache for given seq + std::pair insertCache( + std::string const& _cuckooFilterResourceID, std::string const& _taskID, + TaskState::Ptr const& _taskState, + ppc::protocol::DataResource::ConstPtr const& _dataResource, uint32_t _seq, + ppc::io::DataBatch::Ptr&& _plainData); + + // erase the cache + void eraseTaskCache(std::string const& _taskID) + { + bcos::WriteGuard l(x_caches); + m_caches.erase(_taskID); + } + // obtain the cache according to the taskID and seq + RA2018PSIClientCache::Ptr cache(std::string const& _taskID, uint32_t _seq) const; + + // check the task has completed or not, and store the intersection-result + virtual void checkAndStoreInterSectionResult(); + // compute-intersection + virtual void computeIntersection(); + + virtual CuckooFilterState::Ptr loadCuckooFilterState( + std::string const& _resourceID, bool _create); + + virtual bool isFull() const { return (m_capacity >= m_maxCacheSize); } + + template + bcos::Handler<> onReady(T const& _t) + { + return m_onReady.add(_t); + } + + uint64_t capacity() const { return m_capacity.load(); } + +private: + void commitPSIResult(RA2018PSIClientCache::Ptr _cache); + +private: + RA2018PSIConfig::Ptr m_config; + + // taskID->seq->RA2018PSIClientCache + using RA2018PSICacheType = + std::unordered_map>; + RA2018PSICacheType m_caches; + mutable bcos::SharedMutex x_caches; + + bcos::ThreadPool::Ptr m_commitWorker; + uint64_t m_maxCacheSize; + + std::atomic m_capacity = {0}; + + // record the cuckoo-filter-state for given resource + // TODO: clear the expired resourceCuckooFilterState + std::map m_resourceCuckooFilterState; + mutable bcos::SharedMutex x_resourceCuckooFilterState; + + // onReady + bcos::CallbackCollectionHandler<> m_onReady; +}; +} // namespace ppc::psi \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-psi/src/ra2018-psi/core/RA2018PSIClientCache.cpp b/cpp/wedpr-computing/ppc-psi/src/ra2018-psi/core/RA2018PSIClientCache.cpp new file mode 100644 index 00000000..217d780f --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/ra2018-psi/core/RA2018PSIClientCache.cpp @@ -0,0 +1,194 @@ +/* + * Copyright (C) 2022 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 RA2018PSIClientCache.cpp + * @author: yujiechen + * @date 2022-11-8 + */ +#include "RA2018PSIClientCache.h" + +using namespace ppc::psi; +using namespace bcos; + +// the client blind the input data +std::vector RA2018PSIClientCache::blind() +{ + auto startT = utcSteadyTime(); + bcos::RecursiveGuard l(m_mutex); + std::vector result; + m_config->oprf()->blind(m_plainData, m_privateKey, result); + RA2018_LOG(INFO) << LOG_DESC("blind") << LOG_KV("timecost", (utcSteadyTime() - startT)) + << printCurrentState(); + return result; +} + +// the client finalize the evaluated-data +void RA2018PSIClientCache::finalize(std::vector const& _evaluatedData) +{ + bcos::RecursiveGuard l(m_mutex); + // only can finalize in the evaluating-state + if (m_state != CacheState::Evaluating) + { + return; + } + if (_evaluatedData.size() != m_plainData->size()) + { + RA2018_LOG(WARNING) << LOG_DESC("Invalid evaluated data") + << LOG_KV("evaluatedDataSize", _evaluatedData.size()) + << printCurrentState(); + return; + } + m_state = CacheState::Finalizing; + + auto startT = utcSteadyTime(); + std::vector result; + m_config->oprf()->finalize(_evaluatedData, m_invPrivateKey, m_finalizedData); + m_state = CacheState::Finalized; + RA2018_LOG(INFO) << LOG_DESC("finalize successs") + << LOG_KV("timecost", (utcSteadyTime() - startT)) + << LOG_KV("size", m_finalizedData.size()) << printCurrentState(); + return; +} + +void RA2018PSIClientCache::computeIntersection() +{ + bcos::RecursiveGuard l(m_mutex); + // not finalized + // already been intersectioned or intersection-in-progress or storeing + if (m_state != CacheState::Finalized) + { + RA2018_LOG(DEBUG) << LOG_DESC( + "computeIntersection return for not in-finalized-state(only can " + "intersection in finalized state)") + << printCurrentState(); + return; + } + // the cuckoo-filters not setted + if (!m_cuckooFilterState->fetchFinish()) + { + RA2018_LOG(DEBUG) << LOG_DESC( + "computeIntersection return for the cuckoo-filter not fetched") + << printCurrentState(); + return; + } + auto startT = utcSteadyTime(); + m_state = CacheState::IntersectionProgressing; + // trigger intersection + auto cuckooFilterInfos = m_cuckooFilterState->cuckooFilterInfos(); + for (uint64_t i = 0; i < m_finalizedData.size(); i++) + { + auto const& key = m_finalizedData.at(i); + // foreach the cuckooFilters to find the intersection + for (auto const& it : cuckooFilterInfos) + { + if (it.second->cuckooFilter()->contains(key)) + { + m_intersectionData.emplace_back(m_plainData->getBytes(i)); + break; + } + } + } + m_state = CacheState::Intersectioned; + RA2018_LOG(INFO) << LOG_DESC("computeIntersection success") + << LOG_KV("timecost", (utcSteadyTime() - startT)) << printCurrentState() + << LOG_KV("intersectionSize", m_intersectionData.size()) + << LOG_KV("cuckooFilterSize", cuckooFilterInfos.size()); + return; +} + +void RA2018PSIClientCache::storePSIResult() +{ + // only can store the intersectioned data + bcos::RecursiveGuard l(m_mutex); + if (m_state != CacheState::Intersectioned) + { + return; + } + m_state = CacheState::StoreProgressing; + RA2018_LOG(INFO) << LOG_DESC("storePSIResult") << printCurrentState() + << printDataResourceInfo(m_dataResource); + // store the psi result + m_taskState->storePSIResult(m_config->dataResourceLoader(), m_intersectionData); + m_state = CacheState::Stored; + // commit success + if (!m_taskState->task()->syncResultToPeer()) + { + m_state = CacheState::Synced; + // No need to sync task to peers, erase the seq from the task-state directly + m_taskState->eraseFinishedTaskSeq(m_seq, true); + return; + } + // sync psi result to server + syncPSIResult(); + + // release the allocated memory + std::vector().swap(m_finalizedData); + std::vector().swap(m_intersectionData); +} + +// sync psi result to server +void RA2018PSIClientCache::syncPSIResult() +{ + if (m_state != CacheState::Stored) + { + return; + } + m_state = CacheState::Syncing; + RA2018_LOG(INFO) << LOG_DESC("syncResultToPeer") << printCurrentState() + << LOG_KV("peer", m_taskState->peerID()); + auto dataSyncMsg = + m_config->ra2018MsgFactory()->createPSIMessage((uint32_t)PSIPacketType::PSIResultSyncMsg); + dataSyncMsg->setData(m_intersectionData); + auto self = weak_from_this(); + m_config->generateAndSendPPCMessage( + m_taskState->peerID(), m_taskState->task()->id(), dataSyncMsg, + [self](Error::Ptr&& _error) { + auto cache = self.lock(); + if (!cache) + { + return; + } + if (!_error || _error->errorCode() == 0) + { + return; + } + RA2018_LOG(WARNING) << LOG_DESC("Sync PSI result error") << LOG_KV("seq", cache->m_seq) + << printTaskInfo(cache->m_taskState->task()); + }, + m_seq, + [self](bcos::Error::Ptr _error, std::string const& _agencyID, + ppc::front::PPCMessageFace::Ptr _msg, ppc::front::ResponseFunc) { + auto cache = self.lock(); + if (!cache) + { + return; + } + if (_error) + { + RA2018_LOG(WARNING) + << LOG_DESC("Sync PSI result error") << LOG_KV("seq", cache->m_seq) + << printTaskInfo(cache->m_taskState->task()); + } + else + { + RA2018_LOG(INFO) << LOG_DESC("Sync PSI result success") + << LOG_KV("seq", cache->m_seq) + << printTaskInfo(cache->m_taskState->task()); + } + cache->m_state = CacheState::Synced; + // erase the seq from task-state only when receive the response from the peer + cache->m_taskState->eraseFinishedTaskSeq(cache->m_seq, true); + }); +} diff --git a/cpp/wedpr-computing/ppc-psi/src/ra2018-psi/core/RA2018PSIClientCache.h b/cpp/wedpr-computing/ppc-psi/src/ra2018-psi/core/RA2018PSIClientCache.h new file mode 100644 index 00000000..4891b617 --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/ra2018-psi/core/RA2018PSIClientCache.h @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2022 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 RA2018PSIClientCache.h + * @author: yujiechen + * @date 2022-11-8 + */ + +#pragma once +#include "../../psi-framework/TaskState.h" +#include "../Common.h" +#include "../RA2018PSIConfig.h" +#include "CuckooFilterState.h" +#include "ppc-framework/io/DataBatch.h" +#include "ppc-framework/protocol/DataResource.h" +#include +#include +#include + +namespace ppc::psi +{ +class RA2018PSIClientCache : public std::enable_shared_from_this +{ +public: + using Ptr = std::shared_ptr; + RA2018PSIClientCache(RA2018PSIConfig::Ptr const& _config, + CuckooFilterState::Ptr _cuckooFilterState, std::string const& _taskID, + TaskState::Ptr const& _taskState, + ppc::protocol::DataResource::ConstPtr const& _dataResource, uint32_t _seq, + ppc::io::DataBatch::Ptr&& _plainData) + : m_config(_config), + m_taskID(_taskID), + m_taskState(_taskState), + m_cuckooFilterState(std::move(_cuckooFilterState)), + m_dataResource(_dataResource), + m_seq(_seq), + m_plainData(std::move(_plainData)) + { + m_privateKey = m_config->oprf()->generatePrivateKey(); + m_invPrivateKey = m_config->oprf()->inv(m_privateKey); + } + virtual ~RA2018PSIClientCache() = default; + + // the client blind the input data + virtual std::vector blind(); + + // the client finalize the evaluated-data + virtual void finalize(std::vector const& _evaluatedData); + // compute the intersection when receive both the finalized data and cuckoo-filter + virtual void computeIntersection(); + // the data has been intersectioned or not + virtual CacheState state() const { return m_state; } + virtual void setState(CacheState _state) { m_state = _state; } + + // store the psi-result after intersectioned + virtual void storePSIResult(); + // the task-seq + uint32_t seq() const { return m_seq; } + // the taskID + std::string const& taskID() const { return m_taskID; } + ppc::io::DataBatch::Ptr const& plainData() const { return m_plainData; } + TaskState::Ptr taskState() const { return m_taskState; } + +private: + inline std::string printCurrentState() + { + std::ostringstream stringstream; + stringstream << LOG_KV("task", m_taskID) << LOG_KV("seq", m_seq) + << LOG_KV("plainDataSize", m_plainData->size()) + << LOG_KV("finalizedData", m_finalizedData.size()) + << LOG_KV("intersectionData", m_intersectionData.size()) + << LOG_KV("state", m_state); + return stringstream.str(); + } + + void syncPSIResult(); + +private: + RA2018PSIConfig::Ptr m_config; + std::string m_taskID; + TaskState::Ptr m_taskState; + // Note the data-resource may have multiple cuckoo-filter + CuckooFilterState::Ptr m_cuckooFilterState; + + ppc::protocol::DataResource::ConstPtr m_dataResource; + uint32_t m_seq; + // the plainData batch for given seq + ppc::io::DataBatch::Ptr m_plainData; + + // the finalized-data + std::vector m_finalizedData; + // the intersection-data + std::vector m_intersectionData; + CacheState m_state = CacheState::Evaluating; + + // the privateKey + bcos::bytes m_privateKey; + bcos::bytes m_invPrivateKey; + + mutable bcos::RecursiveMutex m_mutex; +}; +} // namespace ppc::psi \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-psi/src/ra2018-psi/core/RA2018PSIServer.cpp b/cpp/wedpr-computing/ppc-psi/src/ra2018-psi/core/RA2018PSIServer.cpp new file mode 100644 index 00000000..1e7f3c0d --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/ra2018-psi/core/RA2018PSIServer.cpp @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2022 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 RA2018PSIServer.cpp + * @author: yujiechen + * @date 2022-11-8 + */ +#include "RA2018PSIServer.h" +#include + +using namespace ppc::psi; +using namespace ppc::io; +using namespace bcos; + +// full-evaluate the input data +std::vector RA2018PSIServer::fullEvaluate(DataBatch::Ptr const& _data) +{ + auto startT = utcSteadyTime(); + std::vector result; + m_config->oprf()->fullEvaluate(_data, result); + RA2018_LOG(INFO) << LOG_DESC("RA2018PSIServer fullEvaluate finish") + << LOG_KV("timecost", (utcSteadyTime() - startT)) + << LOG_KV("dataSize", _data->size()); + return result; +} + +std::vector RA2018PSIServer::evaluate(std::vector const& _blindData) +{ + auto startT = utcSteadyTime(); + std::vector result; + m_config->oprf()->evaluate(_blindData, result); + RA2018_LOG(INFO) << LOG_DESC("RA2018PSIServer evaluate finish") + << LOG_KV("timecost", (utcSteadyTime() - startT)) + << LOG_KV("dataSize", _blindData.size()); + return result; +} \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-psi/src/ra2018-psi/core/RA2018PSIServer.h b/cpp/wedpr-computing/ppc-psi/src/ra2018-psi/core/RA2018PSIServer.h new file mode 100644 index 00000000..f1f0336d --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/ra2018-psi/core/RA2018PSIServer.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2022 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 RA2018PSIServer.h + * @author: yujiechen + * @date 2022-11-8 + */ +#pragma once +#include "../RA2018PSIConfig.h" +#include "ppc-framework/io/DataBatch.h" +#include +namespace ppc::psi +{ +class RA2018PSIServer +{ +public: + using Ptr = std::shared_ptr; + RA2018PSIServer(RA2018PSIConfig::Ptr const& _config) : m_config(_config) {} + virtual ~RA2018PSIServer() = default; + + // the server offline-full-evaluate + virtual std::vector fullEvaluate(ppc::io::DataBatch::Ptr const& _data); + // the server evaluate the blindedData + virtual std::vector evaluate(std::vector const& _blindData); + +private: + RA2018PSIConfig::Ptr m_config; +}; +} // namespace ppc::psi \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-psi/src/ra2018-psi/core/Ra2018TaskParam.h b/cpp/wedpr-computing/ppc-psi/src/ra2018-psi/core/Ra2018TaskParam.h new file mode 100644 index 00000000..dd05d4a3 --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/ra2018-psi/core/Ra2018TaskParam.h @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2022 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 Ra2018TaskParam.h + * @author: yujiechen + * @date 2022-11-7 + */ +#pragma once +#include "../Common.h" +#include +namespace ppc::psi +{ +class Ra2018TaskParam +{ +public: + using Ptr = std::shared_ptr; + Ra2018TaskParam(std::string_view _param) + { + Json::Reader reader; + Json::Value result; + if (!reader.parse(_param.begin(), _param.end(), result)) + { + BOOST_THROW_EXCEPTION(BCOS_ERROR((int)PSIRetCode::InvalidTaskParamForRA2018, + "Invalid Ra2018TaskParam: invalid json")); + } + if (!result.isArray()) + { + BOOST_THROW_EXCEPTION(BCOS_ERROR((int)PSIRetCode::InvalidTaskParamForRA2018, + "Invalid Ra2018TaskParam: the param must be array")); + } + auto command = result[0].asString(); + // the DATA_PREPROCESSING command must specified the operationType(insert(0)/delete(1)) + if (DATA_PREPROCESSING_CMD == command) + { + m_command = RA2018Command::DATA_PREPROCESSING; + if (result.size() < 2) + { + BOOST_THROW_EXCEPTION(BCOS_ERROR((int)PSIRetCode::InvalidTaskParamForRA2018, + "Must set operation for " + command + ", insert(0)/delete(1)")); + } + m_operation = result[1].asInt(); + } + else if (RUN_PSI_CMD == command) + { + m_command = RA2018Command::RUN_PSI; + } + else + { + BOOST_THROW_EXCEPTION(BCOS_ERROR( + (int)PSIRetCode::InvalidTaskParamForRA2018, "Unsupported command " + command)); + } + } + + int command() const { return m_command; } + int operation() const { return m_operation; } + +private: + int m_command; + int m_operation; +}; +} // namespace ppc::psi diff --git a/cpp/wedpr-computing/ppc-psi/src/ra2018-psi/protocol/RA2018Message.h b/cpp/wedpr-computing/ppc-psi/src/ra2018-psi/protocol/RA2018Message.h new file mode 100644 index 00000000..e6a49166 --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/ra2018-psi/protocol/RA2018Message.h @@ -0,0 +1,154 @@ +/* + * Copyright (C) 2022 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 RA2018Message.h + * @author: yujiechen + * @date 2022-11-9 + */ +#pragma once +#include "../../psi-framework/protocol/PSIMessage.h" +#include "../Common.h" +#include "../core/CuckooFilterInfo.h" +#include "wedpr-protocol/tars/Common.h" + +namespace ppc::psi +{ +class RA2018FilterMessage : public PSIMessage +{ +public: + using Ptr = std::shared_ptr; + RA2018FilterMessage() : PSIMessage() {} + explicit RA2018FilterMessage(uint32_t _type) : PSIMessage(_type) {} + explicit RA2018FilterMessage(std::function _inner) + : PSIMessage(std::move(_inner)) + { + decodeCuckooFilterInfos(); + } + + explicit RA2018FilterMessage(bcos::bytesConstRef _data) : RA2018FilterMessage() + { + decode(_data); + } + + virtual void setFilterInfo(std::vector&& _filterInfos) + { + m_cuckooFilterInfos = std::move(_filterInfos); + } + + virtual void appendFilterInfo(CuckooFilterInfo::Ptr _filterInfo) + { + m_cuckooFilterInfos.emplace_back(std::move(_filterInfo)); + } + + virtual void setCuckooFilterSize(int32_t _cuckooFilterSize) + { + m_inner()->cuckooFilterSize = _cuckooFilterSize; + } + virtual int32_t cuckooFilterSize() const { return m_inner()->cuckooFilterSize; } + + virtual std::vector& mutableFilterInfo() { return m_cuckooFilterInfos; } + virtual std::vector const& filterInfo() { return m_cuckooFilterInfos; } + + bcos::bytesPointer encode() const override + { + m_inner()->cuckooFilterInfo.clear(); + // encode m_cuckooFilterInfos + for (auto& info : m_cuckooFilterInfos) + { + ppctars::TarsCuckooFilter filter; + filter.id = info->filterID(); + filter.hash = std::vector(info->hash().begin(), info->hash().end()); + if (info->cuckooFilterData().empty() && info->cuckooFilter()) + { + auto encodedData = info->cuckooFilter()->serialize(); + std::move(encodedData.begin(), encodedData.end(), std::back_inserter(filter.data)); + } + else if (!info->cuckooFilterData().empty()) + { + auto data = info->cuckooFilterData(); + std::move(data.begin(), data.end(), std::back_inserter(filter.data)); + } + m_inner()->cuckooFilterInfo.emplace_back(std::move(filter)); + } + return PSIMessage::encode(); + } + + // decode the RA2018FilterMessage + void decode(bcos::bytesConstRef _data) override + { + PSIMessage::decode(_data); + // decode m_cuckooFilterInfos + decodeCuckooFilterInfos(); + } + +protected: + void decodeCuckooFilterInfos() + { + m_cuckooFilterInfos.clear(); + for (auto& filterInfo : m_inner()->cuckooFilterInfo) + { + DefaultCukooFilterPtr filter = nullptr; + // decode the cuckoo-filter + if (!filterInfo.data.empty()) + { + filter = std::make_shared(bcos::bytesConstRef( + (const bcos::byte*)filterInfo.data.data(), filterInfo.data.size())); + } + bcos::bytes hashData(filterInfo.hash.begin(), filterInfo.hash.end()); + auto cuckooFilterInfo = + std::make_shared(filterInfo.id, hashData, filter); + m_cuckooFilterInfos.emplace_back(std::move(cuckooFilterInfo)); + } + } + +private: + mutable std::vector m_cuckooFilterInfos; +}; + +// the factory implementation +class RA2018MessageFactory : public PSIMessageFactoryImpl +{ +public: + using Ptr = std::shared_ptr; + RA2018MessageFactory() : PSIMessageFactoryImpl() {} + ~RA2018MessageFactory() override = default; + + virtual RA2018FilterMessage::Ptr createRA2018FilterMessage(uint32_t _packetType) + { + return std::make_shared(_packetType); + } + + PSIMessageInterface::Ptr decodePSIMessage(bcos::bytesConstRef _data) override + { + auto inner = [inner = ppctars::PSIMessage()]() mutable { return &inner; }; + tars::TarsInputStream input; + input.setBuffer((const char*)_data.data(), _data.size()); + inner()->readFrom(input); + switch (inner()->packetType) + { + case (uint32_t)RA2018PacketType::CuckooFilterRequest: + case (uint32_t)RA2018PacketType::CuckooFilterResponse: + case (uint32_t)RA2018PacketType::MissingCuckooFilterRequest: + case (uint32_t)RA2018PacketType::MissingCuckooFilterResponse: + return std::make_shared(inner); + case (uint32_t)RA2018PacketType::EvaluateRequest: + case (uint32_t)RA2018PacketType::EvaluateResponse: + return std::make_shared(inner); + default: + return decodePSIBaseMessage(inner); + } + } +}; +} // namespace ppc::psi \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-psi/src/ra2018-psi/storage/RA2018PSIStorage.cpp b/cpp/wedpr-computing/ppc-psi/src/ra2018-psi/storage/RA2018PSIStorage.cpp new file mode 100644 index 00000000..6b2e316d --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/ra2018-psi/storage/RA2018PSIStorage.cpp @@ -0,0 +1,423 @@ +/* + * Copyright (C) 2022 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 RA2018PSIStorage.cpp + * @author: yujiechen + * @date 2022-10-27 + */ +#include "RA2018PSIStorage.h" +#include "../Common.h" +#include "ppc-framework/protocol/Protocol.h" +#include +#include +#include + +using namespace ppc; +using namespace bcos; +using namespace ppc::psi; +using namespace ppc::storage; +using namespace ppc::protocol; +using namespace ppc::io; + +// create the database +void RA2018PSIStorage::createDataBase() +{ + std::string command = "CREATE DATABASE IF NOT EXISTS " + m_config->dbName(); + m_config->storage()->execCommit(command.c_str(), (int)FieldDataType::TERMINATE); + RA2018_LOG(INFO) << LOG_DESC("RA2018PSIStorage: create database success") + << LOG_KV("dbName", m_config->dbName()); + if (m_config->fileStorage()) + { + m_config->fileStorage()->createDirectory(m_config->dbName()); + } + RA2018_LOG(INFO) << LOG_DESC("RA2018PSIStorage: create directory success") + << LOG_KV("dirPath", m_config->dbName()); +} + +// create the cuckoo-filter-table +// TODO: add hash field to the cuckooFilterTable +void RA2018PSIStorage::createCuckooFilterTable() +{ + std::stringstream ss; + ss << "CREATE TABLE IF NOT EXISTS `" << m_config->cuckooFilterTableName() << "` (\n"; + ss << "`" << m_resourceIDField << "` varchar(128),\n"; + ss << "`" << m_filterIDField << "` INT AUTO_INCREMENT,\n"; + // Note: here filter-hash-field use at-most 32Bytes, for perf-consideration, default use md5 + ss << "`" << m_filterHashField << "` TINYBLOB DEFAULT NULL,\n"; + // Note: the mysql will convert boolean to tinyint + ss << "`" << m_loadField << "` BOOLEAN,\n"; + ss << " PRIMARY KEY (`" << m_resourceIDField << "`, `" << m_filterIDField << "`)\n"; + ss << ", key(" << m_filterIDField << ")"; + ss << ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;"; + m_config->storage()->execCommit(ss.str().c_str(), FieldDataType::TERMINATE); + RA2018_LOG(INFO) << LOG_DESC("createCuckooFilterTable: create cuckoo-filter-table success") + << LOG_KV("dbName", m_config->cuckooFilterTableName()); +} + +// get the cuckoo-filter-ids according to the _resourceID +CuckooFilterInfoSet RA2018PSIStorage::getCuckooFilterInfos( + std::string const& _resourceID, bool _onlyNotFull) +{ + try + { + auto startT = utcSteadyTime(); + std::stringstream ss; + ss << "select `" << m_filterIDField << "`, `" << m_filterHashField << "` from `" + << m_config->cuckooFilterTableName() << "` where `" << m_resourceIDField << "`='" + << _resourceID << "'"; + if (_onlyNotFull) + { + ss << " and `" << m_loadField << "` = 0"; + } + auto sqlCommand = ss.str(); + auto result = + m_config->storage()->execQuery(true, sqlCommand.c_str(), FieldDataType::TERMINATE); + if (result->size() != 2) + { + BOOST_THROW_EXCEPTION(BCOS_ERROR((int64_t)PPCRetCode::EXCEPTION, + "Invalid queried data, expect 2 columns, the result is " + + std::to_string(result->size()) + " columns")); + } + // parse the result + RA2018_LOG(INFO) << LOG_DESC("getCuckooFilterInfos success") + << LOG_KV("metaFieldSize", result->metaData().size()); + // parse the filter data + // int64_t type + auto const& filterIDData = result->data().at(0); + // bytes type + auto const& filterHashData = result->data().at(1); + if (filterIDData->size() != filterHashData->size()) + { + BOOST_THROW_EXCEPTION(BCOS_ERROR((int64_t)PPCRetCode::EXCEPTION, + "Invalid queried data, the item size of filterIDs should be equal to the size of " + "filterHashData")); + } + + CuckooFilterInfoSet filterInfos; + for (uint64_t i = 0; i < filterIDData->size(); i++) + { + auto filterID = filterIDData->get(i); + auto hash = filterHashData->get(i); + filterInfos.insert(std::make_shared(filterID, hash, nullptr)); + RA2018_LOG(INFO) << LOG_DESC("getCuckooFilterInfos") << LOG_KV("resource", _resourceID) + << LOG_KV("filterID", filterID) << LOG_KV("hash", toHex(hash)); + } + RA2018_LOG(INFO) << LOG_DESC("getCuckooFilterInfos success") + << LOG_KV("resource", _resourceID) + << LOG_KV("filterSize", filterInfos.size()) + << LOG_KV("timecost", (utcSteadyTime() - startT)); + return filterInfos; + } + catch (std::exception const& e) + { + std::stringstream oss; + oss << "getCuckooFilterInfos error! " << LOG_KV("resource", _resourceID) + << LOG_KV("error", boost::diagnostic_information(e)); + auto errorMsg = oss.str(); + RA2018_LOG(WARNING) << errorMsg; + BOOST_THROW_EXCEPTION(BCOS_ERROR((int64_t)PPCRetCode::EXCEPTION, errorMsg)); + } +} + +void RA2018PSIStorage::storeFilterData(std::string const& _desc, std::string const& _resourceID, + bcos::bytes const& _hash, bytesConstRef _data) +{ + auto startT = utcSteadyTime(); + auto hexHash = toHex(_hash); + auto desc = obtainCuckooFilterDesc(_resourceID, hexHash); + auto writer = m_config->dataResourceLoader()->loadWriter(desc, true, m_config->fileStorage()); + writer->writeBytes(_data); + writer->flush(); + RA2018_LOG(INFO) << LOG_BADGE("storeFilterData success") << LOG_DESC(_desc) + << LOG_KV("timecost", (utcSteadyTime() - startT)) + << LOG_KV("resource", _resourceID) << LOG_KV("hash", hexHash) + << LOG_KV("dataSize", _data.size()) << LOG_KV("path", desc->path()); +} + +// remove the old filter when updating cuckoo-filter +void RA2018PSIStorage::removeOldFilterData( + std::string const& _desc, std::string const& _resourceID, bcos::bytes const& _hash) +{ + auto hexHash = toHex(_hash); + auto desc = obtainCuckooFilterDesc(_resourceID, hexHash); + try + { + if (desc->type() == (int)ppc::protocol::DataResourceType::FILE) + { + std::remove(desc->path().c_str()); + } + if (desc->type() == (int)ppc::protocol::DataResourceType::HDFS) + { + m_config->fileStorage()->deleteFile(desc->path()); + } + } + catch (std::exception const& e) + { + RA2018_LOG(WARNING) << LOG_DESC("removeOldFilterData error") + << LOG_KV("resource", _resourceID) << LOG_KV("hash", hexHash) + << LOG_KV("path", desc->path()); + } +} + +// store the cuckoo-filter to the storage +void RA2018PSIStorage::asyncInsertCuckooFilter(std::string const& _resourceID, + DefaultCukooFilterPtr _cukooFilter, std::function _callback, + int32_t _filterID) +{ + std::stringstream ss; + auto filterData = _cukooFilter->serialize(); + auto filterDataHash = m_config->binHashImpl()->hash( + bytesConstRef((const bcos::byte*)(filterData.data()), filterData.size())); + storeFilterData("asyncInsertCuckooFilter", _resourceID, filterDataHash, + bytesConstRef((bcos::byte const*)filterData.data(), filterData.size())); + + RA2018_LOG(INFO) << LOG_DESC("asyncInsertCuckooFilter: update meta-info") + << LOG_KV("resource", _resourceID) << LOG_KV("dataSize", filterData.size()); + + auto cuckooFilterFull = _cukooFilter->full() ? 1 : 0; + auto withFilterID = (_filterID == -1) ? false : true; + + ss << "insert into " << m_config->cuckooFilterTableName() << "("; + ss << m_resourceIDField << ", " << m_loadField << ", " << m_filterHashField; + if (withFilterID) + { + ss << "," << m_filterIDField; + } + // resourceID, loadField, filterHash + ss << ") values(?, ?, ?"; + // filterID + if (withFilterID) + { + ss << ",?"; + } + // support update when key-conflict + ss << ")ON DUPLICATE KEY UPDATE `" << m_resourceIDField << "`=?, `" << m_loadField << "`=?, `" + << m_filterHashField << "`=?"; + if (withFilterID) + { + ss << ", `" << m_filterIDField << "` = ?"; + } + // the command + auto sqlCommand = ss.str(); + // resourceID, loadField, filterDataHash + auto statement = + m_config->storage()->generateStatement(sqlCommand.c_str(), FieldDataType::STRING, + _resourceID.c_str(), FieldDataType::UINT, cuckooFilterFull, FieldDataType::BYTES, + filterDataHash.data(), filterDataHash.size(), FieldDataType::TERMINATE); + // filterID + if (withFilterID) + { + m_config->storage()->appendStatement( + statement, FieldDataType::SINT, _filterID, FieldDataType::TERMINATE); + } + m_config->storage()->appendStatement(statement, FieldDataType::STRING, _resourceID.c_str(), + FieldDataType::UINT, cuckooFilterFull, FieldDataType::BYTES, filterDataHash.data(), + filterDataHash.size(), FieldDataType::TERMINATE); + if (withFilterID) + { + m_config->storage()->appendStatement( + statement, FieldDataType::SINT, _filterID, FieldDataType::TERMINATE); + } + asyncCommit("asyncInsertCuckooFilter", _resourceID, statement, _callback); +} + +void RA2018PSIStorage::asyncUpdateCuckooFilter(std::string const& _resourceID, + CuckooFilterInfo::Ptr const& _filterInfo, std::function _callback) +{ + if (!_filterInfo->cuckooFilter()) + { + _callback(BCOS_ERROR_PTR(-1, "asyncUpdateCuckooFilter failed for empty cuckoo-filter")); + return; + } + // the hash not changed + auto filterData = _filterInfo->cuckooFilter()->serialize(); + auto filterDataHash = m_config->binHashImpl()->hash( + bytesConstRef((const bcos::byte*)(filterData.data()), filterData.size())); + + if (filterDataHash == _filterInfo->hash()) + { + RA2018_LOG(INFO) << LOG_DESC("asyncUpdateCuckooFilter return for the filter not changed") + << _filterInfo->desc(); + _callback(nullptr); + return; + } + // remove the old-cuckoo-filter + removeOldFilterData("asyncUpdateCuckooFilter", _resourceID, _filterInfo->hash()); + // store the updated-cuckoo-filter + storeFilterData("asyncUpdateCuckooFilter", _resourceID, filterDataHash, + bytesConstRef((bcos::byte const*)filterData.data(), filterData.size())); + + RA2018_LOG(INFO) << LOG_DESC("asyncUpdateCuckooFilter: updateMetaInfo") + << LOG_KV("resource", _resourceID) << _filterInfo->desc() + << LOG_KV("currentHash", bcos::toHex(filterDataHash)) + << LOG_KV("dataSize", filterData.size()); + std::stringstream ss; + auto cuckooFilterFull = _filterInfo->cuckooFilter()->full() ? 1 : 0; + + ss << "update `" << m_config->cuckooFilterTableName() << "` set "; + ss << m_loadField << " = ?, "; + ss << m_filterHashField << " = ?"; + ss << " where " << m_resourceIDField << " = '" << _resourceID << "'"; + ss << " and " << m_filterIDField << " = " << _filterInfo->filterID(); + auto sqlCommand = ss.str(); + auto statement = m_config->storage()->generateStatement(sqlCommand.c_str(), FieldDataType::UINT, + cuckooFilterFull, FieldDataType::BYTES, filterDataHash.data(), filterDataHash.size(), + FieldDataType::TERMINATE); + asyncCommit("asyncUpdateCuckooFilter", _resourceID, statement, _callback); +} + +void RA2018PSIStorage::asyncCommit(std::string&& _desc, std::string const& _resourceID, + ppc::storage::Statement::Ptr _statement, std::function _callback) +{ + auto self = weak_from_this(); + m_config->threadPool()->enqueue( + [_statement, desc = std::move(_desc), _resourceID, _callback, self]() { + try + { + auto storage = self.lock(); + if (!storage) + { + return; + } + storage->m_config->storage()->execStatement(_statement); + _callback(nullptr); + } + catch (std::exception const& e) + { + std::stringstream oss; + oss << desc << " error !" << LOG_KV("resource", _resourceID) + << LOG_KV("error", boost::diagnostic_information(e)); + auto errorMsg = oss.str(); + RA2018_LOG(WARNING) << errorMsg; + _callback(BCOS_ERROR_PTR((int64_t)PPCRetCode::EXCEPTION, errorMsg)); + } + }); +} + +CuckooFilterInfo::Ptr RA2018PSIStorage::loadCuckooFilterFromFile(std::string const& _resourceID, + int32_t _filterID, bcos::bytes const& _cuckooFilterHash, bool _deserialize) +{ + try + { + auto startT = utcSteadyTime(); + auto cuckooFilterInfo = std::make_shared(_filterID, _cuckooFilterHash); + auto hexHash = toHex(_cuckooFilterHash); + auto desc = obtainCuckooFilterDesc(_resourceID, hexHash); + auto reader = m_config->dataResourceLoader()->loadReader( + desc, DataSchema::Bytes, false, m_config->fileStorage()); + auto cuckooFilterData = reader->readBytes(); + auto dataSize = cuckooFilterData.size(); + // deserialize + if (_deserialize) + { + RA2018_LOG(INFO) << LOG_DESC("deserialize cuckoo-filter") << cuckooFilterInfo->desc() + << LOG_KV("size", cuckooFilterData.size()); + // return the deserialized cuckoo-filter + auto cuckooFilter = std::make_shared( + bcos::bytesConstRef(cuckooFilterData.data(), cuckooFilterData.size())); + cuckooFilterInfo->setCuckooFilter(std::move(cuckooFilter)); + RA2018_LOG(INFO) << LOG_DESC("deserialize cuckoo-filter success") + << cuckooFilterInfo->desc() << LOG_KV("size", cuckooFilterData.size()); + } + else + { + // return the raw data + cuckooFilterInfo->setCuckooFilterData(std::move(cuckooFilterData)); + } + RA2018_LOG(INFO) << LOG_DESC("loadCuckooFilterFromFile success") + << LOG_KV("timecost", (utcSteadyTime() - startT)) + << LOG_KV("resource", _resourceID) << cuckooFilterInfo->desc() + << LOG_KV("dataSize", dataSize) << LOG_KV("path", desc->path()); + return cuckooFilterInfo; + } + catch (OpenFileFailed const& e) + { + RA2018_LOG(WARNING) << LOG_DESC( + "loadCuckooFilterFromFile exception for OpenFileFailed: delete " + "the meta-info from sql-storage") + << LOG_KV("resource", _resourceID) << LOG_KV("filter", _filterID) + << LOG_KV("error", boost::diagnostic_information(e)); + // delete the meta-info from the storage + deleteCuckooFilter(_resourceID, _filterID); + throw e; + } +} +// load the cuckoo-filter from the storage +CuckooFilterInfo::Ptr RA2018PSIStorage::loadCuckooFilterDataInfo( + std::string const& _resourceID, int32_t _filterID, bool _deserialize) +{ + try + { + auto startT = utcSteadyTime(); + std::stringstream ss; + ss << "select `" << m_filterHashField << "` " + << " from `" << m_config->cuckooFilterTableName() << "`"; + ss << " where `" << m_resourceIDField << "` = '" << _resourceID << "'"; + ss << " and `" << m_filterIDField << "` = " << _filterID; + auto command = ss.str(); + + auto result = + m_config->storage()->execQuery(true, command.c_str(), FieldDataType::TERMINATE); + if (result->data().empty()) + { + return nullptr; + } + if (result->size() != 1) + { + BOOST_THROW_EXCEPTION(BCOS_ERROR((int64_t)PPCRetCode::EXCEPTION, + "loadCuckooFilterDataInfo: invalid queried data, expect get 1 columns, real get " + + std::to_string(result->size()) + " columns!")); + } + // Note: only expect obtain one element from the database + auto cuckooFilterHash = result->data().at(0)->get(0); + auto cuckooFilterInfo = + loadCuckooFilterFromFile(_resourceID, _filterID, cuckooFilterHash, _deserialize); + RA2018_LOG(INFO) << LOG_DESC("loadCuckooFilterDataInfo success") + << LOG_KV("timecost", (utcSteadyTime() - startT)) + << LOG_KV("resource", _resourceID) << cuckooFilterInfo->desc(); + return cuckooFilterInfo; + } + catch (std::exception const& e) + { + std::stringstream oss; + oss << "loadCuckooFilterDataInfo error! " << LOG_KV("resource", _resourceID) + << LOG_KV("filter", _filterID) << LOG_KV("error", boost::diagnostic_information(e)); + auto errorMsg = oss.str(); + RA2018_LOG(WARNING) << errorMsg; + BOOST_THROW_EXCEPTION(BCOS_ERROR((int64_t)PPCRetCode::EXCEPTION, errorMsg)); + } +} + +void RA2018PSIStorage::deleteCuckooFilter(std::string const& _resourceID, int32_t _filterID) +{ + try + { + std::stringstream oss; + oss << "delete from `" << m_config->cuckooFilterTableName() << "`"; + oss << " where `" << m_resourceIDField << "` = '" << _resourceID << "'"; + oss << " and `" << m_filterIDField << "` = " << _filterID; + auto command = oss.str(); + m_config->storage()->execCommit(command.c_str(), FieldDataType::TERMINATE); + } + catch (std::exception const& e) + { + std::stringstream oss; + oss << "deleteCuckooFilter error! " << LOG_KV("resource", _resourceID) + << LOG_KV("filter", _filterID) << LOG_KV("error", boost::diagnostic_information(e)); + auto errorMsg = oss.str(); + RA2018_LOG(WARNING) << errorMsg; + BOOST_THROW_EXCEPTION(BCOS_ERROR((int64_t)PPCRetCode::EXCEPTION, errorMsg)); + } +} \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-psi/src/ra2018-psi/storage/RA2018PSIStorage.h b/cpp/wedpr-computing/ppc-psi/src/ra2018-psi/storage/RA2018PSIStorage.h new file mode 100644 index 00000000..edb8158a --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/src/ra2018-psi/storage/RA2018PSIStorage.h @@ -0,0 +1,163 @@ +/* + * Copyright (C) 2022 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 RA2018PSIStorage.h + * @author: yujiechen + * @date 2022-10-27 + */ + +#pragma once +#include "../Common.h" +#include "../RA2018PSIConfig.h" +#include "../core/CuckooFilterInfo.h" +#include "ppc-framework/storage/SQLStorage.h" +#include +#include +#include + +namespace ppc::psi +{ +class RA2018PSIStorage : public std::enable_shared_from_this +{ +public: + using Ptr = std::shared_ptr; + RA2018PSIStorage(RA2018PSIConfig::Ptr _config) : m_config(_config) {} + virtual ~RA2018PSIStorage() = default; + + // get the (cuckoo-filter-id, cuckoo-filter-hash according to the _resourceID and loadFactor + // TODO: optimize the perf(use async-client) + virtual CuckooFilterInfoSet getCuckooFilterInfos( + std::string const& _resourceID, bool _onlyNotFull); + + // load the cuckoo-filter from the storage + // TODO: optimize the perf(use async-client) + virtual CuckooFilterInfo::Ptr loadCuckooFilterDataInfo( + std::string const& _resourceID, int32_t _filterID, bool _deserialize); + + virtual bcos::bytes loadCuckooFilterData(std::string const& _resourceID, int32_t _filterID) + { + try + { + // need to deserialize + auto filterInfo = loadCuckooFilterDataInfo(_resourceID, _filterID, false); + if (!filterInfo) + { + return bcos::bytes(); + } + return filterInfo->cuckooFilterData(); + } + catch (std::exception const& e) + { + return bcos::bytes(); + } + } + + virtual DefaultCukooFilterPtr loadCuckooFilter( + std::string const& _resourceID, int32_t _filterID) + { + // need to serialize + auto filterInfo = loadCuckooFilterDataInfo(_resourceID, _filterID, true); + if (!filterInfo) + { + return nullptr; + } + return filterInfo->cuckooFilter(); + } + + // insert a new cuckoo-filter to the storage + // update the entry if key-conflict + virtual void asyncInsertCuckooFilter(std::string const& _resourceID, + DefaultCukooFilterPtr _cukooFilter, std::function _callback, + int32_t _filterID = -1); + // update the cuckoo-filter + // Note: update is more efficient than asyncInsertCuckooFilter + virtual void asyncUpdateCuckooFilter(std::string const& _resourceID, + CuckooFilterInfo::Ptr const& _filterInfo, + std::function _callback); + + virtual void init() + { + RA2018_LOG(INFO) << LOG_DESC("RA2018PSIStorage init the database") + << LOG_KV("dbName", m_config->dbName()); + createDataBase(); + // use the created database + RA2018_LOG(INFO) << LOG_DESC("RA2018PSIStorage use database: ") << m_config->dbName(); + m_config->storage()->useDataBase(m_config->dbName().c_str()); + + RA2018_LOG(INFO) << LOG_DESC("RA2018PSIStorage init the cuckoo-filter-table") + << LOG_KV("dbName", m_config->cuckooFilterTableName()); + createCuckooFilterTable(); + RA2018_LOG(INFO) << LOG_DESC("RA2018PSIStorage init success"); + } + +protected: + // init the database for ra2018-storage + void createDataBase(); + void createCuckooFilterTable(); + + void asyncCommit(std::string&& _desc, std::string const& _resourceID, + ppc::storage::Statement::Ptr _statement, std::function _callback); + + // store the filter data into file or hdfs + void storeFilterData(std::string const& _desc, std::string const& _resourceID, + bcos::bytes const& _hash, bcos::bytesConstRef _filterData); + // remove the old filter when updating cuckoo-filter + void removeOldFilterData( + std::string const& _desc, std::string const& _resourceID, bcos::bytes const& _hash); + + CuckooFilterInfo::Ptr loadCuckooFilterFromFile(std::string const& _resourceID, + int32_t _filterID, bcos::bytes const& _cuckooFilterHash, bool _deserialize); + + ppc::protocol::DataResourceDesc::Ptr obtainCuckooFilterDesc( + std::string const& _resourceID, std::string const& _hexHash) + { + auto desc = std::make_shared(); + auto resourceIDHash = m_config->binHashImpl()->hash( + bcos::bytesConstRef((bcos::byte const*)_resourceID.data(), _resourceID.size())); + + std::string path = m_config->dataPath() + "/" + bcos::toHex(resourceIDHash) + "/" + + _hexHash + c_dataPostFix; + // use file + if (!m_config->fileStorage()) + { + desc->setType((uint16_t)ppc::protocol::DataResourceType::FILE); + } + else + { + // use hdfs + // Note: we use dbName to distinguish files for different-nodes + path = m_config->dbName() + "/" + path; + desc->setType((uint16_t)ppc::protocol::DataResourceType::HDFS); + } + + desc->setPath(path); + return desc; + } + + // delete the given cuckoo-filter + virtual void deleteCuckooFilter(std::string const& _resourceID, int32_t _filterID); + +private: + RA2018PSIConfig::Ptr m_config; + + std::string const m_resourceIDField = "resource_id"; + // the filter-id auto-inc + std::string const m_filterIDField = "filter_id"; + std::string const m_filterHashField = "hash"; + std::string const m_loadField = "full"; + + std::string const c_dataPostFix = ".filter"; +}; +} // namespace ppc::psi \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-psi/tests/CMakeLists.txt b/cpp/wedpr-computing/ppc-psi/tests/CMakeLists.txt new file mode 100644 index 00000000..327c5bc0 --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/tests/CMakeLists.txt @@ -0,0 +1,11 @@ +file(GLOB_RECURSE SOURCES "*.cpp" "*.h") + +# cmake settings +set(TEST_BINARY_NAME test-ppc-psi) + +add_executable(${TEST_BINARY_NAME} ${SOURCES}) +target_include_directories(${TEST_BINARY_NAME} PRIVATE .) + +target_link_libraries(${TEST_BINARY_NAME} ${BS_ECDH_PSI_TARGET} ${ECDH_CONN_PSI_TARGET} ${RA2018_PSI_TARGET} ${LABELED_PSI_TARGET} ${CM2020_PSI_TARGET} ${ECDH_2PC_PSI_TARGET} ${LABELED_PSI_TARGET} ${CRYPTO_TARGET} ${BOOST_UNIT_TEST}) +target_link_libraries(${TEST_BINARY_NAME} ${RA2018_PSI_TARGET} ${LABELED_PSI_TARGET} ${CM2020_PSI_TARGET} ${ECDH_2PC_PSI_TARGET} ${LABELED_PSI_TARGET} ${CRYPTO_TARGET} ${BOOST_UNIT_TEST}) +add_test(NAME test-ppc-psi WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} COMMAND ${TEST_BINARY_NAME}) \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-psi/tests/bs-ecdh-psi/TestBsEcdhCache.cpp b/cpp/wedpr-computing/ppc-psi/tests/bs-ecdh-psi/TestBsEcdhCache.cpp new file mode 100644 index 00000000..c7049f71 --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/tests/bs-ecdh-psi/TestBsEcdhCache.cpp @@ -0,0 +1,194 @@ +/** + * Copyright (C) 2022 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 applicabl 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 TestBsEcdhCache.cpp + * @author: shawnhe + * @date 2023-10-10 + */ + +#include "ppc-io/src/DataResourceLoaderImpl.h" +#include "ppc-io/src/FileLineReader.h" +#include "ppc-psi/src/bs-ecdh-psi/BsEcdhPSIFactory.h" +#include "ppc-psi/src/bs-ecdh-psi/core/BsEcdhCache.h" +#include "test-utils/FakeFront.h" +#include "test-utils/FileTool.h" +#include "test-utils/TaskMock.h" +#include +#include +#include + +using namespace ppc::psi; +using namespace bcos; +using namespace bcos::test; +using namespace ppc::protocol; +using namespace ppc::io; +using namespace ppc::test; + +namespace ppc::test +{ +BOOST_FIXTURE_TEST_SUITE(BsEcdhCacheTest, TestPromptFixture) + +void testEcdhFunc(const std::string& _input, BsEcdhCache::Ptr _cache0, BsEcdhCache::Ptr _cache1) +{ + _cache0->generateKey(); + _cache1->generateKey(); + auto cipher0 = _cache0->genCipherWithBase64(_input); + auto cipher1 = _cache1->genCipherWithBase64(_input); + auto ecdhCipher0 = _cache1->genEcdhCipherWithBase64(cipher0); + auto ecdhCipher1 = _cache0->genEcdhCipherWithBase64(cipher1); + BOOST_CHECK(ecdhCipher0 == ecdhCipher1); + BOOST_CHECK(ecdhCipher0.size() > POINT_SIZE); + BOOST_CHECK(ecdhCipher1.size() > POINT_SIZE); +} + +BOOST_AUTO_TEST_CASE(testEcdhEnc) +{ + auto cache0 = std::make_shared( + "test0", nullptr, nullptr, nullptr, false, false, nullptr, nullptr, nullptr, 100); + auto cache1 = std::make_shared( + "test1", nullptr, nullptr, nullptr, false, false, nullptr, nullptr, nullptr, 100); + for (int i = 0; i < 100; i++) + { + testEcdhFunc(std::to_string(i), cache0, cache1); + } + + std::string input = "hello world"; + std::string key0 = bcos::base64Decode("teT9hMCdq8UCskX6CRlJ9bX7bC5TZ4M1O/eQlpHmyws="); + std::string key1 = bcos::base64Decode("Oav3jsBuamDwLyUo33VOYumJc0f/ySo5oLbkBe+fMgo="); + cache0->setKey(bcos::bytes(key0.begin(), key0.end())); + cache1->setKey(bcos::bytes(key1.begin(), key1.end())); + auto cipher0 = cache0->genCipherWithBase64(input); + auto cipher1 = cache1->genCipherWithBase64(input); + auto ecdhCipher0 = cache1->genEcdhCipherWithBase64(cipher0); + auto ecdhCipher1 = cache0->genEcdhCipherWithBase64(cipher1); + + std::cout << cipher0 << std::endl; + std::cout << cipher1 << std::endl; + std::cout << ecdhCipher0 << std::endl; + std::cout << ecdhCipher1 << std::endl; + + BOOST_CHECK(ecdhCipher0 == ecdhCipher1); +} + +BOOST_AUTO_TEST_CASE(testBsEcdh) +{ + auto inputPath = "../../../../wedpr-computing/ppc-psi/tests/bs-ecdh-psi/data/inputs.csv"; + auto outputPath = "../../../../../wedpr-computing/ppc-psi/tests/bs-ecdh-psi/data/outputs.csv"; + boost::filesystem::create_directory( + "../../../../wedpr-computing/ppc-psi/tests/bs-ecdh-psi/data"); + + auto count = 123456; + prepareInputs(inputPath, count); + + auto taskRequest = std::make_shared(); + auto taskID = "0x123456"; + auto dataResource = std::make_shared("id"); + auto dataDesc = std::make_shared(); + dataDesc->setType(0); + dataDesc->setPath(inputPath); + dataResource->setDesc(dataDesc); + auto outDesc = std::make_shared(); + outDesc->setType(0); + outDesc->setPath(outputPath); + dataResource->setOutputDesc(outDesc); + taskRequest->dataResource = dataResource; + taskRequest->taskID = taskID; + taskRequest->enableAudit = true; + + auto dataResourceLoader = std::make_shared( + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr); + auto bsEcdhPSIFactory = std::make_shared(); + auto bsEcdhPSI = bsEcdhPSIFactory->buildBsEcdhPSI( + std::make_shared("test_bs-ecdh-psi", std::thread::hardware_concurrency()), + dataResourceLoader, 60); + bsEcdhPSI->enableOutputExists(); + bsEcdhPSI->start(); + bsEcdhPSI->asyncRunTask(taskRequest, nullptr); + + auto getTaskStatusRequest = std::make_shared(); + getTaskStatusRequest->taskID = taskID; + + while (bsEcdhPSI->getTaskStatus(getTaskStatusRequest)->data()["status"].asString() == + protocol::toString(TaskStatus::PENDING)) + { + std::this_thread::sleep_for(std::chrono::seconds(1)); + } + + BOOST_CHECK(bsEcdhPSI->getTaskStatus(getTaskStatusRequest)->data()["status"].asString() == + protocol::toString(TaskStatus::RUNNING)); + + auto cache = std::make_shared( + "test", nullptr, nullptr, nullptr, false, false, nullptr, nullptr, nullptr, count); + cache->generateKey(); + + uint32_t offset = 0; + uint32_t size = 10000; + uint32_t total = count; + do + { + auto fetchCipherRequest = std::make_shared(); + fetchCipherRequest->taskID = taskID; + fetchCipherRequest->offset = offset; + fetchCipherRequest->size = size; + auto result = bsEcdhPSI->fetchCipher(fetchCipherRequest); + total = result->data()["total"].asInt(); + std::vector ciphers; + for (const Json::Value& cipher : result->data()["ciphers"]) + { + ciphers.push_back(cipher.asString()); + } + + auto sendEcdhCipherRequest = std::make_shared(); + sendEcdhCipherRequest->taskID = taskID; + sendEcdhCipherRequest->offset = offset; + sendEcdhCipherRequest->size = ciphers.size(); + + for (const auto& cipher : ciphers) + { + sendEcdhCipherRequest->ecdhCiphers.push_back(cache->genEcdhCipherWithBase64(cipher)); + } + bsEcdhPSI->sendEcdhCipher(sendEcdhCipherRequest); + bsEcdhPSI->sendEcdhCipher(sendEcdhCipherRequest); + + auto sendPartnerCipherRequest = std::make_shared(); + sendPartnerCipherRequest->taskID = taskID; + sendPartnerCipherRequest->offset = offset; + sendPartnerCipherRequest->size = ciphers.size(); + sendPartnerCipherRequest->total = total; + + for (uint32_t i = offset; i < ciphers.size() + offset; i++) + { + sendPartnerCipherRequest->partnerCiphers.push_back( + cache->genCipherWithBase64(std::to_string(100000 + i))); + } + bsEcdhPSI->sendPartnerCipher(sendPartnerCipherRequest); + bsEcdhPSI->sendPartnerCipher(sendPartnerCipherRequest); + + offset += ciphers.size(); + } while (offset < total); + + while (bsEcdhPSI->getTaskStatus(getTaskStatusRequest)->data()["status"].asString() == + protocol::toString(TaskStatus::RUNNING)) + { + std::this_thread::sleep_for(std::chrono::seconds(1)); + } + + BOOST_CHECK(bsEcdhPSI->getTaskStatus(getTaskStatusRequest)->data()["status"].asString() == + protocol::toString(TaskStatus::COMPLETED)); +} + + +BOOST_AUTO_TEST_SUITE_END() +} // namespace ppc::test \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-psi/tests/cm2020-psi/FakeCM2020PSIFactory.h b/cpp/wedpr-computing/ppc-psi/tests/cm2020-psi/FakeCM2020PSIFactory.h new file mode 100644 index 00000000..9a4954bb --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/tests/cm2020-psi/FakeCM2020PSIFactory.h @@ -0,0 +1,86 @@ +/** + * Copyright (C) 2022 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 FakeCM2020PSIFactory.h + * @author: shawnhe + * @date 2022-12-19 + */ +#pragma once +#include "ppc-crypto-core/src/hash/BLAKE2bHash.h" +#include "ppc-crypto/src/ecc/Ed25519EccCrypto.h" +#include "ppc-framework/crypto/CryptoBox.h" +#include "ppc-io/src/DataResourceLoaderImpl.h" +#include "ppc-io/src/FileLineReader.h" +#include "ppc-tools/src/config/PPCConfig.h" +#include "test-utils/FakeFront.h" +#include + +using namespace bcos; +using namespace ppc::protocol; +using namespace ppc::psi; +using namespace ppc::crypto; +using namespace ppc::io; +using namespace ppc::front; +using namespace ppc::tools; + +namespace ppc::test +{ +class FakeCM2020PSIImpl : public CM2020PSIImpl +{ +public: + using Ptr = std::shared_ptr; + FakeCM2020PSIImpl(CM2020PSIConfig::Ptr const& _config, unsigned _idleTimeMs = 0) + : CM2020PSIImpl(_config, _idleTimeMs) + {} + ~FakeCM2020PSIImpl() override = default; +}; + +class FakeCM2020PSIFactory : public CM2020PSIFactory +{ +public: + using Ptr = std::shared_ptr; + + FakeCM2020PSIFactory() + : m_front(std::make_shared()), + m_dataResourceLoader(std::make_shared( + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr)), + m_threadPool(std::make_shared("cm2018-psi", 4)) + { + auto hashImpl = std::make_shared(); + auto eccCrypto = std::make_shared(); + m_cryptoBox = std::make_shared(hashImpl, eccCrypto); + } + + ~FakeCM2020PSIFactory() override = default; + + CM2020PSIImpl::Ptr createCM2020PSI(std::string const& _selfParty) + { + auto config = std::make_shared( + _selfParty, m_front, m_cryptoBox, m_threadPool, m_dataResourceLoader, 1); + + return std::make_shared(config); + } + + DataResourceLoaderImpl::Ptr resourceLoader() { return m_dataResourceLoader; } + FakeFront::Ptr front() { return m_front; } + CryptoBox::Ptr cryptoBox() { return m_cryptoBox; } + +private: + FakeFront::Ptr m_front; + DataResourceLoaderImpl::Ptr m_dataResourceLoader; + ThreadPool::Ptr m_threadPool; + CryptoBox::Ptr m_cryptoBox; +}; +} // namespace ppc::test \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-psi/tests/cm2020-psi/TestCM2020Impl.cpp b/cpp/wedpr-computing/ppc-psi/tests/cm2020-psi/TestCM2020Impl.cpp new file mode 100644 index 00000000..6014a1df --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/tests/cm2020-psi/TestCM2020Impl.cpp @@ -0,0 +1,350 @@ +/** + * Copyright (C) 2022 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 applicabl 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 TestCM2020Impl.cpp + * @author: shawnhe + * @date 2022-12-19 + */ + +#include "FakeCM2020PSIFactory.h" +#include "ppc-io/src/FileLineReader.h" +#include "ppc-psi/src/cm2020-psi/CM2020PSIImpl.h" +#include "protocol/src/JsonTaskImpl.h" +#include "test-utils/FakeFront.h" +#include "test-utils/FileTool.h" +#include "test-utils/TaskMock.h" +#include +#include +#include + +using namespace ppc::psi; +using namespace ppc::io; +using namespace bcos; +using namespace bcos::test; +using namespace ppc::crypto; +using namespace ppc::tools; +using namespace ppc::protocol; +using namespace ppc::io; + +namespace ppc::test +{ +BOOST_FIXTURE_TEST_SUITE(CM2020ImplTest, TestPromptFixture) + +void checkTaskPSIResult(DataResourceLoader::Ptr _resourceLoader, + ppc::protocol::Task::ConstPtr _task, uint64_t expectedResultSize, + std::vector _expectedPSIResult) +{ + auto outputDesc = _task->selfParty()->dataResource()->outputDesc(); + auto reader = _resourceLoader->loadReader(outputDesc, DataSchema::String, false); + // get all result + auto result = reader->next(-1); + // check the result + std::cout << "### result size:" << result->size() << std::endl; + std::cout << "### expectedResultSize: " << expectedResultSize << std::endl; + BOOST_CHECK(result->size() == expectedResultSize); + if (_expectedPSIResult.empty()) + { + return; + } + for (uint64_t i = 0; i < result->size(); i++) + { + BOOST_CHECK(result->get(i) == _expectedPSIResult.at(i)); + } +} + +void testCM2020PSI(FakeCM2020PSIFactory::Ptr _factory, CM2020PSIImpl::Ptr _sender, + CM2020PSIImpl::Ptr _receiver, ppc::protocol::Task::ConstPtr _senderPsiTask, + ppc::protocol::Task::ConstPtr _receiverPsiTask, + std::vector const& _expectedPSIResult, bool _expectedSuccess, + int _expectedErrorCode = 0) +{ + std::atomic flag = 0; + _sender->asyncRunTask(_senderPsiTask, [_senderPsiTask, _expectedSuccess, _expectedErrorCode, + &flag](ppc::protocol::TaskResult::Ptr&& _response) { + if (_expectedSuccess) + { + BOOST_CHECK(_response->error() == nullptr || _response->error()->errorCode() == 0); + BOOST_CHECK(_response->taskID() == _senderPsiTask->id()); + auto result = _response->error(); + BOOST_CHECK(result == nullptr || result->errorCode() == 0); + } + else + { + BOOST_CHECK(_response->error() != nullptr); + auto result = _response->error(); + BOOST_CHECK(result != nullptr); + BOOST_CHECK(_response->error()->errorCode() == _expectedErrorCode); + } + flag++; + }); + + _receiver->asyncRunTask(_receiverPsiTask, + [_receiverPsiTask, _expectedSuccess, &flag](ppc::protocol::TaskResult::Ptr&& _response) { + if (_expectedSuccess) + { + BOOST_CHECK(_response->error() == nullptr || _response->error()->errorCode() == 0); + BOOST_CHECK(_response->taskID() == _receiverPsiTask->id()); + auto result = _response->error(); + BOOST_CHECK(result == nullptr || result->errorCode() == 0); + } + else + { + BOOST_CHECK(_response->error() != nullptr); + auto result = _response->error(); + BOOST_CHECK(result != nullptr); + } + flag++; + }); + + std::this_thread::sleep_for(std::chrono::milliseconds(1000)); + _sender->start(); + _receiver->start(); + + // wait for the task finish and check + while (flag < 2) + { + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } + + _sender->stop(); + _receiver->stop(); + + if (_expectedSuccess && !_expectedPSIResult.empty()) + { + checkTaskPSIResult(_factory->resourceLoader(), _receiverPsiTask, _expectedPSIResult.size(), + _expectedPSIResult); + } +} + + +void testCM2020PSIImplFunc(const std::string& _taskID, const std::string& _params, + bool _syncResults, PartyResource::Ptr _senderParty, PartyResource::Ptr _receiverParty, + std::vector const& _expectedPSIResult, bool _expectedSuccess, + int _expectedErrorCode = 0) +{ + auto factory = std::make_shared(); + + // fake the sender + std::string senderAgencyName = _senderParty->id(); + auto senderPSI = factory->createCM2020PSI(senderAgencyName); + + // fake the receiver + std::string receiverAgencyName = _receiverParty->id(); + auto receiverPSI = factory->createCM2020PSI(receiverAgencyName); + + // register the server-psi into the front + factory->front()->registerCM2020(senderAgencyName, senderPSI); + factory->front()->registerCM2020(receiverAgencyName, receiverPSI); + + // trigger the psi task + auto senderPSITask = std::make_shared(senderAgencyName); + senderPSITask->setId(_taskID); + senderPSITask->setParam(_params); + senderPSITask->setSelf(_senderParty); + senderPSITask->setEnableOutputExists(true); + senderPSITask->addParty(_receiverParty); + senderPSITask->setSyncResultToPeer(_syncResults); + senderPSITask->setAlgorithm((uint8_t)TaskAlgorithmType::CM_PSI_2PC); + + auto receiverPSITask = std::make_shared(receiverAgencyName); + receiverPSITask->setId(_taskID); + receiverPSITask->setParam(_params); + receiverPSITask->setSelf(_receiverParty); + receiverPSITask->setEnableOutputExists(true); + receiverPSITask->addParty(_senderParty); + receiverPSITask->setSyncResultToPeer(_syncResults); + receiverPSITask->setAlgorithm((uint8_t)TaskAlgorithmType::CM_PSI_2PC); + + testCM2020PSI(factory, senderPSI, receiverPSI, senderPSITask, receiverPSITask, + _expectedPSIResult, _expectedSuccess, _expectedErrorCode); +} + +BOOST_AUTO_TEST_CASE(testNormalCM2020PSICase) +{ + std::string senderPath = + "../../../../wedpr-computing/ppc-psi/tests/cm2020-psi/data/sender_inputs.csv"; + std::string receiverPath = + "../../../../wedpr-computing/ppc-psi/tests/cm2020-psi/data/receiver_inputs.csv"; + std::string senderOutputPath = + "../../../../wedpr-computing/ppc-psi/tests/cm2020-psi/data/sender_out.csv"; + std::string receiverOutputPath = + "../../../../wedpr-computing/ppc-psi/tests/cm2020-psi/data/receiver_out.csv"; + + uint32_t count = 513; + boost::filesystem::create_directory( + "../../../../wedpr-computing/ppc-psi/tests/cm2020-psi/data"); + prepareInputs(senderPath, count, receiverPath, count, count); + + auto senderParty = mockParty((uint16_t)ppc::protocol::PartyType::Server, "sender", + "senderPartyResource", "sender_inputs", DataResourceType::FILE, senderPath); + auto senderOutputDesc = std::make_shared(); + senderOutputDesc->setPath(senderOutputPath); + senderParty->mutableDataResource()->setOutputDesc(senderOutputDesc); + + auto receiverParty = mockParty((uint16_t)ppc::protocol::PartyType::Client, "receiver", + "receiverPartyResource", "receiver_inputs", DataResourceType::FILE, receiverPath); + auto receiverOutputDesc = std::make_shared(); + receiverOutputDesc->setPath(receiverOutputPath); + receiverParty->mutableDataResource()->setOutputDesc(receiverOutputDesc); + + std::vector expectedResult; + for (uint32_t i = 0; i < count; i++) + { + expectedResult.emplace_back(std::to_string(100000 + i)); + } + + testCM2020PSIImplFunc( + "0x12345678", "[0]", true, senderParty, receiverParty, expectedResult, true, 0); + testCM2020PSIImplFunc( + "0x12345678", "[1]", true, senderParty, receiverParty, expectedResult, true, 0); + testCM2020PSIImplFunc( + "0x12345678", "[0]", false, senderParty, receiverParty, expectedResult, true, 0); + testCM2020PSIImplFunc( + "0x12345678", "[1]", false, senderParty, receiverParty, expectedResult, true, 0); +} + +BOOST_AUTO_TEST_CASE(testBigDataCM2020PSICase) +{ + std::string senderPath = + "../../../../wedpr-computing/ppc-psi/tests/cm2020-psi/data/sender_inputs.csv"; + std::string receiverPath = + "../../../../wedpr-computing/ppc-psi/tests/cm2020-psi/data/receiver_inputs.csv"; + std::string senderOutputPath = + "../../../../wedpr-computing/ppc-psi/tests/cm2020-psi/data/sender_out.csv"; + std::string receiverOutputPath = + "../../../../wedpr-computing/ppc-psi/tests/cm2020-psi/data/receiver_out.csv"; + + uint32_t count = 1000000, common = 100; + + boost::filesystem::create_directory( + "../../../../wedpr-computing/ppc-psi/tests/cm2020-psi/data"); + prepareInputs(senderPath, count, receiverPath, count, common); + + auto senderParty = mockParty(uint16_t(PartyType::Server), "sender", "senderPartyResource", + "sender_inputs", DataResourceType::FILE, senderPath); + auto senderOutputDesc = std::make_shared(); + senderOutputDesc->setPath(senderOutputPath); + senderParty->mutableDataResource()->setOutputDesc(senderOutputDesc); + + auto receiverParty = mockParty(uint16_t(PartyType::Client), "receiver", "receiverPartyResource", + "receiver_inputs", DataResourceType::FILE, receiverPath); + auto receiverOutputDesc = std::make_shared(); + receiverOutputDesc->setPath(receiverOutputPath); + receiverParty->mutableDataResource()->setOutputDesc(receiverOutputDesc); + + std::vector expectedResult; + for (uint32_t i = 0; i < common; i++) + { + expectedResult.emplace_back(std::to_string(100000 + count - common + i)); + } + + testCM2020PSIImplFunc( + "0x12345678", "[0]", false, senderParty, receiverParty, expectedResult, true, 0); +} + +BOOST_AUTO_TEST_CASE(testErrorCM2020PSICase) +{ + std::string senderPath = + "../../../../wedpr-computing/ppc-psi/tests/cm2020-psi/data/sender_inputs.csv"; + std::string receiverPath = + "../../../../wedpr-computing/ppc-psi/tests/cm2020-psi/data/receiver_inputs.csv"; + std::string senderOutputPath = + "../../../../wedpr-computing/ppc-psi/tests/cm2020-psi/data/sender_out.csv"; + std::string receiverOutputPath = + "../../../../wedpr-computing/ppc-psi/tests/cm2020-psi/data/receiver_out.csv"; + + uint32_t count = 1234; + boost::filesystem::create_directory( + "../../../../wedpr-computing/ppc-psi/tests/cm2020-psi/data"); + prepareInputs(senderPath, count, receiverPath, count, count); + + auto senderParty = mockParty(uint16_t(PartyType::Server), "sender", "senderPartyResource", + "sender_inputs", DataResourceType::FILE, + "../../../../wedpr-computing/ppc-psi/tests/cm2020-psi/data/not_existed.csv"); + + auto senderOutputDesc = std::make_shared(); + senderOutputDesc->setPath(senderOutputPath); + senderParty->mutableDataResource()->setOutputDesc(senderOutputDesc); + + auto receiverParty = mockParty(uint16_t(PartyType::Client), "receiver", "receiverPartyResource", + "receiver_inputs", DataResourceType::FILE, receiverPath); + auto receiverOutputDesc = std::make_shared(); + receiverOutputDesc->setPath(receiverOutputPath); + receiverParty->mutableDataResource()->setOutputDesc(receiverOutputDesc); + + testCM2020PSIImplFunc("0x12345678", "[0]", false, senderParty, receiverParty, + std::vector(), false, -3000); +} + +BOOST_AUTO_TEST_CASE(testRawDataCM2020PSICase) +{ + std::string senderPath = + "../../../../wedpr-computing/ppc-psi/tests/cm2020-psi/data/sender_inputs.csv"; + std::string receiverPath = + "../../../../wedpr-computing/ppc-psi/tests/cm2020-psi/data/receiver_inputs.csv"; + std::string senderOutputPath = + "../../../../wedpr-computing/ppc-psi/tests/cm2020-psi/data/sender_out.csv"; + std::string receiverOutputPath = + "../../../../wedpr-computing/ppc-psi/tests/cm2020-psi/data/receiver_out.csv"; + + uint32_t count = 1234; + boost::filesystem::create_directory( + "../../../../wedpr-computing/ppc-psi/tests/cm2020-psi/data"); + prepareInputs(senderPath, count, receiverPath, count, count); + + auto reader = std::make_shared(senderPath); + auto data = reader->next(-1); + std::vector> sRawData(1); + for (uint32_t i = 0; i < data->size(); i++) + { + sRawData[0].emplace_back(data->get(i)); + } + + auto senderParty = mockParty(uint16_t(PartyType::Server), "sender", "senderPartyResource", + "sender_inputs", DataResourceType::FILE, senderPath, sRawData); + + auto senderOutputDesc = std::make_shared(); + senderOutputDesc->setPath(senderOutputPath); + senderParty->mutableDataResource()->setOutputDesc(senderOutputDesc); + + reader = std::make_shared(senderPath); + data = reader->next(-1); + std::vector> rRawData(1); + for (uint32_t i = 0; i < data->size(); i++) + { + rRawData[0].emplace_back(data->get(i)); + } + + auto receiverParty = mockParty(uint16_t(PartyType::Client), "receiver", "receiverPartyResource", + "receiver_inputs", DataResourceType::FILE, receiverPath, rRawData); + auto receiverOutputDesc = std::make_shared(); + receiverOutputDesc->setPath(receiverOutputPath); + receiverParty->mutableDataResource()->setOutputDesc(receiverOutputDesc); + + testCM2020PSIImplFunc( + "0x12345678", "[1]", true, senderParty, receiverParty, std::vector(), true, 0); +} + +BOOST_AUTO_TEST_CASE(testPrepareInptsCase) +{ + std::string senderPath = "/tmp/test0.csv"; + std::string receiverPath = "/tmp/test1.csv"; + + uint32_t count = 1000 * 10000; + prepareInputs(senderPath, count, receiverPath, count, 500000); +} + +BOOST_AUTO_TEST_SUITE_END() +} // namespace ppc::test \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-psi/tests/labeled-psi/DataTools.h b/cpp/wedpr-computing/ppc-psi/tests/labeled-psi/DataTools.h new file mode 100644 index 00000000..03075d6f --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/tests/labeled-psi/DataTools.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2022 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 applicabl 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 DataTools.cpp + * @author: shawnhe + * @date 2022-11-25 + */ + +#pragma +#include "ppc-framework/io/DataBatch.h" +#include +#include + +namespace ppc::psi +{ +inline void genItemsLabels( + ppc::io::DataBatch::Ptr _items, ppc::io::DataBatch::Ptr _labels, uint32_t _size) +{ + std::vector items(_size); + std::vector labels(_size); + for (uint32_t i = 0; i < _size; ++i) + { + std::string item = std::to_string(i); + items[i] = bcos::bytes(item.begin(), item.end()); + labels[i] = bcos::bytes(item.begin(), item.end()); + } + _items->setData(std::move(items)); + _labels->setData(std::move(labels)); +} + +} // namespace ppc::psi diff --git a/cpp/wedpr-computing/ppc-psi/tests/labeled-psi/FakeLabeledPSIFactory.h b/cpp/wedpr-computing/ppc-psi/tests/labeled-psi/FakeLabeledPSIFactory.h new file mode 100644 index 00000000..350d861a --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/tests/labeled-psi/FakeLabeledPSIFactory.h @@ -0,0 +1,85 @@ +/** + * Copyright (C) 2022 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 FakeLabeledPSIFactory.h + * @author: shawnhe + * @date 2022-12-26 + */ +#pragma once + +#include "ppc-crypto-core/src/hash/BLAKE2bHash.h" +#include "ppc-crypto/src/ecc/Ed25519EccCrypto.h" +#include "ppc-framework/crypto/CryptoBox.h" +#include "ppc-io/src/DataResourceLoaderImpl.h" +#include "ppc-io/src/FileLineReader.h" +#include "ppc-tools/src/config/PPCConfig.h" +#include "test-utils/FakeFront.h" +#include +using namespace bcos; +using namespace ppc::protocol; +using namespace ppc::psi; +using namespace ppc::crypto; +using namespace ppc::io; +using namespace ppc::front; +using namespace ppc::tools; + +namespace ppc::test +{ +class FakeLabeledPSIImpl : public LabeledPSIImpl +{ +public: + using Ptr = std::shared_ptr; + FakeLabeledPSIImpl(LabeledPSIConfig::Ptr const& _config, unsigned _idleTimeMs = 0) + : LabeledPSIImpl(_config, _idleTimeMs) + {} + ~FakeLabeledPSIImpl() override = default; +}; + +class FakeLabeledPSIFactory : public LabeledPSIFactory +{ +public: + using Ptr = std::shared_ptr; + + FakeLabeledPSIFactory() + : m_front(std::make_shared()), + m_dataResourceLoader(std::make_shared( + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr)), + m_threadPool(std::make_shared("labeled-psi", 4)) + { + auto hashImpl = std::make_shared(); + auto eccCrypto = std::make_shared(); + m_cryptoBox = std::make_shared(hashImpl, eccCrypto); + } + + ~FakeLabeledPSIFactory() override = default; + + LabeledPSIImpl::Ptr createLabeledPSI(std::string const& _selfParty) + { + auto config = std::make_shared( + _selfParty, m_front, m_cryptoBox, m_threadPool, m_dataResourceLoader, 1); + return std::make_shared(config); + } + + DataResourceLoaderImpl::Ptr resourceLoader() { return m_dataResourceLoader; } + FakeFront::Ptr front() { return m_front; } + CryptoBox::Ptr cryptoBox() { return m_cryptoBox; } + +private: + FakeFront::Ptr m_front; + DataResourceLoaderImpl::Ptr m_dataResourceLoader; + bcos::ThreadPool::Ptr m_threadPool; + CryptoBox::Ptr m_cryptoBox; +}; +} // namespace ppc::test \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-psi/tests/labeled-psi/TestLabeledPSIImpl.cpp b/cpp/wedpr-computing/ppc-psi/tests/labeled-psi/TestLabeledPSIImpl.cpp new file mode 100644 index 00000000..62f6fd2e --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/tests/labeled-psi/TestLabeledPSIImpl.cpp @@ -0,0 +1,330 @@ +/** + * Copyright (C) 2022 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 applicabl 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 TestCM2020Impl.cpp + * @author: shawnhe + * @date 2022-12-26 + */ + +#include "FakeLabeledPSIFactory.h" +#include "ppc-io/src/FileLineReader.h" +#include "ppc-psi/src/labeled-psi/LabeledPSIImpl.h" +#include "ppc-psi/src/labeled-psi/protocol/LabeledPSIResult.h" +#include "protocol/src/JsonTaskImpl.h" +#include "test-utils/FileTool.h" +#include "test-utils/TaskMock.h" +#include +#include +#include +using namespace ppc::psi; +using namespace bcos; +using namespace bcos::test; +using namespace ppc::crypto; +using namespace ppc::tools; +using namespace ppc::protocol; +using namespace ppc::io; + +namespace ppc::test +{ +BOOST_FIXTURE_TEST_SUITE(LabeledPSIImplTest, TestPromptFixture) + +void runSetup(LabeledPSIImpl::Ptr _sender) +{ + std::string senderPath = + "../../../../wedpr-computing/ppc-psi/tests/labeled-psi/data/sender.csv"; + + uint32_t count = 10000; + boost::filesystem::create_directory( + "../../../../wedpr-computing/ppc-psi/tests/labeled-psi/data"); + prepareItemsAndLabels(senderPath, count); + + auto senderParty = mockParty(uint16_t(PartyType::Server), "sender", "senderPartyResource", + "sender_inputs", DataResourceType::FILE, senderPath); + auto senderOutputDesc = std::make_shared(); + + // fake the sender + std::string senderAgencyName = senderParty->id(); + + auto senderPSITask = std::make_shared(senderAgencyName); + senderPSITask->setId("0x00000000"); + senderPSITask->setEnableOutputExists(true); + senderPSITask->setParam(R"(["setup_sender_db","32"])"); + senderPSITask->setSelf(senderParty); + senderPSITask->setAlgorithm((uint8_t)TaskAlgorithmType::LABELED_PSI_2PC); + + std::atomic flag = 0; + _sender->asyncRunTask(senderPSITask, [&flag](ppc::protocol::TaskResult::Ptr&& _response) { + BOOST_CHECK(_response->error() == nullptr || _response->error()->errorCode() == 0); + auto result = _response->error(); + BOOST_CHECK(result == nullptr || result->errorCode() == 0); + flag++; + }); + + while (flag < 1) + { + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } +} + +void saveCache(LabeledPSIImpl::Ptr _sender) +{ + std::string cachePath = + "../../../../wedpr-computing/ppc-psi/tests/labeled-psi/data/sender_cache.txt"; + boost::filesystem::create_directory( + "../../../../wedpr-computing/ppc-psi/tests/labeled-psi/data"); + + auto senderParty = mockParty(uint16_t(PartyType::Server), "sender", "senderPartyResource", + "sender_inputs", DataResourceType::FILE, ""); + auto senderOutputDesc = std::make_shared(); + senderOutputDesc->setPath(cachePath); + senderParty->mutableDataResource()->setOutputDesc(senderOutputDesc); + + // fake the sender + std::string senderAgencyName = senderParty->id(); + + auto senderPSITask = std::make_shared(senderAgencyName); + senderPSITask->setId("0x00000012"); + senderPSITask->setEnableOutputExists(true); + senderPSITask->setParam(R"(["save_sender_cache"])"); + senderPSITask->setSelf(senderParty); + senderPSITask->setAlgorithm((uint8_t)TaskAlgorithmType::LABELED_PSI_2PC); + + std::atomic flag = 0; + _sender->asyncRunTask(senderPSITask, [&flag](ppc::protocol::TaskResult::Ptr&& _response) { + BOOST_CHECK(_response->error() == nullptr || _response->error()->errorCode() == 0); + auto result = _response->error(); + BOOST_CHECK(result == nullptr || result->errorCode() == 0); + flag++; + }); + + while (flag < 1) + { + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } +} + +void loadCache(LabeledPSIImpl::Ptr _sender) +{ + std::string cachePath = + "../../../../wedpr-computing/ppc-psi/tests/labeled-psi/data/sender_cache.txt"; + + auto senderParty = mockParty(uint16_t(PartyType::Server), "sender", "senderPartyResource", + "sender_inputs", DataResourceType::FILE, cachePath); + + // fake the sender + std::string senderAgencyName = senderParty->id(); + + auto senderPSITask = std::make_shared(senderAgencyName); + senderPSITask->setId("0x00000034"); + senderPSITask->setParam(R"(["load_sender_cache"])"); + senderPSITask->setSelf(senderParty); + senderPSITask->setAlgorithm((uint8_t)TaskAlgorithmType::LABELED_PSI_2PC); + + std::atomic flag = 0; + _sender->asyncRunTask(senderPSITask, [&flag](ppc::protocol::TaskResult::Ptr&& _response) { + BOOST_CHECK(_response->error() == nullptr || _response->error()->errorCode() == 0); + auto result = _response->error(); + BOOST_CHECK(result == nullptr || result->errorCode() == 0); + flag++; + }); + + while (flag < 1) + { + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } +} + +void testLabeledPSI(LabeledPSIImpl::Ptr _sender, LabeledPSIImpl::Ptr _receiver, + ppc::protocol::Task::ConstPtr _senderPsiTask, ppc::protocol::Task::ConstPtr _receiverPsiTask, + bool _expectedSuccess, int _expectedErrorCode = 0, int _hit = 0) +{ + std::atomic flag = 0; + + _receiver->asyncRunTask(_receiverPsiTask, + [_receiverPsiTask, _expectedSuccess, _hit, &flag](protocol::TaskResult::Ptr&& _response) { + if (_expectedSuccess) + { + BOOST_CHECK(_response->error() == nullptr || _response->error()->errorCode() == 0); + BOOST_CHECK(_response->taskID() == _receiverPsiTask->id()); + auto result = _response->error(); + BOOST_CHECK(result == nullptr || result->errorCode() == 0); + + LabeledPSIResult::Ptr labeledPSIResult = + std::dynamic_pointer_cast(_response); + BOOST_CHECK(labeledPSIResult->getOutputs()[0].size() == uint(_hit)); + // std::cout << labeledPSIResult->getOutputs() << std::endl; + } + else + { + BOOST_CHECK(_response->error() != nullptr); + auto result = _response->error(); + BOOST_CHECK(result != nullptr); + } + flag++; + }); + + _sender->asyncRunTask(_senderPsiTask, [_senderPsiTask, _expectedSuccess, _expectedErrorCode, + &flag](ppc::protocol::TaskResult::Ptr&& _response) { + if (_expectedSuccess) + { + BOOST_CHECK(_response->error() == nullptr || _response->error()->errorCode() == 0); + BOOST_CHECK(_response->taskID() == _senderPsiTask->id()); + auto result = _response->error(); + BOOST_CHECK(result == nullptr || result->errorCode() == 0); + } + else + { + BOOST_CHECK(_response->error() != nullptr); + auto result = _response->error(); + BOOST_CHECK(result != nullptr); + BOOST_CHECK(_response->error()->errorCode() == _expectedErrorCode); + } + flag++; + }); + + // wait for the task finish and check + while (flag < 2) + { + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } +} + +void testLabeledPSIImplFunc(const std::string& _taskID, const std::string& _params, + PartyResource::Ptr _senderParty, PartyResource::Ptr _receiverParty, bool _ready, bool _testLoad, + bool _expectedSuccess, int _expectedErrorCode = 0, int _hit = 0) +{ + auto factory = std::make_shared(); + + // fake the sender + std::string senderAgencyName = _senderParty->id(); + auto senderPSI = factory->createLabeledPSI(senderAgencyName); + senderPSI->start(); + if (_ready) + { + if (_testLoad) + { + loadCache(senderPSI); + } + else + { + runSetup(senderPSI); + saveCache(senderPSI); + } + } + + // fake the receiver + std::string receiverAgencyName = _receiverParty->id(); + auto receiverPSI = factory->createLabeledPSI(receiverAgencyName); + receiverPSI->start(); + + // register the server-psi into the front + factory->front()->registerLabeledPSI(senderAgencyName, senderPSI); + factory->front()->registerLabeledPSI(receiverAgencyName, receiverPSI); + + // trigger the psi task + auto senderPSITask = std::make_shared(senderAgencyName); + senderPSITask->setId(_taskID); + senderPSITask->setEnableOutputExists(true); + senderPSITask->setParam(_params); + senderPSITask->setSelf(_senderParty); + senderPSITask->setAlgorithm((uint8_t)TaskAlgorithmType::LABELED_PSI_2PC); + senderPSITask->addParty(_receiverParty); + + auto receiverPSITask = std::make_shared(receiverAgencyName); + receiverPSITask->setId(_taskID); + receiverPSITask->setEnableOutputExists(true); + receiverPSITask->setSelf(_receiverParty); + receiverPSITask->setAlgorithm((uint8_t)TaskAlgorithmType::LABELED_PSI_2PC); + receiverPSITask->addParty(_senderParty); + + testLabeledPSI(senderPSI, receiverPSI, senderPSITask, receiverPSITask, _expectedSuccess, + _expectedErrorCode, _hit); + + senderPSI->stop(); + receiverPSI->stop(); +} + + +BOOST_AUTO_TEST_CASE(testSenderSetup) +{ + auto factory = std::make_shared(); + + // fake the sender + std::string senderAgencyName = "sender"; + auto senderPSI = factory->createLabeledPSI(senderAgencyName); + + senderPSI->start(); + + runSetup(senderPSI); + + senderPSI->stop(); +} + + +BOOST_AUTO_TEST_CASE(testLabeledPSICase) +{ + auto senderParty = mockParty(uint16_t(PartyType::Server), "sender", "senderPartyResource", + "sender_inputs", DataResourceType::FILE, ""); + + std::vector> rRawData(1); + for (int i = 0; i < MAX_QUERY_SIZE / 4; i++) + { + rRawData[0].emplace_back(std::to_string(100000 + i)); + rRawData[0].emplace_back(std::to_string(100000000 + i)); + } + + auto receiverParty = mockParty(uint16_t(PartyType::Client), "", "receiverPartyResource", + "receiver_inputs", DataResourceType::FILE, "", rRawData); + + testLabeledPSIImplFunc("0x12345678", "[\"run_labeled_psi\"]", senderParty, receiverParty, true, + false, true, 0, MAX_QUERY_SIZE / 4); +} + +BOOST_AUTO_TEST_CASE(testLabeledPSINotReady) +{ + auto senderParty = mockParty(uint16_t(PartyType::Server), "sender", "senderPartyResource", + "sender_inputs", DataResourceType::FILE, ""); + + std::vector> rRawData(1); + rRawData[0].emplace_back("100018"); + + auto receiverParty = mockParty(uint16_t(PartyType::Client), "receiver", "receiverPartyResource", + "receiver_inputs", DataResourceType::FILE, "", rRawData); + + testLabeledPSIImplFunc("0x12345678", "[\"run_labeled_psi\"]", senderParty, receiverParty, false, + false, false, -2001); +} + +BOOST_AUTO_TEST_CASE(testLabeledPSILoacdCache) +{ + auto senderParty = mockParty(uint16_t(PartyType::Server), "sender", "senderPartyResource", + "sender_inputs", DataResourceType::FILE, ""); + + std::vector> rRawData(1); + for (int i = 0; i < MAX_QUERY_SIZE / 4; i++) + { + rRawData[0].emplace_back(std::to_string(100000 + i)); + rRawData[0].emplace_back(std::to_string(100000000 + i)); + } + + auto receiverParty = mockParty(uint16_t(PartyType::Client), "", "receiverPartyResource", + "receiver_inputs", DataResourceType::FILE, "", rRawData); + + testLabeledPSIImplFunc("0x12345678", "[\"run_labeled_psi\"]", senderParty, receiverParty, true, + true, true, 0, MAX_QUERY_SIZE / 4); +} + +BOOST_AUTO_TEST_SUITE_END() +} // namespace ppc::test \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-psi/tests/labeled-psi/TestSenderDB.cpp b/cpp/wedpr-computing/ppc-psi/tests/labeled-psi/TestSenderDB.cpp new file mode 100644 index 00000000..0a79fad4 --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/tests/labeled-psi/TestSenderDB.cpp @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2022 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 applicabl 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 TestSenderDB.cpp + * @author: shawnhe + * @date 2022-11-25 + */ + +#include "DataTools.h" +#include "ppc-crypto-core/src/hash/Sha256Hash.h" +#include "ppc-crypto/src/ecc/Ed25519EccCrypto.h" +#include "ppc-crypto/src/oprf/EcdhOprf.h" +#include "ppc-io/src/FileLineReader.h" +#include "ppc-psi/src/labeled-psi/core/LabeledPSIParams.h" +#include "ppc-psi/src/labeled-psi/core/SenderDB.h" +#include "protocol/src/JsonTaskImpl.h" +#include "test-utils/TaskMock.h" +#include +#include +using namespace ppc::psi; +using namespace bcos; +using namespace bcos::test; +using namespace ppc::crypto; +using namespace ppc::protocol; + +namespace ppc::test +{ +BOOST_FIXTURE_TEST_SUITE(SenderDBTest, TestPromptFixture) + +BOOST_AUTO_TEST_CASE(TestPsiParams) +{ + auto params1 = getPsiParams(1024); + BOOST_CHECK(params1.table_params().max_items_per_bin == 42); + BOOST_CHECK(params1.item_params().felts_per_item == 6); + BOOST_CHECK(params1.seal_params().poly_modulus_degree() == 2048); + BOOST_CHECK(params1.query_params().ps_low_degree == 0); + auto params2 = getPsiParams(360000); + BOOST_CHECK(params2.table_params().max_items_per_bin == 228); + BOOST_CHECK(params2.item_params().felts_per_item == 6); + BOOST_CHECK(params2.seal_params().poly_modulus_degree() == 8192); + BOOST_CHECK(params2.query_params().ps_low_degree == 0); + auto params3 = getPsiParams(2000000); + BOOST_CHECK(params3.table_params().max_items_per_bin == 782); + BOOST_CHECK(params3.item_params().felts_per_item == 4); + BOOST_CHECK(params3.seal_params().poly_modulus_degree() == 8192); + BOOST_CHECK(params3.query_params().ps_low_degree == 26); + auto params4 = getPsiParams(20000000); + BOOST_CHECK(params4.table_params().max_items_per_bin == 8100); + BOOST_CHECK(params4.item_params().felts_per_item == 4); + BOOST_CHECK(params4.seal_params().poly_modulus_degree() == 8192); + BOOST_CHECK(params4.query_params().ps_low_degree == 310); +} + +BOOST_AUTO_TEST_CASE(TestSenderDB) +{ + uint32_t count = (1 << 10); + auto items = std::make_shared(); + items->setDataSchema(ppc::io::DataSchema::Bytes); + auto labels = std::make_shared(); + labels->setDataSchema(ppc::io::DataSchema::Bytes); + genItemsLabels(items, labels, count); + BOOST_CHECK(items->size() == count); + + auto hashImpl = std::make_shared(); + auto eccImpl = std::make_shared(); + auto oprfServer = std::make_shared(256, hashImpl, eccImpl); + auto senderDB = std::make_shared(getPsiParams(count), oprfServer, 16, 16, false); + + senderDB->setData(items, labels); + BOOST_CHECK(senderDB->getItemCount() == count); +} + +BOOST_AUTO_TEST_CASE(TestSenderCache) +{ + uint32_t count = (1 << 15); + auto items = std::make_shared(); + items->setDataSchema(ppc::io::DataSchema::Bytes); + auto labels = std::make_shared(); + labels->setDataSchema(ppc::io::DataSchema::Bytes); + genItemsLabels(items, labels, count); + BOOST_CHECK(items->size() == count); + + auto hashImpl = std::make_shared(); + auto eccImpl = std::make_shared(); + auto oprfServer = std::make_shared(256, hashImpl, eccImpl); + auto senderDB = std::make_shared(getPsiParams(count), oprfServer, 16, 16, false); + + senderDB->setData(items, labels); + + bcos::bytes out; + senderDB->saveToBytes(out); + auto newSenderDB = SenderDB::loadFromBytes(oprfServer, out); + + BOOST_CHECK(newSenderDB->getItemCount() == count); + BOOST_CHECK(senderDB->getParams().to_string() == newSenderDB->getParams().to_string()); + BOOST_CHECK(senderDB->isCompressed() == newSenderDB->isCompressed()); + BOOST_CHECK(senderDB->getItemCount() == newSenderDB->getItemCount()); + BOOST_CHECK(senderDB->getHashedItems().size() == newSenderDB->getHashedItems().size()); + BOOST_CHECK(senderDB->getBinBundleCount() == newSenderDB->getBinBundleCount()); +} + + +BOOST_AUTO_TEST_SUITE_END() +} // namespace ppc::test \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-psi/tests/main.cpp b/cpp/wedpr-computing/ppc-psi/tests/main.cpp new file mode 100644 index 00000000..2c06f9b5 --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/tests/main.cpp @@ -0,0 +1,2 @@ +#define BOOST_TEST_MAIN +#include \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-psi/tests/ra2018-psi/TestEcdhPSIImpl.cpp b/cpp/wedpr-computing/ppc-psi/tests/ra2018-psi/TestEcdhPSIImpl.cpp new file mode 100644 index 00000000..c0083254 --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/tests/ra2018-psi/TestEcdhPSIImpl.cpp @@ -0,0 +1,168 @@ +/* + * Copyright (C) 2022 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 applicabl 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 TestEcdhImpl.cpp + * @author: yujiechen + * @date 2022-12-29 + */ +#include "mock/Common.h" +#include "mock/EcdhPSIFixture.h" +// Note: it's better not to depends on the task-impl +#include "ppc-io/src/FileLineReader.h" +#include "protocol/src/JsonTaskImpl.h" +#include "test-utils/TaskMock.h" +#include +#include + +using namespace ppc::psi; +using namespace bcos; +using namespace bcos::test; +using namespace ppc::crypto; +using namespace ppc::tools; +using namespace ppc::protocol; + +namespace ppc::test +{ +BOOST_FIXTURE_TEST_SUITE(EcdhPSIImplTest, TestPromptFixture) +void testEcdhImplFunc(int64_t _dataBatchSize, std::string const& _serverPSIDataSource, + std::string const& _clientPSIDataSource, std::string const& _resultDataPath, + bool _expectOfflineSuccess, bool _expectPSISuccess, + std::vector& _expectedPSIResult, int _expectedErrorCode = 0, + bool _mismatchedTaskID = false) +{ + auto factory = std::make_shared(); + // the server config, with default setting + auto serverConfig = std::make_shared(); + serverConfig->mutableEcdhPSIConfig().dataBatchSize = _dataBatchSize; + serverConfig->setPrivateKey(factory->cryptoBox()->eccCrypto()->generateRandomScalar()); + + // the client config, with default setting + auto clientConfig = std::make_shared(); + clientConfig->mutableEcdhPSIConfig().dataBatchSize = _dataBatchSize; + clientConfig->setPrivateKey(factory->cryptoBox()->eccCrypto()->generateRandomScalar()); + + // fake the server + std::string serverAgencyName = "server"; + auto serverPSI = factory->createEcdhPSI(serverAgencyName, serverConfig); + + // fake the client + std::string clientAgencyName = "client"; + auto clientPSI = factory->createEcdhPSI(clientAgencyName, clientConfig); + + std::vector agencyList = {serverAgencyName, clientAgencyName}; + auto serverFront = std::dynamic_pointer_cast(serverPSI->psiConfig()->front()); + serverFront->setAgencyList(agencyList); + + auto clientFront = std::dynamic_pointer_cast(clientPSI->psiConfig()->front()); + clientFront->setAgencyList(agencyList); + + // register the server-psi into the front + factory->front()->registerEcdhPSI(serverAgencyName, serverPSI); + factory->front()->registerEcdhPSI(clientAgencyName, clientPSI); + // the server party + std::string resourceID = "dataResource"; + std::string clientResourceID = resourceID; + std::string serverResourceID = resourceID; + auto serverParty = mockParty((uint16_t)PartyType::Server, serverAgencyName, "serverParty", + serverResourceID, DataResourceType::FILE, _serverPSIDataSource); + // the clientParty + auto clientParty = mockParty((uint16_t)PartyType::Client, clientAgencyName, "clientParty", + clientResourceID, DataResourceType::FILE, _clientPSIDataSource); + auto outputDesc = std::make_shared(); + outputDesc->setPath(_resultDataPath); + clientParty->mutableDataResource()->setOutputDesc(outputDesc); + // generate client task + auto clientPSITask = std::make_shared(clientAgencyName); + std::string taskID = "runPSI"; + clientPSITask->setId(taskID); + clientPSITask->setEnableOutputExists(true); + clientPSITask->setEnableOutputExists(true); + clientPSITask->setType((int8_t)TaskType::PSI); + clientPSITask->setAlgorithm((int8_t)TaskAlgorithmType::ECDH_PSI_2PC); + clientPSITask->setSelf(clientParty); + clientPSITask->addParty(serverParty); + + // generate server task + auto serverPSITask = std::make_shared(serverAgencyName); + serverPSITask->setSelf(serverParty); + if (_mismatchedTaskID) + { + serverPSITask->setId(taskID + "-mismatch"); + } + else + { + serverPSITask->setId(taskID); + } + serverPSITask->setEnableOutputExists(true); + serverPSITask->setEnableOutputExists(true); + serverPSITask->setType((int8_t)TaskType::PSI); + serverPSITask->setAlgorithm((int8_t)TaskAlgorithmType::ECDH_PSI_2PC); + serverPSITask->addParty(clientParty); + // run psi + testPSI(factory, serverPSI, clientPSI, serverPSITask, clientPSITask, _expectPSISuccess, + _expectedPSIResult, _expectedErrorCode); +} + +void testNormalCase(std::string const& _outputPrefix, int64_t _dataBatchSize) +{ + std::string serverDataPath = + "../../../../wedpr-computing/ppc-psi/tests/ra2018-psi/mock-data/fullevaluate.txt"; + std::string clientDataPath = + "../../../../wedpr-computing/ppc-psi/tests/ra2018-psi/mock-data/psi.txt"; + std::string outputPath = _outputPrefix + "psiResult.txt"; + std::vector expectedResult; + for (int i = 1; i < 49; i++) + { + expectedResult.emplace_back(std::to_string(i)); + } + testEcdhImplFunc( + _dataBatchSize, serverDataPath, clientDataPath, outputPath, true, true, expectedResult, 0); +} + +BOOST_AUTO_TEST_CASE(testNormalEcdhPSICase) +{ + std::cout << "### testNormalEcdhPSICase, batch-size: " << 1000 << std::endl; + testNormalCase("normal-ecdh-psi-1000-batch-", 1000); + std::cout << "### testNormalEcdhPSICase, batch-size: " << 1000 << " success!" << std::endl; + + std::cout << "### testNormalEcdhPSICase, batch-size: " << 20 << std::endl; + testNormalCase("normal-ecdh-psi-20-batch-", 20); + std::cout << "### testNormalEcdhPSICase, batch-size: " << 20 << " success!" << std::endl; +} + +BOOST_AUTO_TEST_CASE(testECDHMissingResourceDataCase) +{ + std::string serverPSIDataPath = + "../../../../wedpr-computing/ppc-psi/tests/ra2018-psi/mock-data/fullevaluate-missing.txt"; + std::string clientPSIDataPath = + "../../../../wedpr-computing/ppc-psi/tests/ra2018-psi/mock-data/psi.txt"; + std::string outputPath = "psiResult_MissingResourceData.txt"; + std::vector expectedResult; + testEcdhImplFunc(1000, serverPSIDataPath, clientPSIDataPath, outputPath, true, false, + expectedResult, (int)PSIRetCode::HandleTaskError); +} +BOOST_AUTO_TEST_CASE(testECDHMisMatchTaskID) +{ + std::string serverPSIDataPath = + "../../../../wedpr-computing/ppc-psi/tests/ra2018-psi/mock-data/fullevaluate.txt"; + std::string clientPSIDataPath = + "../../../../wedpr-computing/ppc-psi/tests/ra2018-psi/mock-data/psi.txt"; + std::string outputPath = "psiResult_MismatchTaskID.txt"; + std::vector expectedResult; + testEcdhImplFunc(1000, serverPSIDataPath, clientPSIDataPath, outputPath, true, false, + expectedResult, (int)PSIRetCode::TaskNotFound, true); +} +BOOST_AUTO_TEST_SUITE_END() +} // namespace ppc::test \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-psi/tests/ra2018-psi/TestRA2018Impl.cpp b/cpp/wedpr-computing/ppc-psi/tests/ra2018-psi/TestRA2018Impl.cpp new file mode 100644 index 00000000..2e6c06fa --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/tests/ra2018-psi/TestRA2018Impl.cpp @@ -0,0 +1,268 @@ +/* + * Copyright (C) 2022 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 applicabl 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 TestRA2018Impl.cpp + * @author: yujiechen + * @date 2022-11-16 + */ +#include "mock/Common.h" +#include "mock/RA2018PSIFixture.h" +// Note: it's better not to depends on the task-impl +#include "ppc-io/src/FileLineReader.h" +#include "protocol/src/JsonTaskImpl.h" +#include "test-utils/TaskMock.h" +#include +#include + +using namespace ppc::psi; +using namespace bcos; +using namespace bcos::test; +using namespace ppc::crypto; +using namespace ppc::tools; +using namespace ppc::protocol; + +namespace ppc::test +{ +BOOST_FIXTURE_TEST_SUITE(RA2018ImplTest, TestPromptFixture) +// offline evaluate +void testRA2018FullEvaluate(FakeRA2018PSIFactory::Ptr _factory, RA2018PSIImpl::Ptr _server, + ppc::protocol::Task::ConstPtr _evaluateTask, bool _expectedSuccess) +{ + // test the server offline-evaluate + std::promise completedFuture; + _server->asyncRunTask(_evaluateTask, [_evaluateTask, _expectedSuccess, &completedFuture]( + ppc::protocol::TaskResult::Ptr&& _response) { + if (_expectedSuccess) + { + BOOST_CHECK(_response->error() == nullptr || _response->error()->errorCode() == 0); + BOOST_CHECK(_response->taskID() == _evaluateTask->id()); + auto result = _response->error(); + BOOST_CHECK(result == nullptr || result->errorCode() == 0); + } + else + { + BOOST_CHECK(_response->error() != nullptr); + auto result = _response->error(); + BOOST_CHECK(result != nullptr); + } + completedFuture.set_value(true); + }); + completedFuture.get_future().get(); +} + +void testRA2018PSIImplFunc(int _dataBatchSize, CuckoofilterOption::Ptr option, + std::string const& _offlineDataPath, std::string const& _psiDataSource, + std::string const& _resultDataPath, bool _expectOfflineSuccess, bool _expectPSISuccess, + std::vector& _expectedPSIResult, int _expectedErrorCode = 0, + bool _misMatchDataSource = false, std::string const& _offlineInsertDataPath = "", + std::vector const& _appendIntersectionData = std::vector()) +{ + auto factory = std::make_shared(); + // the server config, with default cache setting + auto serverConfig = std::make_shared(); + auto& mutableServerConfig = serverConfig->mutableRA2018PSIConfig(); + mutableServerConfig.dataBatchSize = _dataBatchSize; + + serverConfig->setPrivateKey(factory->cryptoBox()->eccCrypto()->generateRandomScalar()); + mutableServerConfig.cuckooFilterOption = option; + + // the client config, with default cache setting + auto clientConfig = std::make_shared(); + auto& mutableClientConfig = clientConfig->mutableRA2018PSIConfig(); + mutableClientConfig.cuckooFilterOption = option; + mutableClientConfig.dataBatchSize = _dataBatchSize; + + // fake the server + std::string serverAgencyName = "server"; + auto serverPSI = factory->createRA2018PSI(serverAgencyName, serverConfig); + + // fake the client + std::string clientAgencyName = "client"; + auto clientPSI = factory->createRA2018PSI(clientAgencyName, clientConfig); + // register the server-psi into the front + factory->front()->registerRA2018(serverAgencyName, serverPSI); + factory->front()->registerRA2018(clientAgencyName, clientPSI); + + // generate offline-evaluate task + std::string resourceID = "dataResource"; + std::string clientResourceID = resourceID; + std::string serverResourceID = resourceID; + auto serverParty = mockParty((uint16_t)PartyType::Server, serverAgencyName, "serverParty", + serverResourceID, DataResourceType::FILE, _offlineDataPath); + + auto offlineFullEvaluateTask = std::make_shared(serverAgencyName); + offlineFullEvaluateTask->setId("offlineFullEvaluate"); + offlineFullEvaluateTask->setSelf(serverParty); + offlineFullEvaluateTask->setEnableOutputExists(true); + // insert operation + std::string param = "[\"data_preprocessing\", 0]"; + offlineFullEvaluateTask->setParam(param); + // the server trigger offline-evaluate + testRA2018FullEvaluate(factory, serverPSI, offlineFullEvaluateTask, _expectOfflineSuccess); + + /// trigger the psi task + // the client task + if (_misMatchDataSource) + { + serverResourceID = "miss-match-" + resourceID; + } + // update the server-resource-id + serverParty->mutableDataResource()->setResourceID(serverResourceID); + auto clientParty = mockParty((uint16_t)PartyType::Client, clientAgencyName, "clientParty", + clientResourceID, DataResourceType::FILE, _psiDataSource); + auto outputDesc = std::make_shared(); + outputDesc->setPath(_resultDataPath); + clientParty->mutableDataResource()->setOutputDesc(outputDesc); + auto clientPSITask = std::make_shared(clientAgencyName); + std::string taskID = "runPSI"; + clientPSITask->setId(taskID); + clientPSITask->setEnableOutputExists(true); + clientPSITask->setSelf(clientParty); + clientPSITask->addParty(serverParty); + param = "[\"ra2018_psi\"]"; + clientPSITask->setParam(param); + + // the server task + auto serverPSITask = std::make_shared(serverAgencyName); + serverPSITask->setSelf(serverParty); + serverPSITask->setEnableOutputExists(true); + serverPSITask->setId(taskID); + serverPSITask->setParam(param); + serverPSITask->addParty(clientParty); + testPSI(factory, serverPSI, clientPSI, serverPSITask, clientPSITask, _expectPSISuccess, + _expectedPSIResult, _expectedErrorCode); + + // test insert new data into the cuckoo-filter + if (_offlineInsertDataPath.empty() || _appendIntersectionData.empty()) + { + return; + } + std::cout << "### test offline-fullevaluate-insert" << std::endl; + offlineFullEvaluateTask->selfParty()->mutableDataResource()->mutableDesc()->setPath( + _offlineInsertDataPath); + offlineFullEvaluateTask->setId("insert_" + _offlineDataPath); + // the server trigger offline-evaluate + testRA2018FullEvaluate(factory, serverPSI, offlineFullEvaluateTask, _expectOfflineSuccess); + std::cout << "### test offline-fullevaluate-insert finished" << std::endl; + + // trigger psi task again + std::cout << "### test psi-insert" << std::endl; + taskID = "insert_runPSI"; + serverPSITask->setId(taskID); + clientPSITask->setId(taskID); + auto expectedResult = _expectedPSIResult; + expectedResult.insert( + expectedResult.end(), _appendIntersectionData.begin(), _appendIntersectionData.end()); + testPSI(factory, serverPSI, clientPSI, serverPSITask, clientPSITask, _expectPSISuccess, + expectedResult, _expectedErrorCode); + std::cout << "### test psi-insert success" << std::endl; + + // delete the evaluated data + std::cout << "### test offline-fullevaluate-delete" << std::endl; + param = "[\"data_preprocessing\", 1]"; + offlineFullEvaluateTask->setId("delete-" + _offlineDataPath); + offlineFullEvaluateTask->setParam(param); + // the server trigger offline-evaluate + testRA2018FullEvaluate(factory, serverPSI, offlineFullEvaluateTask, _expectOfflineSuccess); + std::cout << "### test offline-fullevaluate-delete finished" << std::endl; + + // trigger psi after delete + std::cout << "### test psi-delete" << std::endl; + taskID = "delete_runPSI"; + serverPSITask->setId(taskID); + clientPSITask->setId(taskID); + testPSI(factory, serverPSI, clientPSI, serverPSITask, clientPSITask, _expectPSISuccess, + _expectedPSIResult, _expectedErrorCode); + std::cout << "### test psi-delete success" << std::endl; +} + +void testNormalCase(std::string const& _outputPrefix, CuckoofilterOption::Ptr option, + uint64_t _dataBatchSize = 10000) +{ + std::string dataPath = + "../../../../wedpr-computing/ppc-psi/tests/ra2018-psi/mock-data/fullevaluate.txt"; + std::string psiPath = "../../../../wedpr-computing/ppc-psi/tests/ra2018-psi/mock-data/psi.txt"; + std::string appendPath = + "../../../../wedpr-computing/ppc-psi/tests/ra2018-psi/mock-data/append-full-evaluate.txt"; + std::string outputPath = _outputPrefix + "psiResult.txt"; + std::vector expectedResult; + for (int i = 1; i < 49; i++) + { + expectedResult.emplace_back(std::to_string(i)); + } + testRA2018PSIImplFunc(_dataBatchSize, option, dataPath, psiPath, outputPath, true, true, + expectedResult, 0, false, appendPath, std::vector()); + + // with psi2.txt as input + psiPath = "../../../../wedpr-computing/ppc-psi/tests/ra2018-psi/mock-data/psi2.txt"; + expectedResult.clear(); + for (int i = 2000; i < 4000; i += 3) + { + expectedResult.emplace_back(std::to_string(i)); + } + outputPath = _outputPrefix + "psiResult2.txt"; + std::vector appendIntersectionData; + std::string prefix = "abcdefg"; + for (int i = 0; i < 4; i++) + { + appendIntersectionData.emplace_back(prefix + std::to_string(i)); + } + appendIntersectionData.emplace_back("abcdefg0"); + testRA2018PSIImplFunc(_dataBatchSize, option, dataPath, psiPath, outputPath, true, true, + expectedResult, 0, false, appendPath, appendIntersectionData); +} +// the cuckoo-filter not hitted in the server +BOOST_AUTO_TEST_CASE(testMisMatchResourceIDCase) +{ + auto option = std::make_shared(); + option->tagBits = 32; + option->maxKickOutCount = 10; + option->capacity = 200000; + std::string dataPath = + "../../../../wedpr-computing/ppc-psi/tests/ra2018-psi/mock-data/fullevaluate.txt"; + std::string psiPath = "../../../../wedpr-computing/ppc-psi/tests/ra2018-psi/mock-data/psi.txt"; + std::string outputPath = "psiResult_MismatchResource.txt"; + std::vector expectedResult; + testRA2018PSIImplFunc(10000, option, dataPath, psiPath, outputPath, true, false, expectedResult, + (int)PSIRetCode::NotOfflineFullEvaluated, true); +} + +BOOST_AUTO_TEST_CASE(testNormalRA2018PSICase) +{ + // singleCuckooFilter + auto option = std::make_shared(); + option->tagBits = 32; + option->maxKickOutCount = 10; + option->capacity = 200000; + testNormalCase("singleCuckooFilter-", option); + + // with data-batch-size = 100 + testNormalCase("singleCuckooFilter-100-dataBatch-", option, 100); +} + +// test normal case with multiple-cuckoo-filter +BOOST_AUTO_TEST_CASE(testNormalRA2018PSICaseWithMultipleCuckooFilter) +{ + auto option = std::make_shared(); + option->tagBits = 32; + option->maxKickOutCount = 100; + option->capacity = 2000; + testNormalCase("multipleCuckooFilter-", option); + + // with data-batch-size = 100 + testNormalCase("multipleCuckooFilter-100-dataBatch-", option, 100); +} +BOOST_AUTO_TEST_SUITE_END() +} // namespace ppc::test \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-psi/tests/ra2018-psi/TestRA2018Message.cpp b/cpp/wedpr-computing/ppc-psi/tests/ra2018-psi/TestRA2018Message.cpp new file mode 100644 index 00000000..074068a9 --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/tests/ra2018-psi/TestRA2018Message.cpp @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2022 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 applicabl 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 TestRA2018Message.cpp + * @author: yujiechen + * @date 2022-11-16 + */ +#include "mock/RA2018MessageFixture.h" +#include "ppc-crypto-core/src/hash/Sha256Hash.h" +#include "ppc-io/src/FileLineReader.h" +#include "ppc-psi/src/ra2018-psi/Common.h" +#include +#include + +using namespace ppc::psi; +using namespace bcos; +using namespace bcos::test; +using namespace ppc::crypto; +using namespace ppc::tools; + +namespace ppc::test +{ +BOOST_FIXTURE_TEST_SUITE(RA2018MessageTest, TestPromptFixture) + +BOOST_AUTO_TEST_CASE(testRA2018MessageImpl) +{ + auto msgFactory = std::make_shared(); + std::string partyID = "selfParty"; + std::string resourceID = "testResource"; + int32_t version = 1000123; + // fake the data + std::vector data; + for (int i = 0; i < 100; i++) + { + std::string item = std::to_string(i) + "werwlerklk"; + data.emplace_back(bcos::bytes(item.begin(), item.end())); + } + + // the evaluate message + std::cout << "#### test EvaluateRequest" << std::endl; + auto msg = msgFactory->createPSIMessage((uint32_t)RA2018PacketType::EvaluateRequest); + fakeAndCheckRA2018Message(msg, msgFactory, (uint32_t)RA2018PacketType::EvaluateRequest, partyID, + resourceID, version, data); + std::cout << "#### test EvaluateRequest finish" << std::endl; + // the EvaluateResponse message + std::cout << "#### test EvaluateResponse" << std::endl; + msg = msgFactory->createPSIMessage((uint32_t)RA2018PacketType::EvaluateResponse); + fakeAndCheckRA2018Message(msg, msgFactory, (uint32_t)RA2018PacketType::EvaluateResponse, + partyID, resourceID, version, data); + std::cout << "#### test EvaluateResponse finish" << std::endl; + + // fake the cuckooFilterInfo + std::vector cuckooFilters; + auto hashImpl = std::make_shared(); + auto option = std::make_shared(); + option->tagBits = 32; + option->maxKickOutCount = 10; + option->capacity = 20000; + + for (int i = 0; i < 10; i++) + { + auto filterInfo = fakeCuckooFilterInfo(i, hashImpl, option, 10000 + i); + cuckooFilters.emplace_back(filterInfo); + } + // check the CuckooFilterRequest + std::cout << "#### test CuckooFilterRequest" << std::endl; + msg = msgFactory->createRA2018FilterMessage((uint32_t)RA2018PacketType::CuckooFilterRequest); + fakeAndCheckRA2018FilterMessage(msg, msgFactory, + (uint32_t)RA2018PacketType::CuckooFilterRequest, partyID, resourceID, version, data, + cuckooFilters); + std::cout << "#### test CuckooFilterRequest finish" << std::endl; + + // check the CuckooFilterResponse + std::cout << "#### test CuckooFilterResponse" << std::endl; + msg = msgFactory->createRA2018FilterMessage((uint32_t)RA2018PacketType::CuckooFilterResponse); + fakeAndCheckRA2018FilterMessage(msg, msgFactory, + (uint32_t)RA2018PacketType::CuckooFilterResponse, partyID, resourceID, version, data, + cuckooFilters); + std::cout << "#### test CuckooFilterResponse finish" << std::endl; + + // check the CancelTaskNotification + std::cout << "#### test CancelTaskNotification" << std::endl; + msg = + msgFactory->createTaskNotificationMessage((uint32_t)PSIPacketType::CancelTaskNotification); + fakeAndCheckNotificationMessage(msg, msgFactory, + (uint32_t)PSIPacketType::CancelTaskNotification, partyID, resourceID, version, data, -10999, + "-1000999"); + std::cout << "#### test CancelTaskNotification finish" << std::endl; +} +BOOST_AUTO_TEST_SUITE_END() +} // namespace ppc::test \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-psi/tests/ra2018-psi/mock-data/append-full-evaluate.txt b/cpp/wedpr-computing/ppc-psi/tests/ra2018-psi/mock-data/append-full-evaluate.txt new file mode 100644 index 00000000..247d6104 --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/tests/ra2018-psi/mock-data/append-full-evaluate.txt @@ -0,0 +1,16 @@ +abcdefg0 +abcdefg1 +abcdefg2 +abcdefg3 +abcdefg3 +abcdefg3 +abcdefg3 +abcdefg4 +abcdefg4 +abcdefg4 +abcdefg4 +abcdefg5 +abcdefg5 +abcdefg5 +abcdefg5 +abcdefg0 diff --git a/cpp/wedpr-computing/ppc-psi/tests/ra2018-psi/mock-data/fullevaluate.txt b/cpp/wedpr-computing/ppc-psi/tests/ra2018-psi/mock-data/fullevaluate.txt new file mode 100644 index 00000000..5bcdcf0d --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/tests/ra2018-psi/mock-data/fullevaluate.txt @@ -0,0 +1,10002 @@ +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 + + +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +163 +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 +175 +176 +177 +178 +179 +180 +181 +182 +183 +184 +185 +186 +187 +188 +189 +190 +191 +192 +193 +194 +195 +196 +197 +198 +199 +200 +201 +202 +203 +204 +205 +206 +207 +208 +209 +210 +211 +212 +213 +214 +215 +216 +217 +218 +219 +220 +221 +222 +223 +224 +225 +226 +227 +228 +229 +230 +231 +232 +233 +234 +235 +236 +237 +238 +239 +240 +241 +242 +243 +244 +245 +246 +247 +248 +249 +250 +251 +252 +253 +254 +255 +256 +257 +258 +259 +260 +261 +262 +263 +264 +265 +266 +267 +268 +269 +270 +271 +272 +273 +274 +275 +276 +277 +278 +279 +280 +281 +282 +283 +284 +285 +286 +287 +288 +289 +290 +291 +292 +293 +294 +295 +296 +297 +298 +299 +300 +301 +302 +303 +304 +305 +306 +307 +308 +309 +310 +311 +312 +313 +314 +315 +316 +317 +318 +319 +320 +321 +322 +323 +324 +325 +326 +327 +328 +329 +330 +331 +332 +333 +334 +335 +336 +337 +338 +339 +340 +341 +342 +343 +344 +345 +346 +347 +348 +349 +350 +351 +352 +353 +354 +355 +356 +357 +358 +359 +360 +361 +362 +363 +364 +365 +366 +367 +368 +369 +370 +371 +372 +373 +374 +375 +376 +377 +378 +379 +380 +381 +382 +383 +384 +385 +386 +387 +388 +389 +390 +391 +392 +393 +394 +395 +396 +397 +398 +399 +400 +401 +402 +403 +404 +405 +406 +407 +408 +409 +410 +411 +412 +413 +414 +415 +416 +417 +418 +419 +420 +421 +422 +423 +424 +425 +426 +427 +428 +429 +430 +431 +432 +433 +434 +435 +436 +437 +438 +439 +440 +441 +442 +443 +444 +445 +446 +447 +448 +449 +450 +451 +452 +453 +454 +455 +456 +457 +458 +459 +460 +461 +462 +463 +464 +465 +466 +467 +468 +469 +470 +471 +472 +473 +474 +475 +476 +477 +478 +479 +480 +481 +482 +483 +484 +485 +486 +487 +488 +489 +490 +491 +492 +493 +494 +495 +496 +497 +498 +499 +500 +501 +502 +503 +504 +505 +506 +507 +508 +509 +510 +511 +512 +513 +514 +515 +516 +517 +518 +519 +520 +521 +522 +523 +524 +525 +526 +527 +528 +529 +530 +531 +532 +533 +534 +535 +536 +537 +538 +539 +540 +541 +542 +543 +544 +545 +546 +547 +548 +549 +550 +551 +552 +553 +554 +555 +556 +557 +558 +559 +560 +561 +562 +563 +564 +565 +566 +567 +568 +569 +570 +571 +572 +573 +574 +575 +576 +577 +578 +579 +580 +581 +582 +583 +584 +585 +586 +587 +588 +589 +590 +591 +592 +593 +594 +595 +596 +597 +598 +599 +600 +601 +602 +603 +604 +605 +606 +607 +608 +609 +610 +611 +612 +613 +614 +615 +616 +617 +618 +619 +620 +621 +622 +623 +624 +625 +626 +627 +628 +629 +630 +631 +632 +633 +634 +635 +636 +637 +638 +639 +640 +641 +642 +643 +644 +645 +646 +647 +648 +649 +650 +651 +652 +653 +654 +655 +656 +657 +658 +659 +660 +661 +662 +663 +664 +665 +666 +667 +668 +669 +670 +671 +672 +673 +674 +675 +676 +677 +678 +679 +680 +681 +682 +683 +684 +685 +686 +687 +688 +689 +690 +691 +692 +693 +694 +695 +696 +697 +698 +699 +700 +701 +702 +703 +704 +705 +706 +707 +708 +709 +710 +711 +712 +713 +714 +715 +716 +717 +718 +719 +720 +721 +722 +723 +724 +725 +726 +727 +728 +729 +730 +731 +732 +733 +734 +735 +736 +737 +738 +739 +740 +741 +742 +743 +744 +745 +746 +747 +748 +749 +750 +751 +752 +753 +754 +755 +756 +757 +758 +759 +760 +761 +762 +763 +764 +765 +766 +767 +768 +769 +770 +771 +772 +773 +774 +775 +776 +777 +778 +779 +780 +781 +782 +783 +784 +785 +786 +787 +788 +789 +790 +791 +792 +793 +794 +795 +796 +797 +798 +799 +800 +801 +802 +803 +804 +805 +806 +807 +808 +809 +810 +811 +812 +813 +814 +815 +816 +817 +818 +819 +820 +821 +822 +823 +824 +825 +826 +827 +828 +829 +830 +831 +832 +833 +834 +835 +836 +837 +838 +839 +840 +841 +842 +843 +844 +845 +846 +847 +848 +849 +850 +851 +852 +853 +854 +855 +856 +857 +858 +859 +860 +861 +862 +863 +864 +865 +866 +867 +868 +869 +870 +871 +872 +873 +874 +875 +876 +877 +878 +879 +880 +881 +882 +883 +884 +885 +886 +887 +888 +889 +890 +891 +892 +893 +894 +895 +896 +897 +898 +899 +900 +901 +902 +903 +904 +905 +906 +907 +908 +909 +910 +911 +912 +913 +914 +915 +916 +917 +918 +919 +920 +921 +922 +923 +924 +925 +926 +927 +928 +929 +930 +931 +932 +933 +934 +935 +936 +937 +938 +939 +940 +941 +942 +943 +944 +945 +946 +947 +948 +949 +950 +951 +952 +953 +954 +955 +956 +957 +958 +959 +960 +961 +962 +963 +964 +965 +966 +967 +968 +969 +970 +971 +972 +973 +974 +975 +976 +977 +978 +979 +980 +981 +982 +983 +984 +985 +986 +987 +988 +989 +990 +991 +992 +993 +994 +995 +996 +997 +998 +999 +1000 +1001 +1002 +1003 +1004 +1005 +1006 +1007 +1008 +1009 +1010 +1011 +1012 +1013 +1014 +1015 +1016 +1017 +1018 +1019 +1020 +1021 +1022 +1023 +1024 +1025 +1026 +1027 +1028 +1029 +1030 +1031 +1032 +1033 +1034 +1035 +1036 +1037 +1038 +1039 +1040 +1041 +1042 +1043 +1044 +1045 +1046 +1047 +1048 +1049 +1050 +1051 +1052 +1053 +1054 +1055 +1056 +1057 +1058 +1059 +1060 +1061 +1062 +1063 +1064 +1065 +1066 +1067 +1068 +1069 +1070 +1071 +1072 +1073 +1074 +1075 +1076 +1077 +1078 +1079 +1080 +1081 +1082 +1083 +1084 +1085 +1086 +1087 +1088 +1089 +1090 +1091 +1092 +1093 +1094 +1095 +1096 +1097 +1098 +1099 +1100 +1101 +1102 +1103 +1104 +1105 +1106 +1107 +1108 +1109 +1110 +1111 +1112 +1113 +1114 +1115 +1116 +1117 +1118 +1119 +1120 +1121 +1122 +1123 +1124 +1125 +1126 +1127 +1128 +1129 +1130 +1131 +1132 +1133 +1134 +1135 +1136 +1137 +1138 +1139 +1140 +1141 +1142 +1143 +1144 +1145 +1146 +1147 +1148 +1149 +1150 +1151 +1152 +1153 +1154 +1155 +1156 +1157 +1158 +1159 +1160 +1161 +1162 +1163 +1164 +1165 +1166 +1167 +1168 +1169 +1170 +1171 +1172 +1173 +1174 +1175 +1176 +1177 +1178 +1179 +1180 +1181 +1182 +1183 +1184 +1185 +1186 +1187 +1188 +1189 +1190 +1191 +1192 +1193 +1194 +1195 +1196 +1197 +1198 +1199 +1200 +1201 +1202 +1203 +1204 +1205 +1206 +1207 +1208 +1209 +1210 +1211 +1212 +1213 +1214 +1215 +1216 +1217 +1218 +1219 +1220 +1221 +1222 +1223 +1224 +1225 +1226 +1227 +1228 +1229 +1230 +1231 +1232 +1233 +1234 +1235 +1236 +1237 +1238 +1239 +1240 +1241 +1242 +1243 +1244 +1245 +1246 +1247 +1248 +1249 +1250 +1251 +1252 +1253 +1254 +1255 +1256 +1257 +1258 +1259 +1260 +1261 +1262 +1263 +1264 +1265 +1266 +1267 +1268 +1269 +1270 +1271 +1272 +1273 +1274 +1275 +1276 +1277 +1278 +1279 +1280 +1281 +1282 +1283 +1284 +1285 +1286 +1287 +1288 +1289 +1290 +1291 +1292 +1293 +1294 +1295 +1296 +1297 +1298 +1299 +1300 +1301 +1302 +1303 +1304 +1305 +1306 +1307 +1308 +1309 +1310 +1311 +1312 +1313 +1314 +1315 +1316 +1317 +1318 +1319 +1320 +1321 +1322 +1323 +1324 +1325 +1326 +1327 +1328 +1329 +1330 +1331 +1332 +1333 +1334 +1335 +1336 +1337 +1338 +1339 +1340 +1341 +1342 +1343 +1344 +1345 +1346 +1347 +1348 +1349 +1350 +1351 +1352 +1353 +1354 +1355 +1356 +1357 +1358 +1359 +1360 +1361 +1362 +1363 +1364 +1365 +1366 +1367 +1368 +1369 +1370 +1371 +1372 +1373 +1374 +1375 +1376 +1377 +1378 +1379 +1380 +1381 +1382 +1383 +1384 +1385 +1386 +1387 +1388 +1389 +1390 +1391 +1392 +1393 +1394 +1395 +1396 +1397 +1398 +1399 +1400 +1401 +1402 +1403 +1404 +1405 +1406 +1407 +1408 +1409 +1410 +1411 +1412 +1413 +1414 +1415 +1416 +1417 +1418 +1419 +1420 +1421 +1422 +1423 +1424 +1425 +1426 +1427 +1428 +1429 +1430 +1431 +1432 +1433 +1434 +1435 +1436 +1437 +1438 +1439 +1440 +1441 +1442 +1443 +1444 +1445 +1446 +1447 +1448 +1449 +1450 +1451 +1452 +1453 +1454 +1455 +1456 +1457 +1458 +1459 +1460 +1461 +1462 +1463 +1464 +1465 +1466 +1467 +1468 +1469 +1470 +1471 +1472 +1473 +1474 +1475 +1476 +1477 +1478 +1479 +1480 +1481 +1482 +1483 +1484 +1485 +1486 +1487 +1488 +1489 +1490 +1491 +1492 +1493 +1494 +1495 +1496 +1497 +1498 +1499 +1500 +1501 +1502 +1503 +1504 +1505 +1506 +1507 +1508 +1509 +1510 +1511 +1512 +1513 +1514 +1515 +1516 +1517 +1518 +1519 +1520 +1521 +1522 +1523 +1524 +1525 +1526 +1527 +1528 +1529 +1530 +1531 +1532 +1533 +1534 +1535 +1536 +1537 +1538 +1539 +1540 +1541 +1542 +1543 +1544 +1545 +1546 +1547 +1548 +1549 +1550 +1551 +1552 +1553 +1554 +1555 +1556 +1557 +1558 +1559 +1560 +1561 +1562 +1563 +1564 +1565 +1566 +1567 +1568 +1569 +1570 +1571 +1572 +1573 +1574 +1575 +1576 +1577 +1578 +1579 +1580 +1581 +1582 +1583 +1584 +1585 +1586 +1587 +1588 +1589 +1590 +1591 +1592 +1593 +1594 +1595 +1596 +1597 +1598 +1599 +1600 +1601 +1602 +1603 +1604 +1605 +1606 +1607 +1608 +1609 +1610 +1611 +1612 +1613 +1614 +1615 +1616 +1617 +1618 +1619 +1620 +1621 +1622 +1623 +1624 +1625 +1626 +1627 +1628 +1629 +1630 +1631 +1632 +1633 +1634 +1635 +1636 +1637 +1638 +1639 +1640 +1641 +1642 +1643 +1644 +1645 +1646 +1647 +1648 +1649 +1650 +1651 +1652 +1653 +1654 +1655 +1656 +1657 +1658 +1659 +1660 +1661 +1662 +1663 +1664 +1665 +1666 +1667 +1668 +1669 +1670 +1671 +1672 +1673 +1674 +1675 +1676 +1677 +1678 +1679 +1680 +1681 +1682 +1683 +1684 +1685 +1686 +1687 +1688 +1689 +1690 +1691 +1692 +1693 +1694 +1695 +1696 +1697 +1698 +1699 +1700 +1701 +1702 +1703 +1704 +1705 +1706 +1707 +1708 +1709 +1710 +1711 +1712 +1713 +1714 +1715 +1716 +1717 +1718 +1719 +1720 +1721 +1722 +1723 +1724 +1725 +1726 +1727 +1728 +1729 +1730 +1731 +1732 +1733 +1734 +1735 +1736 +1737 +1738 +1739 +1740 +1741 +1742 +1743 +1744 +1745 +1746 +1747 +1748 +1749 +1750 +1751 +1752 +1753 +1754 +1755 +1756 +1757 +1758 +1759 +1760 +1761 +1762 +1763 +1764 +1765 +1766 +1767 +1768 +1769 +1770 +1771 +1772 +1773 +1774 +1775 +1776 +1777 +1778 +1779 +1780 +1781 +1782 +1783 +1784 +1785 +1786 +1787 +1788 +1789 +1790 +1791 +1792 +1793 +1794 +1795 +1796 +1797 +1798 +1799 +1800 +1801 +1802 +1803 +1804 +1805 +1806 +1807 +1808 +1809 +1810 +1811 +1812 +1813 +1814 +1815 +1816 +1817 +1818 +1819 +1820 +1821 +1822 +1823 +1824 +1825 +1826 +1827 +1828 +1829 +1830 +1831 +1832 +1833 +1834 +1835 +1836 +1837 +1838 +1839 +1840 +1841 +1842 +1843 +1844 +1845 +1846 +1847 +1848 +1849 +1850 +1851 +1852 +1853 +1854 +1855 +1856 +1857 +1858 +1859 +1860 +1861 +1862 +1863 +1864 +1865 +1866 +1867 +1868 +1869 +1870 +1871 +1872 +1873 +1874 +1875 +1876 +1877 +1878 +1879 +1880 +1881 +1882 +1883 +1884 +1885 +1886 +1887 +1888 +1889 +1890 +1891 +1892 +1893 +1894 +1895 +1896 +1897 +1898 +1899 +1900 +1901 +1902 +1903 +1904 +1905 +1906 +1907 +1908 +1909 +1910 +1911 +1912 +1913 +1914 +1915 +1916 +1917 +1918 +1919 +1920 +1921 +1922 +1923 +1924 +1925 +1926 +1927 +1928 +1929 +1930 +1931 +1932 +1933 +1934 +1935 +1936 +1937 +1938 +1939 +1940 +1941 +1942 +1943 +1944 +1945 +1946 +1947 +1948 +1949 +1950 +1951 +1952 +1953 +1954 +1955 +1956 +1957 +1958 +1959 +1960 +1961 +1962 +1963 +1964 +1965 +1966 +1967 +1968 +1969 +1970 +1971 +1972 +1973 +1974 +1975 +1976 +1977 +1978 +1979 +1980 +1981 +1982 +1983 +1984 +1985 +1986 +1987 +1988 +1989 +1990 +1991 +1992 +1993 +1994 +1995 +1996 +1997 +1998 +1999 +2000 +2001 +2002 +2003 +2004 +2005 +2006 +2007 +2008 +2009 +2010 +2011 +2012 +2013 +2014 +2015 +2016 +2017 +2018 +2019 +2020 +2021 +2022 +2023 +2024 +2025 +2026 +2027 +2028 +2029 +2030 +2031 +2032 +2033 +2034 +2035 +2036 +2037 +2038 +2039 +2040 +2041 +2042 +2043 +2044 +2045 +2046 +2047 +2048 +2049 +2050 +2051 +2052 +2053 +2054 +2055 +2056 +2057 +2058 +2059 +2060 +2061 +2062 +2063 +2064 +2065 +2066 +2067 +2068 +2069 +2070 +2071 +2072 +2073 +2074 +2075 +2076 +2077 +2078 +2079 +2080 +2081 +2082 +2083 +2084 +2085 +2086 +2087 +2088 +2089 +2090 +2091 +2092 +2093 +2094 +2095 +2096 +2097 +2098 +2099 +2100 +2101 +2102 +2103 +2104 +2105 +2106 +2107 +2108 +2109 +2110 +2111 +2112 +2113 +2114 +2115 +2116 +2117 +2118 +2119 +2120 +2121 +2122 +2123 +2124 +2125 +2126 +2127 +2128 +2129 +2130 +2131 +2132 +2133 +2134 +2135 +2136 +2137 +2138 +2139 +2140 +2141 +2142 +2143 +2144 +2145 +2146 +2147 +2148 +2149 +2150 +2151 +2152 +2153 +2154 +2155 +2156 +2157 +2158 +2159 +2160 +2161 +2162 +2163 +2164 +2165 +2166 +2167 +2168 +2169 +2170 +2171 +2172 +2173 +2174 +2175 +2176 +2177 +2178 +2179 +2180 +2181 +2182 +2183 +2184 +2185 +2186 +2187 +2188 +2189 +2190 +2191 +2192 +2193 +2194 +2195 +2196 +2197 +2198 +2199 +2200 +2201 +2202 +2203 +2204 +2205 +2206 +2207 +2208 +2209 +2210 +2211 +2212 +2213 +2214 +2215 +2216 +2217 +2218 +2219 +2220 +2221 +2222 +2223 +2224 +2225 +2226 +2227 +2228 +2229 +2230 +2231 +2232 +2233 +2234 +2235 +2236 +2237 +2238 +2239 +2240 +2241 +2242 +2243 +2244 +2245 +2246 +2247 +2248 +2249 +2250 +2251 +2252 +2253 +2254 +2255 +2256 +2257 +2258 +2259 +2260 +2261 +2262 +2263 +2264 +2265 +2266 +2267 +2268 +2269 +2270 +2271 +2272 +2273 +2274 +2275 +2276 +2277 +2278 +2279 +2280 +2281 +2282 +2283 +2284 +2285 +2286 +2287 +2288 +2289 +2290 +2291 +2292 +2293 +2294 +2295 +2296 +2297 +2298 +2299 +2300 +2301 +2302 +2303 +2304 +2305 +2306 +2307 +2308 +2309 +2310 +2311 +2312 +2313 +2314 +2315 +2316 +2317 +2318 +2319 +2320 +2321 +2322 +2323 +2324 +2325 +2326 +2327 +2328 +2329 +2330 +2331 +2332 +2333 +2334 +2335 +2336 +2337 +2338 +2339 +2340 +2341 +2342 +2343 +2344 +2345 +2346 +2347 +2348 +2349 +2350 +2351 +2352 +2353 +2354 +2355 +2356 +2357 +2358 +2359 +2360 +2361 +2362 +2363 +2364 +2365 +2366 +2367 +2368 +2369 +2370 +2371 +2372 +2373 +2374 +2375 +2376 +2377 +2378 +2379 +2380 +2381 +2382 +2383 +2384 +2385 +2386 +2387 +2388 +2389 +2390 +2391 +2392 +2393 +2394 +2395 +2396 +2397 +2398 +2399 +2400 +2401 +2402 +2403 +2404 +2405 +2406 +2407 +2408 +2409 +2410 +2411 +2412 +2413 +2414 +2415 +2416 +2417 +2418 +2419 +2420 +2421 +2422 +2423 +2424 +2425 +2426 +2427 +2428 +2429 +2430 +2431 +2432 +2433 +2434 +2435 +2436 +2437 +2438 +2439 +2440 +2441 +2442 +2443 +2444 +2445 +2446 +2447 +2448 +2449 +2450 +2451 +2452 +2453 +2454 +2455 +2456 +2457 +2458 +2459 +2460 +2461 +2462 +2463 +2464 +2465 +2466 +2467 +2468 +2469 +2470 +2471 +2472 +2473 +2474 +2475 +2476 +2477 +2478 +2479 +2480 +2481 +2482 +2483 +2484 +2485 +2486 +2487 +2488 +2489 +2490 +2491 +2492 +2493 +2494 +2495 +2496 +2497 +2498 +2499 +2500 +2501 +2502 +2503 +2504 +2505 +2506 +2507 +2508 +2509 +2510 +2511 +2512 +2513 +2514 +2515 +2516 +2517 +2518 +2519 +2520 +2521 +2522 +2523 +2524 +2525 +2526 +2527 +2528 +2529 +2530 +2531 +2532 +2533 +2534 +2535 +2536 +2537 +2538 +2539 +2540 +2541 +2542 +2543 +2544 +2545 +2546 +2547 +2548 +2549 +2550 +2551 +2552 +2553 +2554 +2555 +2556 +2557 +2558 +2559 +2560 +2561 +2562 +2563 +2564 +2565 +2566 +2567 +2568 +2569 +2570 +2571 +2572 +2573 +2574 +2575 +2576 +2577 +2578 +2579 +2580 +2581 +2582 +2583 +2584 +2585 +2586 +2587 +2588 +2589 +2590 +2591 +2592 +2593 +2594 +2595 +2596 +2597 +2598 +2599 +2600 +2601 +2602 +2603 +2604 +2605 +2606 +2607 +2608 +2609 +2610 +2611 +2612 +2613 +2614 +2615 +2616 +2617 +2618 +2619 +2620 +2621 +2622 +2623 +2624 +2625 +2626 +2627 +2628 +2629 +2630 +2631 +2632 +2633 +2634 +2635 +2636 +2637 +2638 +2639 +2640 +2641 +2642 +2643 +2644 +2645 +2646 +2647 +2648 +2649 +2650 +2651 +2652 +2653 +2654 +2655 +2656 +2657 +2658 +2659 +2660 +2661 +2662 +2663 +2664 +2665 +2666 +2667 +2668 +2669 +2670 +2671 +2672 +2673 +2674 +2675 +2676 +2677 +2678 +2679 +2680 +2681 +2682 +2683 +2684 +2685 +2686 +2687 +2688 +2689 +2690 +2691 +2692 +2693 +2694 +2695 +2696 +2697 +2698 +2699 +2700 +2701 +2702 +2703 +2704 +2705 +2706 +2707 +2708 +2709 +2710 +2711 +2712 +2713 +2714 +2715 +2716 +2717 +2718 +2719 +2720 +2721 +2722 +2723 +2724 +2725 +2726 +2727 +2728 +2729 +2730 +2731 +2732 +2733 +2734 +2735 +2736 +2737 +2738 +2739 +2740 +2741 +2742 +2743 +2744 +2745 +2746 +2747 +2748 +2749 +2750 +2751 +2752 +2753 +2754 +2755 +2756 +2757 +2758 +2759 +2760 +2761 +2762 +2763 +2764 +2765 +2766 +2767 +2768 +2769 +2770 +2771 +2772 +2773 +2774 +2775 +2776 +2777 +2778 +2779 +2780 +2781 +2782 +2783 +2784 +2785 +2786 +2787 +2788 +2789 +2790 +2791 +2792 +2793 +2794 +2795 +2796 +2797 +2798 +2799 +2800 +2801 +2802 +2803 +2804 +2805 +2806 +2807 +2808 +2809 +2810 +2811 +2812 +2813 +2814 +2815 +2816 +2817 +2818 +2819 +2820 +2821 +2822 +2823 +2824 +2825 +2826 +2827 +2828 +2829 +2830 +2831 +2832 +2833 +2834 +2835 +2836 +2837 +2838 +2839 +2840 +2841 +2842 +2843 +2844 +2845 +2846 +2847 +2848 +2849 +2850 +2851 +2852 +2853 +2854 +2855 +2856 +2857 +2858 +2859 +2860 +2861 +2862 +2863 +2864 +2865 +2866 +2867 +2868 +2869 +2870 +2871 +2872 +2873 +2874 +2875 +2876 +2877 +2878 +2879 +2880 +2881 +2882 +2883 +2884 +2885 +2886 +2887 +2888 +2889 +2890 +2891 +2892 +2893 +2894 +2895 +2896 +2897 +2898 +2899 +2900 +2901 +2902 +2903 +2904 +2905 +2906 +2907 +2908 +2909 +2910 +2911 +2912 +2913 +2914 +2915 +2916 +2917 +2918 +2919 +2920 +2921 +2922 +2923 +2924 +2925 +2926 +2927 +2928 +2929 +2930 +2931 +2932 +2933 +2934 +2935 +2936 +2937 +2938 +2939 +2940 +2941 +2942 +2943 +2944 +2945 +2946 +2947 +2948 +2949 +2950 +2951 +2952 +2953 +2954 +2955 +2956 +2957 +2958 +2959 +2960 +2961 +2962 +2963 +2964 +2965 +2966 +2967 +2968 +2969 +2970 +2971 +2972 +2973 +2974 +2975 +2976 +2977 +2978 +2979 +2980 +2981 +2982 +2983 +2984 +2985 +2986 +2987 +2988 +2989 +2990 +2991 +2992 +2993 +2994 +2995 +2996 +2997 +2998 +2999 +3000 +3001 +3002 +3003 +3004 +3005 +3006 +3007 +3008 +3009 +3010 +3011 +3012 +3013 +3014 +3015 +3016 +3017 +3018 +3019 +3020 +3021 +3022 +3023 +3024 +3025 +3026 +3027 +3028 +3029 +3030 +3031 +3032 +3033 +3034 +3035 +3036 +3037 +3038 +3039 +3040 +3041 +3042 +3043 +3044 +3045 +3046 +3047 +3048 +3049 +3050 +3051 +3052 +3053 +3054 +3055 +3056 +3057 +3058 +3059 +3060 +3061 +3062 +3063 +3064 +3065 +3066 +3067 +3068 +3069 +3070 +3071 +3072 +3073 +3074 +3075 +3076 +3077 +3078 +3079 +3080 +3081 +3082 +3083 +3084 +3085 +3086 +3087 +3088 +3089 +3090 +3091 +3092 +3093 +3094 +3095 +3096 +3097 +3098 +3099 +3100 +3101 +3102 +3103 +3104 +3105 +3106 +3107 +3108 +3109 +3110 +3111 +3112 +3113 +3114 +3115 +3116 +3117 +3118 +3119 +3120 +3121 +3122 +3123 +3124 +3125 +3126 +3127 +3128 +3129 +3130 +3131 +3132 +3133 +3134 +3135 +3136 +3137 +3138 +3139 +3140 +3141 +3142 +3143 +3144 +3145 +3146 +3147 +3148 +3149 +3150 +3151 +3152 +3153 +3154 +3155 +3156 +3157 +3158 +3159 +3160 +3161 +3162 +3163 +3164 +3165 +3166 +3167 +3168 +3169 +3170 +3171 +3172 +3173 +3174 +3175 +3176 +3177 +3178 +3179 +3180 +3181 +3182 +3183 +3184 +3185 +3186 +3187 +3188 +3189 +3190 +3191 +3192 +3193 +3194 +3195 +3196 +3197 +3198 +3199 +3200 +3201 +3202 +3203 +3204 +3205 +3206 +3207 +3208 +3209 +3210 +3211 +3212 +3213 +3214 +3215 +3216 +3217 +3218 +3219 +3220 +3221 +3222 +3223 +3224 +3225 +3226 +3227 +3228 +3229 +3230 +3231 +3232 +3233 +3234 +3235 +3236 +3237 +3238 +3239 +3240 +3241 +3242 +3243 +3244 +3245 +3246 +3247 +3248 +3249 +3250 +3251 +3252 +3253 +3254 +3255 +3256 +3257 +3258 +3259 +3260 +3261 +3262 +3263 +3264 +3265 +3266 +3267 +3268 +3269 +3270 +3271 +3272 +3273 +3274 +3275 +3276 +3277 +3278 +3279 +3280 +3281 +3282 +3283 +3284 +3285 +3286 +3287 +3288 +3289 +3290 +3291 +3292 +3293 +3294 +3295 +3296 +3297 +3298 +3299 +3300 +3301 +3302 +3303 +3304 +3305 +3306 +3307 +3308 +3309 +3310 +3311 +3312 +3313 +3314 +3315 +3316 +3317 +3318 +3319 +3320 +3321 +3322 +3323 +3324 +3325 +3326 +3327 +3328 +3329 +3330 +3331 +3332 +3333 +3334 +3335 +3336 +3337 +3338 +3339 +3340 +3341 +3342 +3343 +3344 +3345 +3346 +3347 +3348 +3349 +3350 +3351 +3352 +3353 +3354 +3355 +3356 +3357 +3358 +3359 +3360 +3361 +3362 +3363 +3364 +3365 +3366 +3367 +3368 +3369 +3370 +3371 +3372 +3373 +3374 +3375 +3376 +3377 +3378 +3379 +3380 +3381 +3382 +3383 +3384 +3385 +3386 +3387 +3388 +3389 +3390 +3391 +3392 +3393 +3394 +3395 +3396 +3397 +3398 +3399 +3400 +3401 +3402 +3403 +3404 +3405 +3406 +3407 +3408 +3409 +3410 +3411 +3412 +3413 +3414 +3415 +3416 +3417 +3418 +3419 +3420 +3421 +3422 +3423 +3424 +3425 +3426 +3427 +3428 +3429 +3430 +3431 +3432 +3433 +3434 +3435 +3436 +3437 +3438 +3439 +3440 +3441 +3442 +3443 +3444 +3445 +3446 +3447 +3448 +3449 +3450 +3451 +3452 +3453 +3454 +3455 +3456 +3457 +3458 +3459 +3460 +3461 +3462 +3463 +3464 +3465 +3466 +3467 +3468 +3469 +3470 +3471 +3472 +3473 +3474 +3475 +3476 +3477 +3478 +3479 +3480 +3481 +3482 +3483 +3484 +3485 +3486 +3487 +3488 +3489 +3490 +3491 +3492 +3493 +3494 +3495 +3496 +3497 +3498 +3499 +3500 +3501 +3502 +3503 +3504 +3505 +3506 +3507 +3508 +3509 +3510 +3511 +3512 +3513 +3514 +3515 +3516 +3517 +3518 +3519 +3520 +3521 +3522 +3523 +3524 +3525 +3526 +3527 +3528 +3529 +3530 +3531 +3532 +3533 +3534 +3535 +3536 +3537 +3538 +3539 +3540 +3541 +3542 +3543 +3544 +3545 +3546 +3547 +3548 +3549 +3550 +3551 +3552 +3553 +3554 +3555 +3556 +3557 +3558 +3559 +3560 +3561 +3562 +3563 +3564 +3565 +3566 +3567 +3568 +3569 +3570 +3571 +3572 +3573 +3574 +3575 +3576 +3577 +3578 +3579 +3580 +3581 +3582 +3583 +3584 +3585 +3586 +3587 +3588 +3589 +3590 +3591 +3592 +3593 +3594 +3595 +3596 +3597 +3598 +3599 +3600 +3601 +3602 +3603 +3604 +3605 +3606 +3607 +3608 +3609 +3610 +3611 +3612 +3613 +3614 +3615 +3616 +3617 +3618 +3619 +3620 +3621 +3622 +3623 +3624 +3625 +3626 +3627 +3628 +3629 +3630 +3631 +3632 +3633 +3634 +3635 +3636 +3637 +3638 +3639 +3640 +3641 +3642 +3643 +3644 +3645 +3646 +3647 +3648 +3649 +3650 +3651 +3652 +3653 +3654 +3655 +3656 +3657 +3658 +3659 +3660 +3661 +3662 +3663 +3664 +3665 +3666 +3667 +3668 +3669 +3670 +3671 +3672 +3673 +3674 +3675 +3676 +3677 +3678 +3679 +3680 +3681 +3682 +3683 +3684 +3685 +3686 +3687 +3688 +3689 +3690 +3691 +3692 +3693 +3694 +3695 +3696 +3697 +3698 +3699 +3700 +3701 +3702 +3703 +3704 +3705 +3706 +3707 +3708 +3709 +3710 +3711 +3712 +3713 +3714 +3715 +3716 +3717 +3718 +3719 +3720 +3721 +3722 +3723 +3724 +3725 +3726 +3727 +3728 +3729 +3730 +3731 +3732 +3733 +3734 +3735 +3736 +3737 +3738 +3739 +3740 +3741 +3742 +3743 +3744 +3745 +3746 +3747 +3748 +3749 +3750 +3751 +3752 +3753 +3754 +3755 +3756 +3757 +3758 +3759 +3760 +3761 +3762 +3763 +3764 +3765 +3766 +3767 +3768 +3769 +3770 +3771 +3772 +3773 +3774 +3775 +3776 +3777 +3778 +3779 +3780 +3781 +3782 +3783 +3784 +3785 +3786 +3787 +3788 +3789 +3790 +3791 +3792 +3793 +3794 +3795 +3796 +3797 +3798 +3799 +3800 +3801 +3802 +3803 +3804 +3805 +3806 +3807 +3808 +3809 +3810 +3811 +3812 +3813 +3814 +3815 +3816 +3817 +3818 +3819 +3820 +3821 +3822 +3823 +3824 +3825 +3826 +3827 +3828 +3829 +3830 +3831 +3832 +3833 +3834 +3835 +3836 +3837 +3838 +3839 +3840 +3841 +3842 +3843 +3844 +3845 +3846 +3847 +3848 +3849 +3850 +3851 +3852 +3853 +3854 +3855 +3856 +3857 +3858 +3859 +3860 +3861 +3862 +3863 +3864 +3865 +3866 +3867 +3868 +3869 +3870 +3871 +3872 +3873 +3874 +3875 +3876 +3877 +3878 +3879 +3880 +3881 +3882 +3883 +3884 +3885 +3886 +3887 +3888 +3889 +3890 +3891 +3892 +3893 +3894 +3895 +3896 +3897 +3898 +3899 +3900 +3901 +3902 +3903 +3904 +3905 +3906 +3907 +3908 +3909 +3910 +3911 +3912 +3913 +3914 +3915 +3916 +3917 +3918 +3919 +3920 +3921 +3922 +3923 +3924 +3925 +3926 +3927 +3928 +3929 +3930 +3931 +3932 +3933 +3934 +3935 +3936 +3937 +3938 +3939 +3940 +3941 +3942 +3943 +3944 +3945 +3946 +3947 +3948 +3949 +3950 +3951 +3952 +3953 +3954 +3955 +3956 +3957 +3958 +3959 +3960 +3961 +3962 +3963 +3964 +3965 +3966 +3967 +3968 +3969 +3970 +3971 +3972 +3973 +3974 +3975 +3976 +3977 +3978 +3979 +3980 +3981 +3982 +3983 +3984 +3985 +3986 +3987 +3988 +3989 +3990 +3991 +3992 +3993 +3994 +3995 +3996 +3997 +3998 +3999 +4000 +4001 +4002 +4003 +4004 +4005 +4006 +4007 +4008 +4009 +4010 +4011 +4012 +4013 +4014 +4015 +4016 +4017 +4018 +4019 +4020 +4021 +4022 +4023 +4024 +4025 +4026 +4027 +4028 +4029 +4030 +4031 +4032 +4033 +4034 +4035 +4036 +4037 +4038 +4039 +4040 +4041 +4042 +4043 +4044 +4045 +4046 +4047 +4048 +4049 +4050 +4051 +4052 +4053 +4054 +4055 +4056 +4057 +4058 +4059 +4060 +4061 +4062 +4063 +4064 +4065 +4066 +4067 +4068 +4069 +4070 +4071 +4072 +4073 +4074 +4075 +4076 +4077 +4078 +4079 +4080 +4081 +4082 +4083 +4084 +4085 +4086 +4087 +4088 +4089 +4090 +4091 +4092 +4093 +4094 +4095 +4096 +4097 +4098 +4099 +4100 +4101 +4102 +4103 +4104 +4105 +4106 +4107 +4108 +4109 +4110 +4111 +4112 +4113 +4114 +4115 +4116 +4117 +4118 +4119 +4120 +4121 +4122 +4123 +4124 +4125 +4126 +4127 +4128 +4129 +4130 +4131 +4132 +4133 +4134 +4135 +4136 +4137 +4138 +4139 +4140 +4141 +4142 +4143 +4144 +4145 +4146 +4147 +4148 +4149 +4150 +4151 +4152 +4153 +4154 +4155 +4156 +4157 +4158 +4159 +4160 +4161 +4162 +4163 +4164 +4165 +4166 +4167 +4168 +4169 +4170 +4171 +4172 +4173 +4174 +4175 +4176 +4177 +4178 +4179 +4180 +4181 +4182 +4183 +4184 +4185 +4186 +4187 +4188 +4189 +4190 +4191 +4192 +4193 +4194 +4195 +4196 +4197 +4198 +4199 +4200 +4201 +4202 +4203 +4204 +4205 +4206 +4207 +4208 +4209 +4210 +4211 +4212 +4213 +4214 +4215 +4216 +4217 +4218 +4219 +4220 +4221 +4222 +4223 +4224 +4225 +4226 +4227 +4228 +4229 +4230 +4231 +4232 +4233 +4234 +4235 +4236 +4237 +4238 +4239 +4240 +4241 +4242 +4243 +4244 +4245 +4246 +4247 +4248 +4249 +4250 +4251 +4252 +4253 +4254 +4255 +4256 +4257 +4258 +4259 +4260 +4261 +4262 +4263 +4264 +4265 +4266 +4267 +4268 +4269 +4270 +4271 +4272 +4273 +4274 +4275 +4276 +4277 +4278 +4279 +4280 +4281 +4282 +4283 +4284 +4285 +4286 +4287 +4288 +4289 +4290 +4291 +4292 +4293 +4294 +4295 +4296 +4297 +4298 +4299 +4300 +4301 +4302 +4303 +4304 +4305 +4306 +4307 +4308 +4309 +4310 +4311 +4312 +4313 +4314 +4315 +4316 +4317 +4318 +4319 +4320 +4321 +4322 +4323 +4324 +4325 +4326 +4327 +4328 +4329 +4330 +4331 +4332 +4333 +4334 +4335 +4336 +4337 +4338 +4339 +4340 +4341 +4342 +4343 +4344 +4345 +4346 +4347 +4348 +4349 +4350 +4351 +4352 +4353 +4354 +4355 +4356 +4357 +4358 +4359 +4360 +4361 +4362 +4363 +4364 +4365 +4366 +4367 +4368 +4369 +4370 +4371 +4372 +4373 +4374 +4375 +4376 +4377 +4378 +4379 +4380 +4381 +4382 +4383 +4384 +4385 +4386 +4387 +4388 +4389 +4390 +4391 +4392 +4393 +4394 +4395 +4396 +4397 +4398 +4399 +4400 +4401 +4402 +4403 +4404 +4405 +4406 +4407 +4408 +4409 +4410 +4411 +4412 +4413 +4414 +4415 +4416 +4417 +4418 +4419 +4420 +4421 +4422 +4423 +4424 +4425 +4426 +4427 +4428 +4429 +4430 +4431 +4432 +4433 +4434 +4435 +4436 +4437 +4438 +4439 +4440 +4441 +4442 +4443 +4444 +4445 +4446 +4447 +4448 +4449 +4450 +4451 +4452 +4453 +4454 +4455 +4456 +4457 +4458 +4459 +4460 +4461 +4462 +4463 +4464 +4465 +4466 +4467 +4468 +4469 +4470 +4471 +4472 +4473 +4474 +4475 +4476 +4477 +4478 +4479 +4480 +4481 +4482 +4483 +4484 +4485 +4486 +4487 +4488 +4489 +4490 +4491 +4492 +4493 +4494 +4495 +4496 +4497 +4498 +4499 +4500 +4501 +4502 +4503 +4504 +4505 +4506 +4507 +4508 +4509 +4510 +4511 +4512 +4513 +4514 +4515 +4516 +4517 +4518 +4519 +4520 +4521 +4522 +4523 +4524 +4525 +4526 +4527 +4528 +4529 +4530 +4531 +4532 +4533 +4534 +4535 +4536 +4537 +4538 +4539 +4540 +4541 +4542 +4543 +4544 +4545 +4546 +4547 +4548 +4549 +4550 +4551 +4552 +4553 +4554 +4555 +4556 +4557 +4558 +4559 +4560 +4561 +4562 +4563 +4564 +4565 +4566 +4567 +4568 +4569 +4570 +4571 +4572 +4573 +4574 +4575 +4576 +4577 +4578 +4579 +4580 +4581 +4582 +4583 +4584 +4585 +4586 +4587 +4588 +4589 +4590 +4591 +4592 +4593 +4594 +4595 +4596 +4597 +4598 +4599 +4600 +4601 +4602 +4603 +4604 +4605 +4606 +4607 +4608 +4609 +4610 +4611 +4612 +4613 +4614 +4615 +4616 +4617 +4618 +4619 +4620 +4621 +4622 +4623 +4624 +4625 +4626 +4627 +4628 +4629 +4630 +4631 +4632 +4633 +4634 +4635 +4636 +4637 +4638 +4639 +4640 +4641 +4642 +4643 +4644 +4645 +4646 +4647 +4648 +4649 +4650 +4651 +4652 +4653 +4654 +4655 +4656 +4657 +4658 +4659 +4660 +4661 +4662 +4663 +4664 +4665 +4666 +4667 +4668 +4669 +4670 +4671 +4672 +4673 +4674 +4675 +4676 +4677 +4678 +4679 +4680 +4681 +4682 +4683 +4684 +4685 +4686 +4687 +4688 +4689 +4690 +4691 +4692 +4693 +4694 +4695 +4696 +4697 +4698 +4699 +4700 +4701 +4702 +4703 +4704 +4705 +4706 +4707 +4708 +4709 +4710 +4711 +4712 +4713 +4714 +4715 +4716 +4717 +4718 +4719 +4720 +4721 +4722 +4723 +4724 +4725 +4726 +4727 +4728 +4729 +4730 +4731 +4732 +4733 +4734 +4735 +4736 +4737 +4738 +4739 +4740 +4741 +4742 +4743 +4744 +4745 +4746 +4747 +4748 +4749 +4750 +4751 +4752 +4753 +4754 +4755 +4756 +4757 +4758 +4759 +4760 +4761 +4762 +4763 +4764 +4765 +4766 +4767 +4768 +4769 +4770 +4771 +4772 +4773 +4774 +4775 +4776 +4777 +4778 +4779 +4780 +4781 +4782 +4783 +4784 +4785 +4786 +4787 +4788 +4789 +4790 +4791 +4792 +4793 +4794 +4795 +4796 +4797 +4798 +4799 +4800 +4801 +4802 +4803 +4804 +4805 +4806 +4807 +4808 +4809 +4810 +4811 +4812 +4813 +4814 +4815 +4816 +4817 +4818 +4819 +4820 +4821 +4822 +4823 +4824 +4825 +4826 +4827 +4828 +4829 +4830 +4831 +4832 +4833 +4834 +4835 +4836 +4837 +4838 +4839 +4840 +4841 +4842 +4843 +4844 +4845 +4846 +4847 +4848 +4849 +4850 +4851 +4852 +4853 +4854 +4855 +4856 +4857 +4858 +4859 +4860 +4861 +4862 +4863 +4864 +4865 +4866 +4867 +4868 +4869 +4870 +4871 +4872 +4873 +4874 +4875 +4876 +4877 +4878 +4879 +4880 +4881 +4882 +4883 +4884 +4885 +4886 +4887 +4888 +4889 +4890 +4891 +4892 +4893 +4894 +4895 +4896 +4897 +4898 +4899 +4900 +4901 +4902 +4903 +4904 +4905 +4906 +4907 +4908 +4909 +4910 +4911 +4912 +4913 +4914 +4915 +4916 +4917 +4918 +4919 +4920 +4921 +4922 +4923 +4924 +4925 +4926 +4927 +4928 +4929 +4930 +4931 +4932 +4933 +4934 +4935 +4936 +4937 +4938 +4939 +4940 +4941 +4942 +4943 +4944 +4945 +4946 +4947 +4948 +4949 +4950 +4951 +4952 +4953 +4954 +4955 +4956 +4957 +4958 +4959 +4960 +4961 +4962 +4963 +4964 +4965 +4966 +4967 +4968 +4969 +4970 +4971 +4972 +4973 +4974 +4975 +4976 +4977 +4978 +4979 +4980 +4981 +4982 +4983 +4984 +4985 +4986 +4987 +4988 +4989 +4990 +4991 +4992 +4993 +4994 +4995 +4996 +4997 +4998 +4999 +5000 +5001 +5002 +5003 +5004 +5005 +5006 +5007 +5008 +5009 +5010 +5011 +5012 +5013 +5014 +5015 +5016 +5017 +5018 +5019 +5020 +5021 +5022 +5023 +5024 +5025 +5026 +5027 +5028 +5029 +5030 +5031 +5032 +5033 +5034 +5035 +5036 +5037 +5038 +5039 +5040 +5041 +5042 +5043 +5044 +5045 +5046 +5047 +5048 +5049 +5050 +5051 +5052 +5053 +5054 +5055 +5056 +5057 +5058 +5059 +5060 +5061 +5062 +5063 +5064 +5065 +5066 +5067 +5068 +5069 +5070 +5071 +5072 +5073 +5074 +5075 +5076 +5077 +5078 +5079 +5080 +5081 +5082 +5083 +5084 +5085 +5086 +5087 +5088 +5089 +5090 +5091 +5092 +5093 +5094 +5095 +5096 +5097 +5098 +5099 +5100 +5101 +5102 +5103 +5104 +5105 +5106 +5107 +5108 +5109 +5110 +5111 +5112 +5113 +5114 +5115 +5116 +5117 +5118 +5119 +5120 +5121 +5122 +5123 +5124 +5125 +5126 +5127 +5128 +5129 +5130 +5131 +5132 +5133 +5134 +5135 +5136 +5137 +5138 +5139 +5140 +5141 +5142 +5143 +5144 +5145 +5146 +5147 +5148 +5149 +5150 +5151 +5152 +5153 +5154 +5155 +5156 +5157 +5158 +5159 +5160 +5161 +5162 +5163 +5164 +5165 +5166 +5167 +5168 +5169 +5170 +5171 +5172 +5173 +5174 +5175 +5176 +5177 +5178 +5179 +5180 +5181 +5182 +5183 +5184 +5185 +5186 +5187 +5188 +5189 +5190 +5191 +5192 +5193 +5194 +5195 +5196 +5197 +5198 +5199 +5200 +5201 +5202 +5203 +5204 +5205 +5206 +5207 +5208 +5209 +5210 +5211 +5212 +5213 +5214 +5215 +5216 +5217 +5218 +5219 +5220 +5221 +5222 +5223 +5224 +5225 +5226 +5227 +5228 +5229 +5230 +5231 +5232 +5233 +5234 +5235 +5236 +5237 +5238 +5239 +5240 +5241 +5242 +5243 +5244 +5245 +5246 +5247 +5248 +5249 +5250 +5251 +5252 +5253 +5254 +5255 +5256 +5257 +5258 +5259 +5260 +5261 +5262 +5263 +5264 +5265 +5266 +5267 +5268 +5269 +5270 +5271 +5272 +5273 +5274 +5275 +5276 +5277 +5278 +5279 +5280 +5281 +5282 +5283 +5284 +5285 +5286 +5287 +5288 +5289 +5290 +5291 +5292 +5293 +5294 +5295 +5296 +5297 +5298 +5299 +5300 +5301 +5302 +5303 +5304 +5305 +5306 +5307 +5308 +5309 +5310 +5311 +5312 +5313 +5314 +5315 +5316 +5317 +5318 +5319 +5320 +5321 +5322 +5323 +5324 +5325 +5326 +5327 +5328 +5329 +5330 +5331 +5332 +5333 +5334 +5335 +5336 +5337 +5338 +5339 +5340 +5341 +5342 +5343 +5344 +5345 +5346 +5347 +5348 +5349 +5350 +5351 +5352 +5353 +5354 +5355 +5356 +5357 +5358 +5359 +5360 +5361 +5362 +5363 +5364 +5365 +5366 +5367 +5368 +5369 +5370 +5371 +5372 +5373 +5374 +5375 +5376 +5377 +5378 +5379 +5380 +5381 +5382 +5383 +5384 +5385 +5386 +5387 +5388 +5389 +5390 +5391 +5392 +5393 +5394 +5395 +5396 +5397 +5398 +5399 +5400 +5401 +5402 +5403 +5404 +5405 +5406 +5407 +5408 +5409 +5410 +5411 +5412 +5413 +5414 +5415 +5416 +5417 +5418 +5419 +5420 +5421 +5422 +5423 +5424 +5425 +5426 +5427 +5428 +5429 +5430 +5431 +5432 +5433 +5434 +5435 +5436 +5437 +5438 +5439 +5440 +5441 +5442 +5443 +5444 +5445 +5446 +5447 +5448 +5449 +5450 +5451 +5452 +5453 +5454 +5455 +5456 +5457 +5458 +5459 +5460 +5461 +5462 +5463 +5464 +5465 +5466 +5467 +5468 +5469 +5470 +5471 +5472 +5473 +5474 +5475 +5476 +5477 +5478 +5479 +5480 +5481 +5482 +5483 +5484 +5485 +5486 +5487 +5488 +5489 +5490 +5491 +5492 +5493 +5494 +5495 +5496 +5497 +5498 +5499 +5500 +5501 +5502 +5503 +5504 +5505 +5506 +5507 +5508 +5509 +5510 +5511 +5512 +5513 +5514 +5515 +5516 +5517 +5518 +5519 +5520 +5521 +5522 +5523 +5524 +5525 +5526 +5527 +5528 +5529 +5530 +5531 +5532 +5533 +5534 +5535 +5536 +5537 +5538 +5539 +5540 +5541 +5542 +5543 +5544 +5545 +5546 +5547 +5548 +5549 +5550 +5551 +5552 +5553 +5554 +5555 +5556 +5557 +5558 +5559 +5560 +5561 +5562 +5563 +5564 +5565 +5566 +5567 +5568 +5569 +5570 +5571 +5572 +5573 +5574 +5575 +5576 +5577 +5578 +5579 +5580 +5581 +5582 +5583 +5584 +5585 +5586 +5587 +5588 +5589 +5590 +5591 +5592 +5593 +5594 +5595 +5596 +5597 +5598 +5599 +5600 +5601 +5602 +5603 +5604 +5605 +5606 +5607 +5608 +5609 +5610 +5611 +5612 +5613 +5614 +5615 +5616 +5617 +5618 +5619 +5620 +5621 +5622 +5623 +5624 +5625 +5626 +5627 +5628 +5629 +5630 +5631 +5632 +5633 +5634 +5635 +5636 +5637 +5638 +5639 +5640 +5641 +5642 +5643 +5644 +5645 +5646 +5647 +5648 +5649 +5650 +5651 +5652 +5653 +5654 +5655 +5656 +5657 +5658 +5659 +5660 +5661 +5662 +5663 +5664 +5665 +5666 +5667 +5668 +5669 +5670 +5671 +5672 +5673 +5674 +5675 +5676 +5677 +5678 +5679 +5680 +5681 +5682 +5683 +5684 +5685 +5686 +5687 +5688 +5689 +5690 +5691 +5692 +5693 +5694 +5695 +5696 +5697 +5698 +5699 +5700 +5701 +5702 +5703 +5704 +5705 +5706 +5707 +5708 +5709 +5710 +5711 +5712 +5713 +5714 +5715 +5716 +5717 +5718 +5719 +5720 +5721 +5722 +5723 +5724 +5725 +5726 +5727 +5728 +5729 +5730 +5731 +5732 +5733 +5734 +5735 +5736 +5737 +5738 +5739 +5740 +5741 +5742 +5743 +5744 +5745 +5746 +5747 +5748 +5749 +5750 +5751 +5752 +5753 +5754 +5755 +5756 +5757 +5758 +5759 +5760 +5761 +5762 +5763 +5764 +5765 +5766 +5767 +5768 +5769 +5770 +5771 +5772 +5773 +5774 +5775 +5776 +5777 +5778 +5779 +5780 +5781 +5782 +5783 +5784 +5785 +5786 +5787 +5788 +5789 +5790 +5791 +5792 +5793 +5794 +5795 +5796 +5797 +5798 +5799 +5800 +5801 +5802 +5803 +5804 +5805 +5806 +5807 +5808 +5809 +5810 +5811 +5812 +5813 +5814 +5815 +5816 +5817 +5818 +5819 +5820 +5821 +5822 +5823 +5824 +5825 +5826 +5827 +5828 +5829 +5830 +5831 +5832 +5833 +5834 +5835 +5836 +5837 +5838 +5839 +5840 +5841 +5842 +5843 +5844 +5845 +5846 +5847 +5848 +5849 +5850 +5851 +5852 +5853 +5854 +5855 +5856 +5857 +5858 +5859 +5860 +5861 +5862 +5863 +5864 +5865 +5866 +5867 +5868 +5869 +5870 +5871 +5872 +5873 +5874 +5875 +5876 +5877 +5878 +5879 +5880 +5881 +5882 +5883 +5884 +5885 +5886 +5887 +5888 +5889 +5890 +5891 +5892 +5893 +5894 +5895 +5896 +5897 +5898 +5899 +5900 +5901 +5902 +5903 +5904 +5905 +5906 +5907 +5908 +5909 +5910 +5911 +5912 +5913 +5914 +5915 +5916 +5917 +5918 +5919 +5920 +5921 +5922 +5923 +5924 +5925 +5926 +5927 +5928 +5929 +5930 +5931 +5932 +5933 +5934 +5935 +5936 +5937 +5938 +5939 +5940 +5941 +5942 +5943 +5944 +5945 +5946 +5947 +5948 +5949 +5950 +5951 +5952 +5953 +5954 +5955 +5956 +5957 +5958 +5959 +5960 +5961 +5962 +5963 +5964 +5965 +5966 +5967 +5968 +5969 +5970 +5971 +5972 +5973 +5974 +5975 +5976 +5977 +5978 +5979 +5980 +5981 +5982 +5983 +5984 +5985 +5986 +5987 +5988 +5989 +5990 +5991 +5992 +5993 +5994 +5995 +5996 +5997 +5998 +5999 +6000 +6001 +6002 +6003 +6004 +6005 +6006 +6007 +6008 +6009 +6010 +6011 +6012 +6013 +6014 +6015 +6016 +6017 +6018 +6019 +6020 +6021 +6022 +6023 +6024 +6025 +6026 +6027 +6028 +6029 +6030 +6031 +6032 +6033 +6034 +6035 +6036 +6037 +6038 +6039 +6040 +6041 +6042 +6043 +6044 +6045 +6046 +6047 +6048 +6049 +6050 +6051 +6052 +6053 +6054 +6055 +6056 +6057 +6058 +6059 +6060 +6061 +6062 +6063 +6064 +6065 +6066 +6067 +6068 +6069 +6070 +6071 +6072 +6073 +6074 +6075 +6076 +6077 +6078 +6079 +6080 +6081 +6082 +6083 +6084 +6085 +6086 +6087 +6088 +6089 +6090 +6091 +6092 +6093 +6094 +6095 +6096 +6097 +6098 +6099 +6100 +6101 +6102 +6103 +6104 +6105 +6106 +6107 +6108 +6109 +6110 +6111 +6112 +6113 +6114 +6115 +6116 +6117 +6118 +6119 +6120 +6121 +6122 +6123 +6124 +6125 +6126 +6127 +6128 +6129 +6130 +6131 +6132 +6133 +6134 +6135 +6136 +6137 +6138 +6139 +6140 +6141 +6142 +6143 +6144 +6145 +6146 +6147 +6148 +6149 +6150 +6151 +6152 +6153 +6154 +6155 +6156 +6157 +6158 +6159 +6160 +6161 +6162 +6163 +6164 +6165 +6166 +6167 +6168 +6169 +6170 +6171 +6172 +6173 +6174 +6175 +6176 +6177 +6178 +6179 +6180 +6181 +6182 +6183 +6184 +6185 +6186 +6187 +6188 +6189 +6190 +6191 +6192 +6193 +6194 +6195 +6196 +6197 +6198 +6199 +6200 +6201 +6202 +6203 +6204 +6205 +6206 +6207 +6208 +6209 +6210 +6211 +6212 +6213 +6214 +6215 +6216 +6217 +6218 +6219 +6220 +6221 +6222 +6223 +6224 +6225 +6226 +6227 +6228 +6229 +6230 +6231 +6232 +6233 +6234 +6235 +6236 +6237 +6238 +6239 +6240 +6241 +6242 +6243 +6244 +6245 +6246 +6247 +6248 +6249 +6250 +6251 +6252 +6253 +6254 +6255 +6256 +6257 +6258 +6259 +6260 +6261 +6262 +6263 +6264 +6265 +6266 +6267 +6268 +6269 +6270 +6271 +6272 +6273 +6274 +6275 +6276 +6277 +6278 +6279 +6280 +6281 +6282 +6283 +6284 +6285 +6286 +6287 +6288 +6289 +6290 +6291 +6292 +6293 +6294 +6295 +6296 +6297 +6298 +6299 +6300 +6301 +6302 +6303 +6304 +6305 +6306 +6307 +6308 +6309 +6310 +6311 +6312 +6313 +6314 +6315 +6316 +6317 +6318 +6319 +6320 +6321 +6322 +6323 +6324 +6325 +6326 +6327 +6328 +6329 +6330 +6331 +6332 +6333 +6334 +6335 +6336 +6337 +6338 +6339 +6340 +6341 +6342 +6343 +6344 +6345 +6346 +6347 +6348 +6349 +6350 +6351 +6352 +6353 +6354 +6355 +6356 +6357 +6358 +6359 +6360 +6361 +6362 +6363 +6364 +6365 +6366 +6367 +6368 +6369 +6370 +6371 +6372 +6373 +6374 +6375 +6376 +6377 +6378 +6379 +6380 +6381 +6382 +6383 +6384 +6385 +6386 +6387 +6388 +6389 +6390 +6391 +6392 +6393 +6394 +6395 +6396 +6397 +6398 +6399 +6400 +6401 +6402 +6403 +6404 +6405 +6406 +6407 +6408 +6409 +6410 +6411 +6412 +6413 +6414 +6415 +6416 +6417 +6418 +6419 +6420 +6421 +6422 +6423 +6424 +6425 +6426 +6427 +6428 +6429 +6430 +6431 +6432 +6433 +6434 +6435 +6436 +6437 +6438 +6439 +6440 +6441 +6442 +6443 +6444 +6445 +6446 +6447 +6448 +6449 +6450 +6451 +6452 +6453 +6454 +6455 +6456 +6457 +6458 +6459 +6460 +6461 +6462 +6463 +6464 +6465 +6466 +6467 +6468 +6469 +6470 +6471 +6472 +6473 +6474 +6475 +6476 +6477 +6478 +6479 +6480 +6481 +6482 +6483 +6484 +6485 +6486 +6487 +6488 +6489 +6490 +6491 +6492 +6493 +6494 +6495 +6496 +6497 +6498 +6499 +6500 +6501 +6502 +6503 +6504 +6505 +6506 +6507 +6508 +6509 +6510 +6511 +6512 +6513 +6514 +6515 +6516 +6517 +6518 +6519 +6520 +6521 +6522 +6523 +6524 +6525 +6526 +6527 +6528 +6529 +6530 +6531 +6532 +6533 +6534 +6535 +6536 +6537 +6538 +6539 +6540 +6541 +6542 +6543 +6544 +6545 +6546 +6547 +6548 +6549 +6550 +6551 +6552 +6553 +6554 +6555 +6556 +6557 +6558 +6559 +6560 +6561 +6562 +6563 +6564 +6565 +6566 +6567 +6568 +6569 +6570 +6571 +6572 +6573 +6574 +6575 +6576 +6577 +6578 +6579 +6580 +6581 +6582 +6583 +6584 +6585 +6586 +6587 +6588 +6589 +6590 +6591 +6592 +6593 +6594 +6595 +6596 +6597 +6598 +6599 +6600 +6601 +6602 +6603 +6604 +6605 +6606 +6607 +6608 +6609 +6610 +6611 +6612 +6613 +6614 +6615 +6616 +6617 +6618 +6619 +6620 +6621 +6622 +6623 +6624 +6625 +6626 +6627 +6628 +6629 +6630 +6631 +6632 +6633 +6634 +6635 +6636 +6637 +6638 +6639 +6640 +6641 +6642 +6643 +6644 +6645 +6646 +6647 +6648 +6649 +6650 +6651 +6652 +6653 +6654 +6655 +6656 +6657 +6658 +6659 +6660 +6661 +6662 +6663 +6664 +6665 +6666 +6667 +6668 +6669 +6670 +6671 +6672 +6673 +6674 +6675 +6676 +6677 +6678 +6679 +6680 +6681 +6682 +6683 +6684 +6685 +6686 +6687 +6688 +6689 +6690 +6691 +6692 +6693 +6694 +6695 +6696 +6697 +6698 +6699 +6700 +6701 +6702 +6703 +6704 +6705 +6706 +6707 +6708 +6709 +6710 +6711 +6712 +6713 +6714 +6715 +6716 +6717 +6718 +6719 +6720 +6721 +6722 +6723 +6724 +6725 +6726 +6727 +6728 +6729 +6730 +6731 +6732 +6733 +6734 +6735 +6736 +6737 +6738 +6739 +6740 +6741 +6742 +6743 +6744 +6745 +6746 +6747 +6748 +6749 +6750 +6751 +6752 +6753 +6754 +6755 +6756 +6757 +6758 +6759 +6760 +6761 +6762 +6763 +6764 +6765 +6766 +6767 +6768 +6769 +6770 +6771 +6772 +6773 +6774 +6775 +6776 +6777 +6778 +6779 +6780 +6781 +6782 +6783 +6784 +6785 +6786 +6787 +6788 +6789 +6790 +6791 +6792 +6793 +6794 +6795 +6796 +6797 +6798 +6799 +6800 +6801 +6802 +6803 +6804 +6805 +6806 +6807 +6808 +6809 +6810 +6811 +6812 +6813 +6814 +6815 +6816 +6817 +6818 +6819 +6820 +6821 +6822 +6823 +6824 +6825 +6826 +6827 +6828 +6829 +6830 +6831 +6832 +6833 +6834 +6835 +6836 +6837 +6838 +6839 +6840 +6841 +6842 +6843 +6844 +6845 +6846 +6847 +6848 +6849 +6850 +6851 +6852 +6853 +6854 +6855 +6856 +6857 +6858 +6859 +6860 +6861 +6862 +6863 +6864 +6865 +6866 +6867 +6868 +6869 +6870 +6871 +6872 +6873 +6874 +6875 +6876 +6877 +6878 +6879 +6880 +6881 +6882 +6883 +6884 +6885 +6886 +6887 +6888 +6889 +6890 +6891 +6892 +6893 +6894 +6895 +6896 +6897 +6898 +6899 +6900 +6901 +6902 +6903 +6904 +6905 +6906 +6907 +6908 +6909 +6910 +6911 +6912 +6913 +6914 +6915 +6916 +6917 +6918 +6919 +6920 +6921 +6922 +6923 +6924 +6925 +6926 +6927 +6928 +6929 +6930 +6931 +6932 +6933 +6934 +6935 +6936 +6937 +6938 +6939 +6940 +6941 +6942 +6943 +6944 +6945 +6946 +6947 +6948 +6949 +6950 +6951 +6952 +6953 +6954 +6955 +6956 +6957 +6958 +6959 +6960 +6961 +6962 +6963 +6964 +6965 +6966 +6967 +6968 +6969 +6970 +6971 +6972 +6973 +6974 +6975 +6976 +6977 +6978 +6979 +6980 +6981 +6982 +6983 +6984 +6985 +6986 +6987 +6988 +6989 +6990 +6991 +6992 +6993 +6994 +6995 +6996 +6997 +6998 +6999 +7000 +7001 +7002 +7003 +7004 +7005 +7006 +7007 +7008 +7009 +7010 +7011 +7012 +7013 +7014 +7015 +7016 +7017 +7018 +7019 +7020 +7021 +7022 +7023 +7024 +7025 +7026 +7027 +7028 +7029 +7030 +7031 +7032 +7033 +7034 +7035 +7036 +7037 +7038 +7039 +7040 +7041 +7042 +7043 +7044 +7045 +7046 +7047 +7048 +7049 +7050 +7051 +7052 +7053 +7054 +7055 +7056 +7057 +7058 +7059 +7060 +7061 +7062 +7063 +7064 +7065 +7066 +7067 +7068 +7069 +7070 +7071 +7072 +7073 +7074 +7075 +7076 +7077 +7078 +7079 +7080 +7081 +7082 +7083 +7084 +7085 +7086 +7087 +7088 +7089 +7090 +7091 +7092 +7093 +7094 +7095 +7096 +7097 +7098 +7099 +7100 +7101 +7102 +7103 +7104 +7105 +7106 +7107 +7108 +7109 +7110 +7111 +7112 +7113 +7114 +7115 +7116 +7117 +7118 +7119 +7120 +7121 +7122 +7123 +7124 +7125 +7126 +7127 +7128 +7129 +7130 +7131 +7132 +7133 +7134 +7135 +7136 +7137 +7138 +7139 +7140 +7141 +7142 +7143 +7144 +7145 +7146 +7147 +7148 +7149 +7150 +7151 +7152 +7153 +7154 +7155 +7156 +7157 +7158 +7159 +7160 +7161 +7162 +7163 +7164 +7165 +7166 +7167 +7168 +7169 +7170 +7171 +7172 +7173 +7174 +7175 +7176 +7177 +7178 +7179 +7180 +7181 +7182 +7183 +7184 +7185 +7186 +7187 +7188 +7189 +7190 +7191 +7192 +7193 +7194 +7195 +7196 +7197 +7198 +7199 +7200 +7201 +7202 +7203 +7204 +7205 +7206 +7207 +7208 +7209 +7210 +7211 +7212 +7213 +7214 +7215 +7216 +7217 +7218 +7219 +7220 +7221 +7222 +7223 +7224 +7225 +7226 +7227 +7228 +7229 +7230 +7231 +7232 +7233 +7234 +7235 +7236 +7237 +7238 +7239 +7240 +7241 +7242 +7243 +7244 +7245 +7246 +7247 +7248 +7249 +7250 +7251 +7252 +7253 +7254 +7255 +7256 +7257 +7258 +7259 +7260 +7261 +7262 +7263 +7264 +7265 +7266 +7267 +7268 +7269 +7270 +7271 +7272 +7273 +7274 +7275 +7276 +7277 +7278 +7279 +7280 +7281 +7282 +7283 +7284 +7285 +7286 +7287 +7288 +7289 +7290 +7291 +7292 +7293 +7294 +7295 +7296 +7297 +7298 +7299 +7300 +7301 +7302 +7303 +7304 +7305 +7306 +7307 +7308 +7309 +7310 +7311 +7312 +7313 +7314 +7315 +7316 +7317 +7318 +7319 +7320 +7321 +7322 +7323 +7324 +7325 +7326 +7327 +7328 +7329 +7330 +7331 +7332 +7333 +7334 +7335 +7336 +7337 +7338 +7339 +7340 +7341 +7342 +7343 +7344 +7345 +7346 +7347 +7348 +7349 +7350 +7351 +7352 +7353 +7354 +7355 +7356 +7357 +7358 +7359 +7360 +7361 +7362 +7363 +7364 +7365 +7366 +7367 +7368 +7369 +7370 +7371 +7372 +7373 +7374 +7375 +7376 +7377 +7378 +7379 +7380 +7381 +7382 +7383 +7384 +7385 +7386 +7387 +7388 +7389 +7390 +7391 +7392 +7393 +7394 +7395 +7396 +7397 +7398 +7399 +7400 +7401 +7402 +7403 +7404 +7405 +7406 +7407 +7408 +7409 +7410 +7411 +7412 +7413 +7414 +7415 +7416 +7417 +7418 +7419 +7420 +7421 +7422 +7423 +7424 +7425 +7426 +7427 +7428 +7429 +7430 +7431 +7432 +7433 +7434 +7435 +7436 +7437 +7438 +7439 +7440 +7441 +7442 +7443 +7444 +7445 +7446 +7447 +7448 +7449 +7450 +7451 +7452 +7453 +7454 +7455 +7456 +7457 +7458 +7459 +7460 +7461 +7462 +7463 +7464 +7465 +7466 +7467 +7468 +7469 +7470 +7471 +7472 +7473 +7474 +7475 +7476 +7477 +7478 +7479 +7480 +7481 +7482 +7483 +7484 +7485 +7486 +7487 +7488 +7489 +7490 +7491 +7492 +7493 +7494 +7495 +7496 +7497 +7498 +7499 +7500 +7501 +7502 +7503 +7504 +7505 +7506 +7507 +7508 +7509 +7510 +7511 +7512 +7513 +7514 +7515 +7516 +7517 +7518 +7519 +7520 +7521 +7522 +7523 +7524 +7525 +7526 +7527 +7528 +7529 +7530 +7531 +7532 +7533 +7534 +7535 +7536 +7537 +7538 +7539 +7540 +7541 +7542 +7543 +7544 +7545 +7546 +7547 +7548 +7549 +7550 +7551 +7552 +7553 +7554 +7555 +7556 +7557 +7558 +7559 +7560 +7561 +7562 +7563 +7564 +7565 +7566 +7567 +7568 +7569 +7570 +7571 +7572 +7573 +7574 +7575 +7576 +7577 +7578 +7579 +7580 +7581 +7582 +7583 +7584 +7585 +7586 +7587 +7588 +7589 +7590 +7591 +7592 +7593 +7594 +7595 +7596 +7597 +7598 +7599 +7600 +7601 +7602 +7603 +7604 +7605 +7606 +7607 +7608 +7609 +7610 +7611 +7612 +7613 +7614 +7615 +7616 +7617 +7618 +7619 +7620 +7621 +7622 +7623 +7624 +7625 +7626 +7627 +7628 +7629 +7630 +7631 +7632 +7633 +7634 +7635 +7636 +7637 +7638 +7639 +7640 +7641 +7642 +7643 +7644 +7645 +7646 +7647 +7648 +7649 +7650 +7651 +7652 +7653 +7654 +7655 +7656 +7657 +7658 +7659 +7660 +7661 +7662 +7663 +7664 +7665 +7666 +7667 +7668 +7669 +7670 +7671 +7672 +7673 +7674 +7675 +7676 +7677 +7678 +7679 +7680 +7681 +7682 +7683 +7684 +7685 +7686 +7687 +7688 +7689 +7690 +7691 +7692 +7693 +7694 +7695 +7696 +7697 +7698 +7699 +7700 +7701 +7702 +7703 +7704 +7705 +7706 +7707 +7708 +7709 +7710 +7711 +7712 +7713 +7714 +7715 +7716 +7717 +7718 +7719 +7720 +7721 +7722 +7723 +7724 +7725 +7726 +7727 +7728 +7729 +7730 +7731 +7732 +7733 +7734 +7735 +7736 +7737 +7738 +7739 +7740 +7741 +7742 +7743 +7744 +7745 +7746 +7747 +7748 +7749 +7750 +7751 +7752 +7753 +7754 +7755 +7756 +7757 +7758 +7759 +7760 +7761 +7762 +7763 +7764 +7765 +7766 +7767 +7768 +7769 +7770 +7771 +7772 +7773 +7774 +7775 +7776 +7777 +7778 +7779 +7780 +7781 +7782 +7783 +7784 +7785 +7786 +7787 +7788 +7789 +7790 +7791 +7792 +7793 +7794 +7795 +7796 +7797 +7798 +7799 +7800 +7801 +7802 +7803 +7804 +7805 +7806 +7807 +7808 +7809 +7810 +7811 +7812 +7813 +7814 +7815 +7816 +7817 +7818 +7819 +7820 +7821 +7822 +7823 +7824 +7825 +7826 +7827 +7828 +7829 +7830 +7831 +7832 +7833 +7834 +7835 +7836 +7837 +7838 +7839 +7840 +7841 +7842 +7843 +7844 +7845 +7846 +7847 +7848 +7849 +7850 +7851 +7852 +7853 +7854 +7855 +7856 +7857 +7858 +7859 +7860 +7861 +7862 +7863 +7864 +7865 +7866 +7867 +7868 +7869 +7870 +7871 +7872 +7873 +7874 +7875 +7876 +7877 +7878 +7879 +7880 +7881 +7882 +7883 +7884 +7885 +7886 +7887 +7888 +7889 +7890 +7891 +7892 +7893 +7894 +7895 +7896 +7897 +7898 +7899 +7900 +7901 +7902 +7903 +7904 +7905 +7906 +7907 +7908 +7909 +7910 +7911 +7912 +7913 +7914 +7915 +7916 +7917 +7918 +7919 +7920 +7921 +7922 +7923 +7924 +7925 +7926 +7927 +7928 +7929 +7930 +7931 +7932 +7933 +7934 +7935 +7936 +7937 +7938 +7939 +7940 +7941 +7942 +7943 +7944 +7945 +7946 +7947 +7948 +7949 +7950 +7951 +7952 +7953 +7954 +7955 +7956 +7957 +7958 +7959 +7960 +7961 +7962 +7963 +7964 +7965 +7966 +7967 +7968 +7969 +7970 +7971 +7972 +7973 +7974 +7975 +7976 +7977 +7978 +7979 +7980 +7981 +7982 +7983 +7984 +7985 +7986 +7987 +7988 +7989 +7990 +7991 +7992 +7993 +7994 +7995 +7996 +7997 +7998 +7999 +8000 +8001 +8002 +8003 +8004 +8005 +8006 +8007 +8008 +8009 +8010 +8011 +8012 +8013 +8014 +8015 +8016 +8017 +8018 +8019 +8020 +8021 +8022 +8023 +8024 +8025 +8026 +8027 +8028 +8029 +8030 +8031 +8032 +8033 +8034 +8035 +8036 +8037 +8038 +8039 +8040 +8041 +8042 +8043 +8044 +8045 +8046 +8047 +8048 +8049 +8050 +8051 +8052 +8053 +8054 +8055 +8056 +8057 +8058 +8059 +8060 +8061 +8062 +8063 +8064 +8065 +8066 +8067 +8068 +8069 +8070 +8071 +8072 +8073 +8074 +8075 +8076 +8077 +8078 +8079 +8080 +8081 +8082 +8083 +8084 +8085 +8086 +8087 +8088 +8089 +8090 +8091 +8092 +8093 +8094 +8095 +8096 +8097 +8098 +8099 +8100 +8101 +8102 +8103 +8104 +8105 +8106 +8107 +8108 +8109 +8110 +8111 +8112 +8113 +8114 +8115 +8116 +8117 +8118 +8119 +8120 +8121 +8122 +8123 +8124 +8125 +8126 +8127 +8128 +8129 +8130 +8131 +8132 +8133 +8134 +8135 +8136 +8137 +8138 +8139 +8140 +8141 +8142 +8143 +8144 +8145 +8146 +8147 +8148 +8149 +8150 +8151 +8152 +8153 +8154 +8155 +8156 +8157 +8158 +8159 +8160 +8161 +8162 +8163 +8164 +8165 +8166 +8167 +8168 +8169 +8170 +8171 +8172 +8173 +8174 +8175 +8176 +8177 +8178 +8179 +8180 +8181 +8182 +8183 +8184 +8185 +8186 +8187 +8188 +8189 +8190 +8191 +8192 +8193 +8194 +8195 +8196 +8197 +8198 +8199 +8200 +8201 +8202 +8203 +8204 +8205 +8206 +8207 +8208 +8209 +8210 +8211 +8212 +8213 +8214 +8215 +8216 +8217 +8218 +8219 +8220 +8221 +8222 +8223 +8224 +8225 +8226 +8227 +8228 +8229 +8230 +8231 +8232 +8233 +8234 +8235 +8236 +8237 +8238 +8239 +8240 +8241 +8242 +8243 +8244 +8245 +8246 +8247 +8248 +8249 +8250 +8251 +8252 +8253 +8254 +8255 +8256 +8257 +8258 +8259 +8260 +8261 +8262 +8263 +8264 +8265 +8266 +8267 +8268 +8269 +8270 +8271 +8272 +8273 +8274 +8275 +8276 +8277 +8278 +8279 +8280 +8281 +8282 +8283 +8284 +8285 +8286 +8287 +8288 +8289 +8290 +8291 +8292 +8293 +8294 +8295 +8296 +8297 +8298 +8299 +8300 +8301 +8302 +8303 +8304 +8305 +8306 +8307 +8308 +8309 +8310 +8311 +8312 +8313 +8314 +8315 +8316 +8317 +8318 +8319 +8320 +8321 +8322 +8323 +8324 +8325 +8326 +8327 +8328 +8329 +8330 +8331 +8332 +8333 +8334 +8335 +8336 +8337 +8338 +8339 +8340 +8341 +8342 +8343 +8344 +8345 +8346 +8347 +8348 +8349 +8350 +8351 +8352 +8353 +8354 +8355 +8356 +8357 +8358 +8359 +8360 +8361 +8362 +8363 +8364 +8365 +8366 +8367 +8368 +8369 +8370 +8371 +8372 +8373 +8374 +8375 +8376 +8377 +8378 +8379 +8380 +8381 +8382 +8383 +8384 +8385 +8386 +8387 +8388 +8389 +8390 +8391 +8392 +8393 +8394 +8395 +8396 +8397 +8398 +8399 +8400 +8401 +8402 +8403 +8404 +8405 +8406 +8407 +8408 +8409 +8410 +8411 +8412 +8413 +8414 +8415 +8416 +8417 +8418 +8419 +8420 +8421 +8422 +8423 +8424 +8425 +8426 +8427 +8428 +8429 +8430 +8431 +8432 +8433 +8434 +8435 +8436 +8437 +8438 +8439 +8440 +8441 +8442 +8443 +8444 +8445 +8446 +8447 +8448 +8449 +8450 +8451 +8452 +8453 +8454 +8455 +8456 +8457 +8458 +8459 +8460 +8461 +8462 +8463 +8464 +8465 +8466 +8467 +8468 +8469 +8470 +8471 +8472 +8473 +8474 +8475 +8476 +8477 +8478 +8479 +8480 +8481 +8482 +8483 +8484 +8485 +8486 +8487 +8488 +8489 +8490 +8491 +8492 +8493 +8494 +8495 +8496 +8497 +8498 +8499 +8500 +8501 +8502 +8503 +8504 +8505 +8506 +8507 +8508 +8509 +8510 +8511 +8512 +8513 +8514 +8515 +8516 +8517 +8518 +8519 +8520 +8521 +8522 +8523 +8524 +8525 +8526 +8527 +8528 +8529 +8530 +8531 +8532 +8533 +8534 +8535 +8536 +8537 +8538 +8539 +8540 +8541 +8542 +8543 +8544 +8545 +8546 +8547 +8548 +8549 +8550 +8551 +8552 +8553 +8554 +8555 +8556 +8557 +8558 +8559 +8560 +8561 +8562 +8563 +8564 +8565 +8566 +8567 +8568 +8569 +8570 +8571 +8572 +8573 +8574 +8575 +8576 +8577 +8578 +8579 +8580 +8581 +8582 +8583 +8584 +8585 +8586 +8587 +8588 +8589 +8590 +8591 +8592 +8593 +8594 +8595 +8596 +8597 +8598 +8599 +8600 +8601 +8602 +8603 +8604 +8605 +8606 +8607 +8608 +8609 +8610 +8611 +8612 +8613 +8614 +8615 +8616 +8617 +8618 +8619 +8620 +8621 +8622 +8623 +8624 +8625 +8626 +8627 +8628 +8629 +8630 +8631 +8632 +8633 +8634 +8635 +8636 +8637 +8638 +8639 +8640 +8641 +8642 +8643 +8644 +8645 +8646 +8647 +8648 +8649 +8650 +8651 +8652 +8653 +8654 +8655 +8656 +8657 +8658 +8659 +8660 +8661 +8662 +8663 +8664 +8665 +8666 +8667 +8668 +8669 +8670 +8671 +8672 +8673 +8674 +8675 +8676 +8677 +8678 +8679 +8680 +8681 +8682 +8683 +8684 +8685 +8686 +8687 +8688 +8689 +8690 +8691 +8692 +8693 +8694 +8695 +8696 +8697 +8698 +8699 +8700 +8701 +8702 +8703 +8704 +8705 +8706 +8707 +8708 +8709 +8710 +8711 +8712 +8713 +8714 +8715 +8716 +8717 +8718 +8719 +8720 +8721 +8722 +8723 +8724 +8725 +8726 +8727 +8728 +8729 +8730 +8731 +8732 +8733 +8734 +8735 +8736 +8737 +8738 +8739 +8740 +8741 +8742 +8743 +8744 +8745 +8746 +8747 +8748 +8749 +8750 +8751 +8752 +8753 +8754 +8755 +8756 +8757 +8758 +8759 +8760 +8761 +8762 +8763 +8764 +8765 +8766 +8767 +8768 +8769 +8770 +8771 +8772 +8773 +8774 +8775 +8776 +8777 +8778 +8779 +8780 +8781 +8782 +8783 +8784 +8785 +8786 +8787 +8788 +8789 +8790 +8791 +8792 +8793 +8794 +8795 +8796 +8797 +8798 +8799 +8800 +8801 +8802 +8803 +8804 +8805 +8806 +8807 +8808 +8809 +8810 +8811 +8812 +8813 +8814 +8815 +8816 +8817 +8818 +8819 +8820 +8821 +8822 +8823 +8824 +8825 +8826 +8827 +8828 +8829 +8830 +8831 +8832 +8833 +8834 +8835 +8836 +8837 +8838 +8839 +8840 +8841 +8842 +8843 +8844 +8845 +8846 +8847 +8848 +8849 +8850 +8851 +8852 +8853 +8854 +8855 +8856 +8857 +8858 +8859 +8860 +8861 +8862 +8863 +8864 +8865 +8866 +8867 +8868 +8869 +8870 +8871 +8872 +8873 +8874 +8875 +8876 +8877 +8878 +8879 +8880 +8881 +8882 +8883 +8884 +8885 +8886 +8887 +8888 +8889 +8890 +8891 +8892 +8893 +8894 +8895 +8896 +8897 +8898 +8899 +8900 +8901 +8902 +8903 +8904 +8905 +8906 +8907 +8908 +8909 +8910 +8911 +8912 +8913 +8914 +8915 +8916 +8917 +8918 +8919 +8920 +8921 +8922 +8923 +8924 +8925 +8926 +8927 +8928 +8929 +8930 +8931 +8932 +8933 +8934 +8935 +8936 +8937 +8938 +8939 +8940 +8941 +8942 +8943 +8944 +8945 +8946 +8947 +8948 +8949 +8950 +8951 +8952 +8953 +8954 +8955 +8956 +8957 +8958 +8959 +8960 +8961 +8962 +8963 +8964 +8965 +8966 +8967 +8968 +8969 +8970 +8971 +8972 +8973 +8974 +8975 +8976 +8977 +8978 +8979 +8980 +8981 +8982 +8983 +8984 +8985 +8986 +8987 +8988 +8989 +8990 +8991 +8992 +8993 +8994 +8995 +8996 +8997 +8998 +8999 +9000 +9001 +9002 +9003 +9004 +9005 +9006 +9007 +9008 +9009 +9010 +9011 +9012 +9013 +9014 +9015 +9016 +9017 +9018 +9019 +9020 +9021 +9022 +9023 +9024 +9025 +9026 +9027 +9028 +9029 +9030 +9031 +9032 +9033 +9034 +9035 +9036 +9037 +9038 +9039 +9040 +9041 +9042 +9043 +9044 +9045 +9046 +9047 +9048 +9049 +9050 +9051 +9052 +9053 +9054 +9055 +9056 +9057 +9058 +9059 +9060 +9061 +9062 +9063 +9064 +9065 +9066 +9067 +9068 +9069 +9070 +9071 +9072 +9073 +9074 +9075 +9076 +9077 +9078 +9079 +9080 +9081 +9082 +9083 +9084 +9085 +9086 +9087 +9088 +9089 +9090 +9091 +9092 +9093 +9094 +9095 +9096 +9097 +9098 +9099 +9100 +9101 +9102 +9103 +9104 +9105 +9106 +9107 +9108 +9109 +9110 +9111 +9112 +9113 +9114 +9115 +9116 +9117 +9118 +9119 +9120 +9121 +9122 +9123 +9124 +9125 +9126 +9127 +9128 +9129 +9130 +9131 +9132 +9133 +9134 +9135 +9136 +9137 +9138 +9139 +9140 +9141 +9142 +9143 +9144 +9145 +9146 +9147 +9148 +9149 +9150 +9151 +9152 +9153 +9154 +9155 +9156 +9157 +9158 +9159 +9160 +9161 +9162 +9163 +9164 +9165 +9166 +9167 +9168 +9169 +9170 +9171 +9172 +9173 +9174 +9175 +9176 +9177 +9178 +9179 +9180 +9181 +9182 +9183 +9184 +9185 +9186 +9187 +9188 +9189 +9190 +9191 +9192 +9193 +9194 +9195 +9196 +9197 +9198 +9199 +9200 +9201 +9202 +9203 +9204 +9205 +9206 +9207 +9208 +9209 +9210 +9211 +9212 +9213 +9214 +9215 +9216 +9217 +9218 +9219 +9220 +9221 +9222 +9223 +9224 +9225 +9226 +9227 +9228 +9229 +9230 +9231 +9232 +9233 +9234 +9235 +9236 +9237 +9238 +9239 +9240 +9241 +9242 +9243 +9244 +9245 +9246 +9247 +9248 +9249 +9250 +9251 +9252 +9253 +9254 +9255 +9256 +9257 +9258 +9259 +9260 +9261 +9262 +9263 +9264 +9265 +9266 +9267 +9268 +9269 +9270 +9271 +9272 +9273 +9274 +9275 +9276 +9277 +9278 +9279 +9280 +9281 +9282 +9283 +9284 +9285 +9286 +9287 +9288 +9289 +9290 +9291 +9292 +9293 +9294 +9295 +9296 +9297 +9298 +9299 +9300 +9301 +9302 +9303 +9304 +9305 +9306 +9307 +9308 +9309 +9310 +9311 +9312 +9313 +9314 +9315 +9316 +9317 +9318 +9319 +9320 +9321 +9322 +9323 +9324 +9325 +9326 +9327 +9328 +9329 +9330 +9331 +9332 +9333 +9334 +9335 +9336 +9337 +9338 +9339 +9340 +9341 +9342 +9343 +9344 +9345 +9346 +9347 +9348 +9349 +9350 +9351 +9352 +9353 +9354 +9355 +9356 +9357 +9358 +9359 +9360 +9361 +9362 +9363 +9364 +9365 +9366 +9367 +9368 +9369 +9370 +9371 +9372 +9373 +9374 +9375 +9376 +9377 +9378 +9379 +9380 +9381 +9382 +9383 +9384 +9385 +9386 +9387 +9388 +9389 +9390 +9391 +9392 +9393 +9394 +9395 +9396 +9397 +9398 +9399 +9400 +9401 +9402 +9403 +9404 +9405 +9406 +9407 +9408 +9409 +9410 +9411 +9412 +9413 +9414 +9415 +9416 +9417 +9418 +9419 +9420 +9421 +9422 +9423 +9424 +9425 +9426 +9427 +9428 +9429 +9430 +9431 +9432 +9433 +9434 +9435 +9436 +9437 +9438 +9439 +9440 +9441 +9442 +9443 +9444 +9445 +9446 +9447 +9448 +9449 +9450 +9451 +9452 +9453 +9454 +9455 +9456 +9457 +9458 +9459 +9460 +9461 +9462 +9463 +9464 +9465 +9466 +9467 +9468 +9469 +9470 +9471 +9472 +9473 +9474 +9475 +9476 +9477 +9478 +9479 +9480 +9481 +9482 +9483 +9484 +9485 +9486 +9487 +9488 +9489 +9490 +9491 +9492 +9493 +9494 +9495 +9496 +9497 +9498 +9499 +9500 +9501 +9502 +9503 +9504 +9505 +9506 +9507 +9508 +9509 +9510 +9511 +9512 +9513 +9514 +9515 +9516 +9517 +9518 +9519 +9520 +9521 +9522 +9523 +9524 +9525 +9526 +9527 +9528 +9529 +9530 +9531 +9532 +9533 +9534 +9535 +9536 +9537 +9538 +9539 +9540 +9541 +9542 +9543 +9544 +9545 +9546 +9547 +9548 +9549 +9550 +9551 +9552 +9553 +9554 +9555 +9556 +9557 +9558 +9559 +9560 +9561 +9562 +9563 +9564 +9565 +9566 +9567 +9568 +9569 +9570 +9571 +9572 +9573 +9574 +9575 +9576 +9577 +9578 +9579 +9580 +9581 +9582 +9583 +9584 +9585 +9586 +9587 +9588 +9589 +9590 +9591 +9592 +9593 +9594 +9595 +9596 +9597 +9598 +9599 +9600 +9601 +9602 +9603 +9604 +9605 +9606 +9607 +9608 +9609 +9610 +9611 +9612 +9613 +9614 +9615 +9616 +9617 +9618 +9619 +9620 +9621 +9622 +9623 +9624 +9625 +9626 +9627 +9628 +9629 +9630 +9631 +9632 +9633 +9634 +9635 +9636 +9637 +9638 +9639 +9640 +9641 +9642 +9643 +9644 +9645 +9646 +9647 +9648 +9649 +9650 +9651 +9652 +9653 +9654 +9655 +9656 +9657 +9658 +9659 +9660 +9661 +9662 +9663 +9664 +9665 +9666 +9667 +9668 +9669 +9670 +9671 +9672 +9673 +9674 +9675 +9676 +9677 +9678 +9679 +9680 +9681 +9682 +9683 +9684 +9685 +9686 +9687 +9688 +9689 +9690 +9691 +9692 +9693 +9694 +9695 +9696 +9697 +9698 +9699 +9700 +9701 +9702 +9703 +9704 +9705 +9706 +9707 +9708 +9709 +9710 +9711 +9712 +9713 +9714 +9715 +9716 +9717 +9718 +9719 +9720 +9721 +9722 +9723 +9724 +9725 +9726 +9727 +9728 +9729 +9730 +9731 +9732 +9733 +9734 +9735 +9736 +9737 +9738 +9739 +9740 +9741 +9742 +9743 +9744 +9745 +9746 +9747 +9748 +9749 +9750 +9751 +9752 +9753 +9754 +9755 +9756 +9757 +9758 +9759 +9760 +9761 +9762 +9763 +9764 +9765 +9766 +9767 +9768 +9769 +9770 +9771 +9772 +9773 +9774 +9775 +9776 +9777 +9778 +9779 +9780 +9781 +9782 +9783 +9784 +9785 +9786 +9787 +9788 +9789 +9790 +9791 +9792 +9793 +9794 +9795 +9796 +9797 +9798 +9799 +9800 +9801 +9802 +9803 +9804 +9805 +9806 +9807 +9808 +9809 +9810 +9811 +9812 +9813 +9814 +9815 +9816 +9817 +9818 +9819 +9820 +9821 +9822 +9823 +9824 +9825 +9826 +9827 +9828 +9829 +9830 +9831 +9832 +9833 +9834 +9835 +9836 +9837 +9838 +9839 +9840 +9841 +9842 +9843 +9844 +9845 +9846 +9847 +9848 +9849 +9850 +9851 +9852 +9853 +9854 +9855 +9856 +9857 +9858 +9859 +9860 +9861 +9862 +9863 +9864 +9865 +9866 +9867 +9868 +9869 +9870 +9871 +9872 +9873 +9874 +9875 +9876 +9877 +9878 +9879 +9880 +9881 +9882 +9883 +9884 +9885 +9886 +9887 +9888 +9889 +9890 +9891 +9892 +9893 +9894 +9895 +9896 +9897 +9898 +9899 +9900 +9901 +9902 +9903 +9904 +9905 +9906 +9907 +9908 +9909 +9910 +9911 +9912 +9913 +9914 +9915 +9916 +9917 +9918 +9919 +9920 +9921 +9922 +9923 +9924 +9925 +9926 +9927 +9928 +9929 +9930 +9931 +9932 +9933 +9934 +9935 +9936 +9937 +9938 +9939 +9940 +9941 +9942 +9943 +9944 +9945 +9946 +9947 +9948 +9949 +9950 +9951 +9952 +9953 +9954 +9955 +9956 +9957 +9958 +9959 +9960 +9961 +9962 +9963 +9964 +9965 +9966 +9967 +9968 +9969 +9970 +9971 +9972 +9973 +9974 +9975 +9976 +9977 +9978 +9979 +9980 +9981 +9982 +9983 +9984 +9985 +9986 +9987 +9988 +9989 +9990 +9991 +9992 +9993 +9994 +9995 +9996 +9997 +9998 +9999 +10000 diff --git a/cpp/wedpr-computing/ppc-psi/tests/ra2018-psi/mock-data/psi.txt b/cpp/wedpr-computing/ppc-psi/tests/ra2018-psi/mock-data/psi.txt new file mode 100644 index 00000000..d39f4855 --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/tests/ra2018-psi/mock-data/psi.txt @@ -0,0 +1,50 @@ +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 + + +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 diff --git a/cpp/wedpr-computing/ppc-psi/tests/ra2018-psi/mock-data/psi2.txt b/cpp/wedpr-computing/ppc-psi/tests/ra2018-psi/mock-data/psi2.txt new file mode 100644 index 00000000..d1517d07 --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/tests/ra2018-psi/mock-data/psi2.txt @@ -0,0 +1,672 @@ +2000 +2003 +2006 +2009 +2012 +2015 +2018 +2021 +2024 +2027 +2030 +2033 +2036 +2039 +2042 +2045 +2048 +2051 +2054 +2057 +2060 +2063 +2066 +2069 +2072 +2075 +2078 +2081 +2084 +2087 +2090 +2093 +2096 +2099 +2102 +2105 +2108 +2111 +2114 +2117 +2120 +2123 +2126 +2129 +2132 +2135 +2138 +2141 +2144 +2147 +2150 +2153 +2156 +2159 +2162 +2165 +2168 +2171 +2174 +2177 +2180 +2183 +2186 +2189 +2192 +2195 +2198 +2201 +2204 +2207 +2210 +2213 +2216 +2219 +2222 +2225 +2228 +2231 +2234 +2237 +2240 +2243 +2246 +2249 +2252 +2255 +2258 +2261 +2264 +2267 +2270 +2273 +2276 +2279 +2282 +2285 +2288 +2291 +2294 +2297 +2300 +2303 +2306 +2309 +2312 +2315 +2318 +2321 +2324 +2327 +2330 +2333 +2336 +2339 +2342 +2345 +2348 +2351 +2354 +2357 +2360 +2363 +2366 +2369 +2372 +2375 +2378 +2381 +2384 +2387 +2390 +2393 +2396 +2399 +2402 +2405 +2408 +2411 +2414 +2417 +2420 +2423 +2426 +2429 +2432 +2435 +2438 +2441 +2444 +2447 +2450 +2453 +2456 +2459 +2462 +2465 +2468 +2471 +2474 +2477 +2480 +2483 +2486 +2489 +2492 +2495 +2498 +2501 +2504 +2507 +2510 +2513 +2516 +2519 +2522 +2525 +2528 +2531 +2534 +2537 +2540 +2543 +2546 +2549 +2552 +2555 +2558 +2561 +2564 +2567 +2570 +2573 +2576 +2579 +2582 +2585 +2588 +2591 +2594 +2597 +2600 +2603 +2606 +2609 +2612 +2615 +2618 +2621 +2624 +2627 +2630 +2633 +2636 +2639 +2642 +2645 +2648 +2651 +2654 +2657 +2660 +2663 +2666 +2669 +2672 +2675 +2678 +2681 +2684 +2687 +2690 +2693 +2696 +2699 +2702 +2705 +2708 +2711 +2714 +2717 +2720 +2723 +2726 +2729 +2732 +2735 +2738 +2741 +2744 +2747 +2750 +2753 +2756 +2759 +2762 +2765 +2768 +2771 +2774 +2777 +2780 +2783 +2786 +2789 +2792 +2795 +2798 +2801 +2804 +2807 +2810 +2813 +2816 +2819 +2822 +2825 +2828 +2831 +2834 +2837 +2840 +2843 +2846 +2849 +2852 +2855 +2858 +2861 +2864 +2867 +2870 +2873 +2876 +2879 +2882 +2885 +2888 +2891 +2894 +2897 +2900 +2903 +2906 +2909 +2912 +2915 +2918 +2921 +2924 +2927 +2930 +2933 +2936 +2939 +2942 +2945 +2948 +2951 +2954 +2957 +2960 +2963 +2966 +2969 +2972 +2975 +2978 +2981 +2984 +2987 +2990 +2993 +2996 +2999 +3002 +3005 +3008 +3011 +3014 +3017 +3020 +3023 +3026 +3029 +3032 +3035 +3038 +3041 +3044 +3047 +3050 +3053 +3056 +3059 +3062 +3065 +3068 +3071 +3074 +3077 +3080 +3083 +3086 +3089 +3092 +3095 +3098 +3101 +3104 +3107 +3110 +3113 +3116 +3119 +3122 +3125 +3128 +3131 +3134 +3137 +3140 +3143 +3146 +3149 +3152 +3155 +3158 +3161 +3164 +3167 +3170 +3173 +3176 +3179 +3182 +3185 +3188 +3191 +3194 +3197 +3200 +3203 +3206 +3209 +3212 +3215 +3218 +3221 +3224 +3227 +3230 +3233 +3236 +3239 +3242 +3245 +3248 +3251 +3254 +3257 +3260 +3263 +3266 +3269 +3272 +3275 +3278 +3281 +3284 +3287 +3290 +3293 +3296 +3299 +3302 +3305 +3308 +3311 +3314 +3317 +3320 +3323 +3326 +3329 +3332 +3335 +3338 +3341 +3344 +3347 +3350 +3353 +3356 +3359 +3362 +3365 +3368 +3371 +3374 +3377 +3380 +3383 +3386 +3389 +3392 +3395 +3398 +3401 +3404 +3407 +3410 +3413 +3416 +3419 +3422 +3425 +3428 +3431 +3434 +3437 +3440 +3443 +3446 +3449 +3452 +3455 +3458 +3461 +3464 +3467 +3470 +3473 +3476 +3479 +3482 +3485 +3488 +3491 +3494 +3497 +3500 +3503 +3506 +3509 +3512 +3515 +3518 +3521 +3524 +3527 +3530 +3533 +3536 +3539 +3542 +3545 +3548 +3551 +3554 +3557 +3560 +3563 +3566 +3569 +3572 +3575 +3578 +3581 +3584 +3587 +3590 +3593 +3596 +3599 +3602 +3605 +3608 +3611 +3614 +3617 +3620 +3623 +3626 +3629 +3632 +3635 +3638 +3641 +3644 +3647 +3650 +3653 +3656 +3659 +3662 +3665 +3668 +3671 +3674 +3677 +3680 +3683 +3686 +3689 +3692 +3695 +3698 +3701 +3704 +3707 +3710 +3713 +3716 +3719 +3722 +3725 +3728 +3731 +3734 +3737 +3740 +3743 +3746 +3749 +3752 +3755 +3758 +3761 +3764 +3767 +3770 +3773 +3776 +3779 +3782 +3785 +3788 +3791 +3794 +3797 +3800 +3803 +3806 +3809 +3812 +3815 +3818 +3821 +3824 +3827 +3830 +3833 +3836 +3839 +3842 +3845 +3848 +3851 +3854 +3857 +3860 +3863 +3866 +3869 +3872 +3875 +3878 +3881 +3884 +3887 +3890 +3893 +3896 +3899 +3902 +3905 +3908 +3911 +3914 +3917 +3920 +3923 +3926 +3929 +3932 +3935 +3938 +3941 +3944 +3947 +3950 +3953 +3956 +3959 +3962 +3965 +3968 +3971 +3974 +3977 +3980 +3983 +3986 +3989 +3992 +3995 +3998 +abcdefg0 +abcdefg1 +abcdefg2 +abcdefg3 +abcdefg0 diff --git a/cpp/wedpr-computing/ppc-psi/tests/ra2018-psi/mock/Common.h b/cpp/wedpr-computing/ppc-psi/tests/ra2018-psi/mock/Common.h new file mode 100644 index 00000000..80459986 --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/tests/ra2018-psi/mock/Common.h @@ -0,0 +1,122 @@ +/* + * Copyright (C) 2022 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 applicabl 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 Common.h + * @author: yujiechen + * @date 2022-12-29 + */ +#pragma once +#include "ppc-io/src/FileLineReader.h" +#include "protocol/src/JsonTaskImpl.h" +#include "test-utils/TaskMock.h" +#include + +using namespace bcos; +using namespace ppc::protocol; +using namespace ppc::io; + +namespace ppc::test +{ +template +inline void checkTaskPSIResult(T _factory, ppc::protocol::Task::ConstPtr _task, + uint64_t expectedResultSize, std::vector _expectedPSIResult) +{ + auto outputDesc = _task->selfParty()->dataResource()->outputDesc(); + auto reader = _factory->resourceLoader()->loadReader(outputDesc, DataSchema::String, false); + // get all result + DataBatch::Ptr result = reader->next(-1); + // check the result + std::cout << "### result size:" << (result ? result->size() : 0) << std::endl; + std::cout << "### expectedResultSize: " << expectedResultSize << std::endl; + BOOST_CHECK(result->size() == expectedResultSize); + if (_expectedPSIResult.empty()) + { + return; + } + // Note: the order of the result is not the same with _expectedPSIResult + std::set expectedResult(_expectedPSIResult.begin(), _expectedPSIResult.end()); + for (uint64_t i = 0; i < result->size(); i++) + { + BOOST_CHECK(expectedResult.count(result->get(i))); + } +} + +// online psi +template +void testPSI(T _factory, S _server, S _client, ppc::protocol::Task::ConstPtr _serverPsiTask, + ppc::protocol::Task::ConstPtr _clientPsiTask, bool _expectedSuccess, + std::vector const& _expectedPSIResult, int _expectedErrorCode = 0) +{ + bool serverFinished = false; + bool clientFinished = false; + _server->asyncRunTask(_serverPsiTask, [_serverPsiTask, _expectedSuccess, _expectedErrorCode, + &serverFinished]( + ppc::protocol::TaskResult::Ptr&& _response) { + if (_expectedSuccess) + { + BOOST_CHECK(_response->error() == nullptr || _response->error()->errorCode() == 0); + BOOST_CHECK(_response->taskID() == _serverPsiTask->id()); + auto result = _response->error(); + BOOST_CHECK(result == nullptr || result->errorCode() == 0); + } + else + { + BOOST_CHECK(_response->error() != nullptr); + auto result = _response->error(); + BOOST_CHECK(result != nullptr); + std::cout << "### response errorCode: " << _response->error()->errorCode() << std::endl; + std::cout << "### _expectedErrorCode: " << _expectedErrorCode << std::endl; + BOOST_CHECK(_response->error()->errorCode() == _expectedErrorCode); + } + serverFinished = true; + std::cout << "#### testPSI, the server asyncRunTask success" << std::endl; + }); + _client->asyncRunTask(_clientPsiTask, [_clientPsiTask, _expectedSuccess, &clientFinished]( + ppc::protocol::TaskResult::Ptr&& _response) { + if (_expectedSuccess) + { + BOOST_CHECK(_response->error() == nullptr || _response->error()->errorCode() == 0); + BOOST_CHECK(_response->taskID() == _clientPsiTask->id()); + auto result = _response->error(); + BOOST_CHECK(result == nullptr || result->errorCode() == 0); + } + else + { + BOOST_CHECK(_response->error() != nullptr); + auto result = _response->error(); + BOOST_CHECK(result != nullptr); + } + clientFinished = true; + std::cout << "#### testPSI, the client asyncRunTask success" << std::endl; + }); + // wait for the task finish and check + while (!clientFinished || !serverFinished || _server->pendingTasksSize() > 0 || + _client->pendingTasksSize() > 0) + { + _server->executeWorker(); + _client->executeWorker(); + std::this_thread::sleep_for(std::chrono::milliseconds(20)); + } + BOOST_CHECK(_client->pendingTasksSize() == 0); + BOOST_CHECK(_client->lockingResourceSize() == 0); + BOOST_CHECK(_server->pendingTasksSize() == 0); + BOOST_CHECK(_server->lockingResourceSize() == 0); + if (_expectedSuccess) + { + checkTaskPSIResult(_factory, _clientPsiTask, _expectedPSIResult.size(), _expectedPSIResult); + } +} + +} // namespace ppc::test \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-psi/tests/ra2018-psi/mock/EcdhPSIFixture.h b/cpp/wedpr-computing/ppc-psi/tests/ra2018-psi/mock/EcdhPSIFixture.h new file mode 100644 index 00000000..4404c8b3 --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/tests/ra2018-psi/mock/EcdhPSIFixture.h @@ -0,0 +1,112 @@ +/* + * Copyright (C) 2022 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 applicabl 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 EcdhPSIFixutre.h + * @author: yujiechen + * @date 2022-12-29 + */ +#pragma once +#include "ppc-crypto-core/src/hash/Sha256Hash.h" +#include "ppc-crypto/src/ecc/ECDHCryptoFactoryImpl.h" +#include "ppc-crypto/src/ecc/Ed25519EccCrypto.h" +#include "ppc-crypto/src/ecc/OpenSSLEccCrypto.h" +#include "ppc-io/src/DataResourceLoaderImpl.h" +#include "ppc-tools/src/config/PPCConfig.h" +#include "test-utils/FakeFront.h" +#include "test-utils/FakePPCMessage.h" +#include +#include + + +using namespace bcos; +using namespace ppc::protocol; +using namespace ppc::psi; +using namespace ppc::crypto; +using namespace ppc::io; +using namespace ppc::front; +using namespace ppc::tools; + +namespace ppc::test +{ +class FakeEcdhPSIImpl : public EcdhPSIImpl +{ +public: + using Ptr = std::shared_ptr; + FakeEcdhPSIImpl(EcdhPSIConfig::Ptr const& _config, unsigned _idleTimeMs = 0) + : EcdhPSIImpl(_config, _idleTimeMs) + { + // set the m_started flag to be true + m_started = true; + m_taskSyncTimer->registerTimeoutHandler([this]() { syncTaskInfo(); }); + m_taskSyncTimer->start(); + } + ~FakeEcdhPSIImpl() override = default; +}; + +class FakeEcdhPSIFactory : public EcdhPSIFactory +{ +public: + using Ptr = std::shared_ptr; + FakeEcdhPSIFactory() + : m_front(std::make_shared()), + m_ppcMsgFactory(std::make_shared()), + m_dataResourceLoader(std::make_shared( + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr)), + m_threadPool(std::make_shared("ra2018-psi", 4)) + { + auto hashImpl = std::make_shared(); + auto eccCrypto = std::make_shared(hashImpl, ECCCurve::P256); + m_cryptoBox = std::make_shared(hashImpl, eccCrypto); + } + + ~FakeEcdhPSIFactory() override = default; + + EcdhPSIImpl::Ptr createEcdhPSI(ppc::tools::PPCConfig::Ptr const& _ppcConfig, + ppc::crypto::ECDHCryptoFactory::Ptr const& _ecdhCryptoFactory, + ppc::front::FrontInterface::Ptr _front, + ppc::front::PPCMessageFaceFactory::Ptr _ppcMsgFactory, bcos::ThreadPool::Ptr _threadPool, + ppc::io::DataResourceLoader::Ptr const& _dataResourceLoader, + uint32_t minNeededMemoryGB = 1) override + { + auto psiMsgFactory = std::make_shared(); + auto const& ecdhParam = _ppcConfig->ecdhPSIConfig(); + auto config = std::make_shared(_ppcConfig->agencyID(), _ecdhCryptoFactory, + _front, _ppcMsgFactory, psiMsgFactory, _dataResourceLoader, ecdhParam.dataBatchSize, + 10000, minNeededMemoryGB, _threadPool); + // enforce the taskExpireTime to 3000ms + config->setTaskExpireTime(3000); + return std::make_shared(config); + } + + EcdhPSIImpl::Ptr createEcdhPSI(std::string const& _selfParty, PPCConfig::Ptr const& _config) + { + _config->setAgencyID(_selfParty); + auto const& ra2018Config = _config->ra2018PSIConfig(); + auto ecdhCryptoFactory = std::make_shared(_config->privateKey()); + return createEcdhPSI( + _config, ecdhCryptoFactory, m_front, m_ppcMsgFactory, nullptr, m_dataResourceLoader); + } + DataResourceLoaderImpl::Ptr resourceLoader() { return m_dataResourceLoader; } + FakeFront::Ptr front() { return m_front; } + CryptoBox::Ptr cryptoBox() { return m_cryptoBox; } + +private: + FakeFront::Ptr m_front; + CryptoBox::Ptr m_cryptoBox; + FakePPCMessageFactory::Ptr m_ppcMsgFactory; + DataResourceLoaderImpl::Ptr m_dataResourceLoader; + ThreadPool::Ptr m_threadPool; +}; +} // namespace ppc::test \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-psi/tests/ra2018-psi/mock/FakeRA2018PSIStorage.h b/cpp/wedpr-computing/ppc-psi/tests/ra2018-psi/mock/FakeRA2018PSIStorage.h new file mode 100644 index 00000000..343f2b69 --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/tests/ra2018-psi/mock/FakeRA2018PSIStorage.h @@ -0,0 +1,146 @@ +/* + * Copyright (C) 2022 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 applicabl 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 FakeRA2018PSIStorage.h + * @author: yujiechen + * @date 2022-11-16 + */ +#pragma once +#include "ppc-crypto-core/src/hash/MD5Hash.h" +#include "ppc-psi/src/ra2018-psi/storage/RA2018PSIStorage.h" + +using namespace ppc::psi; +using namespace ppc::crypto; + +namespace ppc::test +{ +class FakeRA2018PSIStorage : public RA2018PSIStorage +{ +public: + FakeRA2018PSIStorage(RA2018PSIConfig::Ptr _config) + : RA2018PSIStorage(_config), m_hashImpl(std::make_shared()) + {} + + ~FakeRA2018PSIStorage() override = default; + + void init() override {} + // get the (cuckoo-filter-id, cuckoo-filter-hash according to the _resourceID and loadFactor + // TODO: optimize the perf(use async-client) + CuckooFilterInfoSet getCuckooFilterInfos( + std::string const& _resourceID, bool _onlyNotFull) override + { + CuckooFilterInfoSet result; + bcos::ReadGuard l(x_cuckooFilterInfo); + if (!m_cuckooFilterInfo.count(_resourceID)) + { + return result; + } + auto const& filters = m_cuckooFilterInfo.at(_resourceID); + for (auto const& it : filters) + { + auto filter = it.second->cuckooFilter(); + if (_onlyNotFull && !filter->full()) + { + result.insert(it.second); + continue; + } + result.insert(it.second); + } + return result; + } + + // load the cuckoo-filter from the storage + CuckooFilterInfo::Ptr loadCuckooFilterDataInfo( + std::string const& _resourceID, int32_t _filterID, bool _deserialize) override + { + bcos::ReadGuard l(x_cuckooFilterInfo); + if (!m_cuckooFilterInfo.count(_resourceID) || + !m_cuckooFilterInfo.at(_resourceID).count(_filterID)) + { + return nullptr; + } + auto filterInfo = m_cuckooFilterInfo[_resourceID][_filterID]; + // with raw-data + if (!_deserialize) + { + auto cuckooFilterInfo = + std::make_shared(filterInfo->filterID(), filterInfo->hash()); + auto encodedData = filterInfo->cuckooFilter()->serialize(); + bcos::bytes data(encodedData.begin(), encodedData.end()); + // set the cuckoo-filterData + cuckooFilterInfo->setCuckooFilterData(std::move(data)); + return cuckooFilterInfo; + } + // with deserialized cuckoo-filter + return filterInfo; + } + + // insert a new cuckoo-filter to the storage + // update the entry if key-conflict + void asyncInsertCuckooFilter(std::string const& _resourceID, + DefaultCukooFilterPtr _cuckooFilter, std::function _callback, + int32_t _filterID = -1) override + { + auto filterID = _filterID; + bcos::WriteGuard l(x_cuckooFilterInfo); + if (filterID == -1) + { + m_filterID++; + filterID = m_filterID; + } + m_cuckooFilterInfo[_resourceID][filterID] = + generateCuckooFilterInfo(filterID, _cuckooFilter); + _callback(nullptr); + } + + // update the cuckoo-filter + // Note: update is more efficient than asyncInsertCuckooFilter + void asyncUpdateCuckooFilter(std::string const& _resourceID, + CuckooFilterInfo::Ptr const& _filterInfo, + std::function _callback) override + { + bcos::WriteGuard l(x_cuckooFilterInfo); + if (!m_cuckooFilterInfo.count(_resourceID) || + !m_cuckooFilterInfo.at(_resourceID).count(_filterInfo->filterID())) + { + _callback(std::make_shared( + -1, "update cuckoo-filter failed for the entry not exist!")); + return; + } + m_cuckooFilterInfo[_resourceID][_filterInfo->filterID()] = + generateCuckooFilterInfo(_filterInfo->filterID(), _filterInfo->cuckooFilter()); + _callback(nullptr); + } + +private: + CuckooFilterInfo::Ptr generateCuckooFilterInfo( + int32_t _filterID, DefaultCukooFilterPtr _cuckooFilter) + { + auto encodedData = _cuckooFilter->serialize(); + auto hashResult = m_hashImpl->hash( + bcos::bytesConstRef((bcos::byte*)encodedData.data(), encodedData.size())); + auto cuckooFilterInfo = std::make_shared(_filterID, hashResult); + cuckooFilterInfo->setCuckooFilter(std::move(_cuckooFilter)); + return cuckooFilterInfo; + } + +private: + Hash::Ptr m_hashImpl; + // resourceID => filterID => cuckooFilter + std::map> m_cuckooFilterInfo; + mutable bcos::SharedMutex x_cuckooFilterInfo; + int32_t m_filterID = 0; +}; +} // namespace ppc::test \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-psi/tests/ra2018-psi/mock/RA2018MessageFixture.h b/cpp/wedpr-computing/ppc-psi/tests/ra2018-psi/mock/RA2018MessageFixture.h new file mode 100644 index 00000000..22c0bbec --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/tests/ra2018-psi/mock/RA2018MessageFixture.h @@ -0,0 +1,185 @@ +/* + * Copyright (C) 2022 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 applicabl 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 RA2018MessageFixture.h + * @author: yujiechen + * @date 2022-11-16 + */ +#pragma once +#include "ppc-crypto-core/src/hash/MD5Hash.h" +#include "ppc-psi/src/ra2018-psi/protocol/RA2018Message.h" +#include +#include +#include +#include + +using namespace ppc::psi; +using namespace ppc::crypto; +using namespace ppc::tools; +using namespace bcos; +using namespace bcos::test; + +namespace ppc::test +{ +inline CuckooFilterInfo::Ptr fakeCuckooFilterInfo( + int32_t _filterID, Hash::Ptr hashImpl, CuckoofilterOption::Ptr option, uint64_t insertedKeySize) +{ + auto filterInfo = std::make_shared(_filterID); + auto filter = std::make_shared>(option); + std::vector hashList; + for (uint64_t i = 0; i < insertedKeySize; i++) + { + std::string input = std::to_string(i); + bcos::bytes inputData(input.begin(), input.end()); + hashList.emplace_back(hashImpl->hash(ref(inputData))); + } + // insert the hashList and check + auto tmpHashList = hashList; + auto result = filter->batchInsert(tmpHashList); + BOOST_CHECK(tmpHashList.empty() == true); + BOOST_CHECK(result); + // set the hash + auto md5Hash = std::make_shared(); + auto encodedData = filter->serialize(); + auto hashResult = + md5Hash->hash(bytesConstRef((bcos::byte*)encodedData.data(), encodedData.size())); + filterInfo->setHash(hashResult); + // set the cuckoo-filter + filterInfo->setCuckooFilter(std::move(filter)); + return filterInfo; +} + +inline void checkMessage(PSIMessageInterface::Ptr _msg, uint32_t _packetType, + std::string const& _partyID, std::string const& _resourceID, int32_t _version, + std::vector const& _data) +{ + // check the message + BOOST_CHECK(_msg->partyID() == _partyID); + BOOST_CHECK(_msg->resourceID() == _resourceID); + BOOST_CHECK(_msg->version() == _version); + BOOST_CHECK(_data.size() == _msg->dataSize()); + uint64_t i = 0; + for (uint64_t i = 0; i < _msg->dataSize(); i++) + { + auto msgData = _msg->getData(i); + BOOST_CHECK(_data.at(i) == bytes(msgData.begin(), msgData.end())); + } +} + +inline void fakeAndCheckRA2018Message(PSIMessageInterface::Ptr msg, + RA2018MessageFactory::Ptr _msgFactory, uint32_t _packetType, std::string const& _partyID, + std::string const& _resourceID, int32_t _version, std::vector const& _data) +{ + msg->setPacketType(_packetType); + msg->setPartyID(_partyID); + msg->setResourceID(_resourceID); + msg->setVersion(_version); + auto tmpData = _data; + msg->setData(std::move(tmpData)); + + // check the result + checkMessage(msg, _packetType, _partyID, _resourceID, _version, _data); + // encode + auto encodedData = msg->encode(); + // decode + auto decodedMsg = _msgFactory->decodePSIMessage(ref(*encodedData)); + checkMessage(decodedMsg, _packetType, _partyID, _resourceID, _version, _data); + + // check takeData + auto takedData = decodedMsg->takeData(); + uint64_t i = 0; + for (auto const& it : takedData) + { + BOOST_CHECK(_data.at(i) == it); + i++; + } +} + +inline void checkCuckooFilter( + RA2018FilterMessage::Ptr _msg, std::vector _cuckooFilters) +{ + auto& msgCuckooFilters = _msg->mutableFilterInfo(); + BOOST_CHECK(msgCuckooFilters.size() == _cuckooFilters.size()); + auto md5Hash = std::make_shared(); + for (uint64_t i = 0; i < msgCuckooFilters.size(); i++) + { + auto msgCuckooFilter = msgCuckooFilters.at(i); + auto cuckooFilter = _cuckooFilters.at(i); + BOOST_CHECK(msgCuckooFilter->filterID() == cuckooFilter->filterID()); + BOOST_CHECK(msgCuckooFilter->hash() == cuckooFilter->hash()); + if (cuckooFilter->cuckooFilter()) + { + BOOST_CHECK(msgCuckooFilter->cuckooFilter() != nullptr); + auto cuckooFilterEncodedData = cuckooFilter->cuckooFilter()->serialize(); + BOOST_CHECK(msgCuckooFilter->cuckooFilter()->serialize() == cuckooFilterEncodedData); + // check the hash + auto hashResult = md5Hash->hash(bytesConstRef( + (bcos::byte*)(cuckooFilterEncodedData.data()), cuckooFilterEncodedData.size())); + BOOST_CHECK(hashResult == cuckooFilter->hash()); + } + BOOST_CHECK(msgCuckooFilter->cuckooFilterData() == cuckooFilter->cuckooFilterData()); + } +} + +inline void fakeAndCheckRA2018FilterMessage(PSIMessageInterface::Ptr _msg, + RA2018MessageFactory::Ptr _msgFactory, uint32_t _packetType, std::string const& _partyID, + std::string const& _resourceID, int32_t _version, std::vector const& _data, + std::vector _cuckooFilters) +{ + auto msg = std::dynamic_pointer_cast(_msg); + // with empty cuckoo-filter + fakeAndCheckRA2018Message( + msg, _msgFactory, _packetType, _partyID, _resourceID, _version, _data); + + // set the cuckoo-filter + auto cuckooFilters = _cuckooFilters; + msg->setFilterInfo(std::move(_cuckooFilters)); + // check the cuckooFilters + checkCuckooFilter(msg, cuckooFilters); + + // encode + auto encodedData = msg->encode(); + auto decodedMsg = _msgFactory->decodePSIMessage(ref(*encodedData)); + checkMessage(decodedMsg, _packetType, _partyID, _resourceID, _version, _data); + auto decodedFilterMsg = std::dynamic_pointer_cast(decodedMsg); + // check the cuckoo-filters + checkCuckooFilter(decodedFilterMsg, cuckooFilters); +} + +inline void fakeAndCheckNotificationMessage(PSIMessageInterface::Ptr _msg, + RA2018MessageFactory::Ptr _msgFactory, uint32_t _packetType, std::string const& _partyID, + std::string const& _resourceID, int32_t _version, std::vector const& _data, + int32_t _errorCode, std::string const& _errorMsg) +{ + auto msg = std::dynamic_pointer_cast(_msg); + // with default errorCode/errorMessage + fakeAndCheckRA2018Message( + msg, _msgFactory, _packetType, _partyID, _resourceID, _version, _data); + msg->setErrorCode(_errorCode); + msg->setErrorMessage(_errorMsg); + + BOOST_CHECK(msg->errorCode() == _errorCode); + BOOST_CHECK(msg->errorMessage() == _errorMsg); + // encode + auto encodedData = msg->encode(); + // decode + auto decodedMsg = _msgFactory->decodePSIMessage(ref(*encodedData)); + auto decodedNotificationMsg = std::dynamic_pointer_cast(decodedMsg); + // check the errorCode/errorMessage + BOOST_CHECK(decodedNotificationMsg->errorCode() == _errorCode); + BOOST_CHECK(decodedNotificationMsg->errorMessage() == _errorMsg); +} + +} // namespace ppc::test \ No newline at end of file diff --git a/cpp/wedpr-computing/ppc-psi/tests/ra2018-psi/mock/RA2018PSIFixture.h b/cpp/wedpr-computing/ppc-psi/tests/ra2018-psi/mock/RA2018PSIFixture.h new file mode 100644 index 00000000..83eaffbe --- /dev/null +++ b/cpp/wedpr-computing/ppc-psi/tests/ra2018-psi/mock/RA2018PSIFixture.h @@ -0,0 +1,122 @@ +/* + * Copyright (C) 2022 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 RA2018PSIFixture.h + * @author: yujiechen + * @date 2022-11-6 + */ +#pragma once +#include "FakeRA2018PSIStorage.h" +#include "ppc-crypto-core/src/hash/MD5Hash.h" +#include "ppc-crypto-core/src/hash/Sha256Hash.h" +#include "ppc-crypto/src/ecc/Ed25519EccCrypto.h" +#include "ppc-crypto/src/ecc/OpenSSLEccCrypto.h" +#include "ppc-crypto/src/oprf/RA2018Oprf.h" +#include "ppc-framework/crypto/CryptoBox.h" +#include "ppc-io/src/DataResourceLoaderImpl.h" +#include "ppc-tools/src/config/PPCConfig.h" +#include "test-utils/FakeFront.h" +#include "test-utils/FakePPCMessage.h" +#include + +using namespace bcos; +using namespace ppc::protocol; +using namespace ppc::psi; +using namespace ppc::crypto; +using namespace ppc::io; +using namespace ppc::front; +using namespace ppc::tools; + +namespace ppc::test +{ +class FakeRA2018Impl : public RA2018PSIImpl +{ +public: + using Ptr = std::shared_ptr; + FakeRA2018Impl(RA2018PSIConfig::Ptr _config, RA2018PSIStorage::Ptr _storage, + unsigned _idleTimeMs = 0, bool _waitResult = false, bool _disabled = false) + : RA2018PSIImpl(_config, _storage, _idleTimeMs, _waitResult, _disabled) + { + // set the m_started flag to be true + m_started = true; + m_taskSyncTimer->registerTimeoutHandler([this]() { syncTaskInfo(); }); + m_taskSyncTimer->start(); + } + + ~FakeRA2018Impl() override = default; +}; + +class FakeRA2018PSIFactory : public RA2018PSIFactory +{ +public: + using Ptr = std::shared_ptr; + FakeRA2018PSIFactory() + : m_front(std::make_shared()), + m_ppcMsgFactory(std::make_shared()), + m_dataResourceLoader(std::make_shared( + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr)), + m_threadPool(std::make_shared("ra2018-psi", 4)) + { + auto hashImpl = std::make_shared(); + auto eccCrypto = std::make_shared(hashImpl, ECCCurve::P256); + m_cryptoBox = std::make_shared(hashImpl, eccCrypto); + m_binHashImpl = std::make_shared(); + } + + ~FakeRA2018PSIFactory() override = default; + + RA2018PSIImpl::Ptr createRA2018PSI(std::string const& _selfParty, + ppc::front::FrontInterface::Ptr _front, ppc::tools::PPCConfig::Ptr const& _config, + ppc::crypto::RA2018OprfInterface::Ptr const& _oprf, ppc::crypto::Hash::Ptr _binHashImpl, + ppc::front::PPCMessageFaceFactory::Ptr _ppcMsgFactory, + ppc::storage::SQLStorage::Ptr _storage, ppc::storage::FileStorage::Ptr _fileStorage, + bcos::ThreadPool::Ptr _threadPool, ppc::io::DataResourceLoader::Ptr _dataResourceLoader, + uint32_t minNeededMemoryGB = 1) override + { + auto const& ra2018Config = _config->ra2018PSIConfig(); + auto config = std::make_shared(_selfParty, _front, _oprf, _binHashImpl, + _ppcMsgFactory, ra2018Config.cuckooFilterOption, _threadPool, _storage, _fileStorage, + _dataResourceLoader, 10000, minNeededMemoryGB, ra2018Config.dbName, + ra2018Config.cuckooFilterCacheSize, ra2018Config.cacheSize, ra2018Config.dataBatchSize); + // enforce the taskExpireTime to 3000ms + config->setTaskExpireTime(3000); + // use the FakeRA2018PSIStorage + auto PSIStorage = std::make_shared(config); + // wait-for the task completed or exceptioned to call the notification-callback + return std::make_shared(config, PSIStorage, 0, true, false); + } + + RA2018PSIImpl::Ptr createRA2018PSI(std::string const& _selfParty, PPCConfig::Ptr const& _config) + { + auto const& ra2018Config = _config->ra2018PSIConfig(); + auto oprf = std::make_shared( + _config->privateKey(), m_cryptoBox->eccCrypto(), m_cryptoBox->hashImpl()); + return createRA2018PSI(_selfParty, m_front, _config, oprf, m_binHashImpl, m_ppcMsgFactory, + nullptr, nullptr, m_threadPool, m_dataResourceLoader); + } + + DataResourceLoaderImpl::Ptr resourceLoader() { return m_dataResourceLoader; } + FakeFront::Ptr front() { return m_front; } + CryptoBox::Ptr cryptoBox() { return m_cryptoBox; } + +private: + FakeFront::Ptr m_front; + CryptoBox::Ptr m_cryptoBox; + Hash::Ptr m_binHashImpl; + FakePPCMessageFactory::Ptr m_ppcMsgFactory; + DataResourceLoaderImpl::Ptr m_dataResourceLoader; + ThreadPool::Ptr m_threadPool; +}; +} // namespace ppc::test \ No newline at end of file diff --git a/cpp/wedpr-crypto/ppc-crypto-core/CMakeLists.txt b/cpp/wedpr-crypto/ppc-crypto-core/CMakeLists.txt new file mode 100644 index 00000000..2c156e1b --- /dev/null +++ b/cpp/wedpr-crypto/ppc-crypto-core/CMakeLists.txt @@ -0,0 +1,6 @@ +add_subdirectory(src) +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-crypto/ppc-crypto-core/src/CMakeLists.txt b/cpp/wedpr-crypto/ppc-crypto-core/src/CMakeLists.txt new file mode 100644 index 00000000..2a56797c --- /dev/null +++ b/cpp/wedpr-crypto/ppc-crypto-core/src/CMakeLists.txt @@ -0,0 +1,8 @@ +file(GLOB_RECURSE SRCS *.cpp) +add_library(${CRYPTO_CORE_TARGET} ${SRCS}) + +find_package(OpenSSL REQUIRED) +message(STATUS "OPENSSL_INCLUDE_DIR: ${OPENSSL_INCLUDE_DIR}") +message(STATUS "OPENSSL_LIBRARIES: ${OPENSSL_LIBRARIES}") + +target_link_libraries(${CRYPTO_CORE_TARGET} PUBLIC unofficial-sodium::sodium ${BCOS_UTILITIES_TARGET} OpenSSL::Crypto ${CPU_FEATURES_LIB}) \ No newline at end of file diff --git a/cpp/wedpr-crypto/ppc-crypto-core/src/Common.h b/cpp/wedpr-crypto/ppc-crypto-core/src/Common.h new file mode 100644 index 00000000..fce2f7ad --- /dev/null +++ b/cpp/wedpr-crypto/ppc-crypto-core/src/Common.h @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2022 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 Common.h + * @author: yujiechen + * @date 2022-11-2 + */ +#pragma once +#include "ppc-framework/Common.h" +#include +#include + +namespace ppc::crypto +{ +DERIVE_PPC_EXCEPTION(HashException); +DERIVE_PPC_EXCEPTION(SymCryptoException); +DERIVE_PPC_EXCEPTION(OreException); + +DERIVE_PPC_EXCEPTION(UnsupportedHashType); +DERIVE_PPC_EXCEPTION(BitVectorException); +DERIVE_PPC_EXCEPTION(FastOreException); +} // namespace ppc::crypto diff --git a/cpp/wedpr-crypto/ppc-crypto-core/src/hash/BLAKE2bHash.h b/cpp/wedpr-crypto/ppc-crypto-core/src/hash/BLAKE2bHash.h new file mode 100644 index 00000000..985377ed --- /dev/null +++ b/cpp/wedpr-crypto/ppc-crypto-core/src/hash/BLAKE2bHash.h @@ -0,0 +1,136 @@ +/** + * Copyright (C) 2022 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 BLAKE2bHash.h + * @author: shawnhe + * @date 2022-12-4 + */ + +#pragma once +#include "../Common.h" +#include "ppc-framework/crypto/Hash.h" +#include "ppc-framework/protocol/Protocol.h" +#include + +namespace ppc::crypto +{ +class BLAKE2bHashState : public HashState +{ +public: + using Ptr = std::shared_ptr; + BLAKE2bHashState() : m_state(std::make_shared()) {} + ~BLAKE2bHashState() override = default; + + void* state() override { return (void*)m_state.get(); } + +private: + std::shared_ptr m_state; +}; + +class BLAKE2bHash : public Hash +{ +public: + using Ptr = std::shared_ptr; + BLAKE2bHash() = default; + ~BLAKE2bHash() override = default; + + // the hashBytes length of given hash-algorithm + size_t hashLen() const override { return crypto_generichash_BYTES_MAX; } + + // the implementation of the hash-algorithm + ppc::protocol::HashImplName type() const override + { + return ppc::protocol::HashImplName::BLAKE2b; + } + + // calculate hash and output default length + bcos::bytes hash(bcos::bytesConstRef _input) const override + { + return hash(_input, crypto_generichash_BYTES_MAX); + } + + // calculate hash without key + bcos::bytes hash(bcos::bytesConstRef _input, size_t _outLen) const + { + return hash(_input, bcos::bytesConstRef(), _outLen); + } + + // calculate hash with a key + bcos::bytes hash(bcos::bytesConstRef _input, bcos::bytesConstRef _key, size_t _outLen) const + { + if (_outLen < crypto_generichash_BYTES_MIN || _outLen > crypto_generichash_BYTES_MAX) + { + BOOST_THROW_EXCEPTION(HashException() << bcos::errinfo_comment( + "outLen of BLAKE2b should be between " + + std::to_string(crypto_generichash_BYTES_MIN) + " and " + + std::to_string(crypto_generichash_BYTES_MAX))); + } + + bcos::bytes result(_outLen); + auto ret = crypto_generichash(result.data(), _outLen, (const unsigned char*)_input.data(), + _input.size(), (const unsigned char*)_key.data(), _key.size()); + if (ret) + { + BOOST_THROW_EXCEPTION( + HashException() << bcos::errinfo_comment( + "hash error for BLAKE2b_hash failed, code: " + std::to_string(ret))); + } + return result; + } + + // init the hash-state + HashState::Ptr init() const override { return init(bcos::bytesConstRef()); } + + // init the hash-state with a key + HashState::Ptr init(bcos::bytesConstRef _key) const + { + auto state = std::make_shared(); + auto ret = crypto_generichash_init((crypto_generichash_state*)state->state(), + (const unsigned char*)_key.data(), _key.size(), crypto_generichash_BYTES_MAX); + if (ret) + { + BOOST_THROW_EXCEPTION(HashException() << bcos::errinfo_comment( + "BLAKE2b_init error: " + std::to_string(ret))); + } + return state; + } + + // update new message into the given hash-state + void update(HashState::Ptr _state, bcos::bytesConstRef _data) const override + { + auto ret = crypto_generichash_update((crypto_generichash_state*)_state->state(), + (const unsigned char*)_data.data(), _data.size()); + if (ret) + { + BOOST_THROW_EXCEPTION(HashException() << bcos::errinfo_comment( + "BLAKE2b_update error: " + std::to_string(ret))); + } + } + + // obtain the hash-result from the given hash-state + bcos::bytes final(HashState::Ptr _state) const override + { + bcos::bytes result(crypto_generichash_BYTES_MAX); + auto ret = crypto_generichash_final((crypto_generichash_state*)_state->state(), + result.data(), crypto_generichash_BYTES_MAX); + if (ret) + { + BOOST_THROW_EXCEPTION(HashException() << bcos::errinfo_comment( + "BLAKE2b_final error: " + std::to_string(ret))); + } + return result; + } +}; +} // namespace ppc::crypto diff --git a/cpp/wedpr-crypto/ppc-crypto-core/src/hash/BitMixMurmurHash.h b/cpp/wedpr-crypto/ppc-crypto-core/src/hash/BitMixMurmurHash.h new file mode 100644 index 00000000..785b60db --- /dev/null +++ b/cpp/wedpr-crypto/ppc-crypto-core/src/hash/BitMixMurmurHash.h @@ -0,0 +1,283 @@ +/** + * Copyright (C) 2022 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 BitMixMurmurHash.h + * @author: yujiechen + * @date 2022-10-25 + */ +#pragma once +#include +#include +namespace ppc::crypto +{ +class BitMixMurmurHash +{ +public: + BitMixMurmurHash() = default; + ~BitMixMurmurHash() = default; + + template + uint64_t hash(T const& _key, unsigned _hashBitsLen, uint32_t _seed = 32) const + { + // Note: _seed is unused when the key is integer + boost::ignore_unused(_seed); + static_assert(std::is_same::value || + std::is_same::value || + std::is_same::value || + std::is_same::value || + std::is_same::value || std::is_same::value || + std::is_same::value || std::is_same::value || + std::is_same::value || std::is_same::value || + std::is_same::value || std::is_same::value, + "only support string/string_view/bytes/bytesConstRef/int8_t to int64_t/uint8_t to " + "uint64_t"); + // the bytes type + if constexpr (std::is_same::value || + std::is_same::value || + std::is_same::value || + std::is_same::value) + { + return hashData((const unsigned char*)_key.data(), _key.size(), _hashBitsLen, _seed); + } + else + { + // the int type + return (_hashBitsLen <= 32 ? (hash32N(_key)) : hash64N(_key)); + } + } + +protected: + uint64_t hashData( + const unsigned char* key, uint32_t len, unsigned _hashBitsLen, uint32_t _seed) const + { + return (_hashBitsLen <= 32 ? (hash32(key, len, _seed)) : hash64(key, len, _seed)); + } + + inline uint64_t hash64N(uint64_t _value) const + { // Bit mix from MurmurHash64/CLHash + _value ^= _value >> 33; + _value *= 0xff51afd7ed558ccdULL; + _value ^= _value >> 33; + _value *= 0xc4ceb9fe1a85ec53ULL; + _value ^= _value >> 33; + return _value; + } + + inline uint32_t hash32N(uint32_t _value) const + { // Bit mix from MurmurHash32 + _value ^= _value >> 16; + _value *= 0x85ebca6b; + _value ^= _value >> 13; + _value *= 0xc2b2ae35; + _value ^= _value >> 16; + return _value; + } + + // Note: when generating 32bits hash, there is a high probability of a collision + // so we default to generate 64bits hash + uint32_t hash32(const unsigned char* key, uint32_t len, uint32_t seed) const + { + uint32_t c1 = 0xcc9e2d51; + uint32_t c2 = 0x1b873593; + uint32_t r1 = 15; + uint32_t r2 = 13; + uint32_t m = 5; + uint32_t n = 0xe6546b64; + uint32_t h = 0; + uint32_t k = 0; + uint8_t* d = (uint8_t*)key; // 32 bit extract from `key' + const uint32_t* chunks = NULL; + const uint8_t* tail = NULL; // tail - last 8 bytes + int i = 0; + int l = len / 4; // chunk length + + h = seed; + + chunks = (const uint32_t*)(d + l * 4); // body + tail = (const uint8_t*)(d + l * 4); // last 8 byte chunk of `key' + + // for each 4 byte chunk of `key' + for (i = -l; i != 0; ++i) + { + // next 4 byte chunk of `key' + k = chunks[i]; + + // encode next 4 byte chunk of `key' + k *= c1; + k = (k << r1) | (k >> (32 - r1)); + k *= c2; + + // append to hash + h ^= k; + h = (h << r2) | (h >> (32 - r2)); + h = h * m + n; + } + k = 0; + // remainder + switch (len & 3) + { // `len % 4' + case 3: + k ^= (tail[2] << 16); + break; + case 2: + k ^= (tail[1] << 8); + break; + case 1: + k ^= tail[0]; + k *= c1; + k = (k << r1) | (k >> (32 - r1)); + k *= c2; + h ^= k; + break; + default: // unreachable-branch + break; + } + + h ^= len; + + h ^= (h >> 16); + h *= 0x85ebca6b; + h ^= (h >> 13); + h *= 0xc2b2ae35; + h ^= (h >> 16); + + return h; + } + + uint64_t hash64(const unsigned char* key, const int len, const uint32_t seed) const + { + const uint8_t* data = (const uint8_t*)key; + const int nblocks = len / 16; + int i; + + uint64_t h1 = seed; + uint64_t h2 = seed; + + uint64_t c1 = 0x87c37b91114253d5; + uint64_t c2 = 0x4cf5ad432745937f; + const uint64_t* blocks = (const uint64_t*)(data); + + for (i = 0; i < nblocks; i++) + { + uint64_t k1 = blocks[i * 2]; + uint64_t k2 = blocks[i * 2 + 1]; + + k1 *= c1; + k1 = rotl64(k1, 31); + k1 *= c2; + h1 ^= k1; + + h1 = rotl64(h1, 27); + h1 += h2; + h1 = h1 * 5 + 0x52dce729; + + k2 *= c2; + k2 = rotl64(k2, 33); + k2 *= c1; + h2 ^= k2; + + h2 = rotl64(h2, 31); + h2 += h1; + h2 = h2 * 5 + 0x38495ab5; + } + const uint8_t* tail = (const uint8_t*)(data + nblocks * 16); + + uint64_t k1 = 0; + uint64_t k2 = 0; + + switch (len & 15) + { + case 15: + k2 ^= (uint64_t)(tail[14]) << 48; + break; + case 14: + k2 ^= (uint64_t)(tail[13]) << 40; + break; + case 13: + k2 ^= (uint64_t)(tail[12]) << 32; + break; + case 12: + k2 ^= (uint64_t)(tail[11]) << 24; + break; + case 11: + k2 ^= (uint64_t)(tail[10]) << 16; + break; + case 10: + k2 ^= (uint64_t)(tail[9]) << 8; + break; + case 9: + k2 ^= (uint64_t)(tail[8]) << 0; + k2 *= c2; + k2 = rotl64(k2, 33); + k2 *= c1; + h2 ^= k2; + break; + case 8: + k1 ^= (uint64_t)(tail[7]) << 56; + break; + case 7: + k1 ^= (uint64_t)(tail[6]) << 48; + break; + case 6: + k1 ^= (uint64_t)(tail[5]) << 40; + break; + case 5: + k1 ^= (uint64_t)(tail[4]) << 32; + break; + case 4: + k1 ^= (uint64_t)(tail[3]) << 24; + break; + case 3: + k1 ^= (uint64_t)(tail[2]) << 16; + break; + case 2: + k1 ^= (uint64_t)(tail[1]) << 8; + break; + case 1: + k1 ^= (uint64_t)(tail[0]) << 0; + k1 *= c1; + k1 = rotl64(k1, 31); + k1 *= c2; + h1 ^= k1; + break; + default: // unreachable-branch + break; + }; + h1 ^= len; + h2 ^= len; + + h1 += h2; + h2 += h1; + + h1 = fmix64(h1); + h2 = fmix64(h2); + + h1 += h2; + h2 += h1; + return h1; + } + + inline uint64_t rotl64(uint64_t x, int8_t r) const { return (x << r) | (x >> (64 - r)); } + inline uint64_t fmix64(uint64_t k) const + { + k ^= k >> 33; + k *= 0xff51afd7ed558ccd; + k ^= k >> 33; + k *= 0xc4ceb9fe1a85ec53; + k ^= k >> 33; + return k; + } +}; +} // namespace ppc::crypto \ No newline at end of file diff --git a/cpp/wedpr-crypto/ppc-crypto-core/src/hash/HashFactoryImpl.h b/cpp/wedpr-crypto/ppc-crypto-core/src/hash/HashFactoryImpl.h new file mode 100644 index 00000000..500713d3 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-crypto-core/src/hash/HashFactoryImpl.h @@ -0,0 +1,58 @@ +/** + * 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 HashFactoryImpl.h + * @author: yujiechen + * @date 2023-1-3 + */ +#pragma once +#include "../Common.h" +#include "BLAKE2bHash.h" +#include "MD5Hash.h" +#include "SM3Hash.h" +#include "Sha256Hash.h" +#include "Sha512Hash.h" +#include "ppc-framework/protocol/Protocol.h" + +namespace ppc::crypto +{ +class HashFactoryImpl : public HashFactory +{ +public: + using Ptr = std::shared_ptr; + HashFactoryImpl() = default; + ~HashFactoryImpl() override = default; + + Hash::Ptr createHashImpl(int8_t _hashType) const override + { + switch (_hashType) + { + case (int8_t)ppc::protocol::HashImplName::SHA256: + return std::make_shared(); + case (int8_t)ppc::protocol::HashImplName::SHA512: + return std::make_shared(); + case (int8_t)ppc::protocol::HashImplName::SM3: + return std::make_shared(); + case (int8_t)ppc::protocol::HashImplName::MD5: + return std::make_shared(); + case (int8_t)ppc::protocol::HashImplName::BLAKE2b: + return std::make_shared(); + default: + BOOST_THROW_EXCEPTION(UnsupportedHashType() << bcos::errinfo_comment( + "unsupported hashType: " + std::to_string(_hashType))); + } + } +}; +} // namespace ppc::crypto \ No newline at end of file diff --git a/cpp/wedpr-crypto/ppc-crypto-core/src/hash/MD5Hash.h b/cpp/wedpr-crypto/ppc-crypto-core/src/hash/MD5Hash.h new file mode 100644 index 00000000..b685ba5f --- /dev/null +++ b/cpp/wedpr-crypto/ppc-crypto-core/src/hash/MD5Hash.h @@ -0,0 +1,102 @@ +/** + * Copyright (C) 2022 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 MD5Hash.h + * @author: yujiechen + * @date 2022-11-10 + */ +#pragma once +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#include "../Common.h" +#include "openssl/md5.h" +#include "ppc-framework/crypto/Hash.h" +#include "ppc-framework/protocol/Protocol.h" +#include + +namespace ppc::crypto +{ +class MD5HashState : public HashState +{ +public: + using Ptr = std::shared_ptr; + MD5HashState() : m_state(std::make_shared()) {} + ~MD5HashState() override = default; + + void* state() override { return (void*)m_state.get(); } + +private: + std::shared_ptr m_state; +}; + +class MD5Hash : public Hash +{ +public: + using Ptr = std::shared_ptr; + MD5Hash() = default; + ~MD5Hash() override = default; + + // the hashBytes length of given hash-algorithm + size_t hashLen() const override { return MD5_DIGEST_LENGTH; } + // the implementation of the hash-algorithm + ppc::protocol::HashImplName type() const override { return ppc::protocol::HashImplName::MD5; } + + // calculate-hash + bcos::bytes hash(bcos::bytesConstRef _input) const override + { + bcos::bytes result(MD5_DIGEST_LENGTH); + MD5(_input.data(), _input.size(), result.data()); + return result; + } + + // init the hash-state + HashState::Ptr init() const override + { + auto hashState = std::make_shared(); + auto ret = MD5_Init((MD5_CTX*)hashState->state()); + if (1 != ret) + { + BOOST_THROW_EXCEPTION( + HashException() << bcos::errinfo_comment("md5_init error: " + std::to_string(ret))); + } + return hashState; + } + + // update new message into the given hash-state + void update(HashState::Ptr _state, bcos::bytesConstRef _data) const override + { + auto ret = MD5_Update((MD5_CTX*)_state->state(), (const void*)_data.data(), _data.size()); + if (1 != ret) + { + BOOST_THROW_EXCEPTION(HashException() << bcos::errinfo_comment( + "md5_update error: " + std::to_string(ret))); + } + } + + // obtain the hash-result from the given hash-state + bcos::bytes final(HashState::Ptr _state) const override + { + bcos::bytes result(MD5_DIGEST_LENGTH); + auto ret = MD5_Final(result.data(), (MD5_CTX*)_state->state()); + if (1 != ret) + { + BOOST_THROW_EXCEPTION(HashException() << bcos::errinfo_comment( + "md5_final error: " + std::to_string(ret))); + } + return result; + } +}; +} // namespace ppc::crypto +#pragma GCC diagnostic pop \ No newline at end of file diff --git a/cpp/wedpr-crypto/ppc-crypto-core/src/hash/OpenSSLHash.h b/cpp/wedpr-crypto/ppc-crypto-core/src/hash/OpenSSLHash.h new file mode 100644 index 00000000..e69de29b diff --git a/cpp/wedpr-crypto/ppc-crypto-core/src/hash/SM3Hash.h b/cpp/wedpr-crypto/ppc-crypto-core/src/hash/SM3Hash.h new file mode 100644 index 00000000..9c742610 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-crypto-core/src/hash/SM3Hash.h @@ -0,0 +1,119 @@ +/** + * Copyright (C) 2022 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 SM3Hash.h + * @author: yujiechen + * @date 2022-11-2 + */ +#pragma once +#include "../Common.h" +#include "openssl/sm3.h" +#include "ppc-framework/crypto/Hash.h" +#include "ppc-framework/protocol/Protocol.h" + +namespace ppc::crypto +{ +class SM3HashState : public HashState +{ +public: + using Ptr = std::shared_ptr; + SM3HashState() : m_state(std::make_shared()) {} + ~SM3HashState() override = default; + + void* state() override { return (void*)m_state.get(); } + +private: + std::shared_ptr m_state; +}; + +class SM3Hash : public Hash +{ +public: + using Ptr = std::shared_ptr; + SM3Hash() = default; + ~SM3Hash() override = default; + + // the hashBytes length of given hash-algorithm + size_t hashLen() const override { return 32; } + // the implementation of the hash-algorithm + ppc::protocol::HashImplName type() const override { return ppc::protocol::HashImplName::SM3; } + + // calculate-hash + bcos::bytes hash(bcos::bytesConstRef _input) const override + { + SM3_CTX hashState; + auto ret = sm3_init(&hashState); + if (1 != ret) + { + BOOST_THROW_EXCEPTION( + HashException() << bcos::errinfo_comment( + "hash error for sm3_init failed, code: " + std::to_string(ret))); + } + ret = sm3_update(&hashState, (const void*)_input.data(), _input.size()); + if (1 != ret) + { + BOOST_THROW_EXCEPTION( + HashException() << bcos::errinfo_comment( + "hash error for sm3_update failed, code: " + std::to_string(ret))); + } + bcos::bytes result(32); + ret = sm3_final(result.data(), &hashState); + if (1 != ret) + { + BOOST_THROW_EXCEPTION( + HashException() << bcos::errinfo_comment( + "hash error for sm3_final failed, code: " + std::to_string(ret))); + } + return result; + } + + // init the hash-state + HashState::Ptr init() const override + { + auto hashState = std::make_shared(); + auto ret = sm3_init((SM3_CTX*)hashState->state()); + if (1 != ret) + { + BOOST_THROW_EXCEPTION( + HashException() << bcos::errinfo_comment("sm3_init error: " + std::to_string(ret))); + } + return hashState; + } + + // update new message into the given hash-state + void update(HashState::Ptr _state, bcos::bytesConstRef _data) const override + { + auto ret = sm3_update((SM3_CTX*)_state->state(), (const void*)_data.data(), _data.size()); + if (1 != ret) + { + BOOST_THROW_EXCEPTION(HashException() << bcos::errinfo_comment( + "sm3_update error: " + std::to_string(ret))); + } + } + + // obtain the hash-result from the given hash-state + bcos::bytes final(HashState::Ptr _state) const override + { + bcos::bytes result(32); + auto ret = sm3_final(result.data(), (SM3_CTX*)_state->state()); + if (1 != ret) + { + BOOST_THROW_EXCEPTION(HashException() << bcos::errinfo_comment( + "sm3_final error: " + std::to_string(ret))); + } + return result; + } +}; +} // namespace ppc::crypto diff --git a/cpp/wedpr-crypto/ppc-crypto-core/src/hash/Sha256Hash.h b/cpp/wedpr-crypto/ppc-crypto-core/src/hash/Sha256Hash.h new file mode 100644 index 00000000..ecbcb8cb --- /dev/null +++ b/cpp/wedpr-crypto/ppc-crypto-core/src/hash/Sha256Hash.h @@ -0,0 +1,107 @@ +/** + * Copyright (C) 2022 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 Sha256Hash.h + * @author: yujiechen + * @date 2022-11-2 + */ +#pragma once +#include "../Common.h" +#include "ppc-framework/crypto/Hash.h" +#include "ppc-framework/protocol/Protocol.h" +#include + +namespace ppc::crypto +{ +class Sha256HashState : public HashState +{ +public: + using Ptr = std::shared_ptr; + Sha256HashState() : m_state(std::make_shared()) {} + ~Sha256HashState() override = default; + void* state() override { return (void*)m_state.get(); } + +private: + std::shared_ptr m_state; +}; + +class Sha256Hash : public Hash +{ +public: + using Ptr = std::shared_ptr; + Sha256Hash() = default; + ~Sha256Hash() override = default; + + // the hashBytes length of given hash-algorithm + size_t hashLen() const override { return crypto_hash_sha256_BYTES; } + // the implementation of the hash-algorithm + ppc::protocol::HashImplName type() const override + { + return ppc::protocol::HashImplName::SHA256; + } + + // calculate-hash + bcos::bytes hash(bcos::bytesConstRef _input) const override + { + bcos::bytes result(crypto_hash_sha256_BYTES); + auto ret = crypto_hash_sha256(result.data(), _input.data(), _input.size()); + if (ret) + { + BOOST_THROW_EXCEPTION(HashException() << bcos::errinfo_comment( + "crypto_hash_sha256 error: " + std::to_string(ret))); + } + return result; + } + + // init the hash-state + HashState::Ptr init() const override + { + auto state = std::make_shared(); + auto ret = crypto_hash_sha256_init((crypto_hash_sha256_state*)state->state()); + if (ret) + { + BOOST_THROW_EXCEPTION(HashException() << bcos::errinfo_comment( + "crypto_hash_sha256_init error: " + std::to_string(ret))); + } + return state; + } + + // update new message into the given hash-state + void update(HashState::Ptr _state, bcos::bytesConstRef _data) const override + { + auto ret = crypto_hash_sha256_update( + (crypto_hash_sha256_state*)_state->state(), _data.data(), _data.size()); + if (ret) + { + BOOST_THROW_EXCEPTION(HashException() << bcos::errinfo_comment( + "crypto_hash_sha256_update error: " + std::to_string(ret))); + } + } + + // obtain the hash-result from the given hash-state + bcos::bytes final(HashState::Ptr _state) const override + { + bcos::bytes result(crypto_hash_sha256_BYTES); + auto ret = + crypto_hash_sha256_final((crypto_hash_sha256_state*)_state->state(), result.data()); + if (ret) + { + BOOST_THROW_EXCEPTION(HashException() << bcos::errinfo_comment( + "crypto_hash_sha256_final error: " + std::to_string(ret))); + } + return result; + } +}; +} // namespace ppc::crypto \ No newline at end of file diff --git a/cpp/wedpr-crypto/ppc-crypto-core/src/hash/Sha512Hash.h b/cpp/wedpr-crypto/ppc-crypto-core/src/hash/Sha512Hash.h new file mode 100644 index 00000000..f8a207b2 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-crypto-core/src/hash/Sha512Hash.h @@ -0,0 +1,107 @@ +/** + * Copyright (C) 2022 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 Sha512Hash.h + * @author: yujiechen + * @date 2022-11-2 + */ +#pragma once +#include "../Common.h" +#include "ppc-framework/crypto/Hash.h" +#include "ppc-framework/protocol/Protocol.h" +#include + +namespace ppc::crypto +{ +class Sha512HashState : public HashState +{ +public: + using Ptr = std::shared_ptr; + Sha512HashState() : m_state(std::make_shared()) {} + ~Sha512HashState() override = default; + void* state() override { return (void*)m_state.get(); } + +private: + std::shared_ptr m_state; +}; + +class Sha512Hash : public Hash +{ +public: + using Ptr = std::shared_ptr; + Sha512Hash() = default; + virtual ~Sha512Hash() = default; + + // the hashBytes length of given hash-algorithm + size_t hashLen() const override { return crypto_hash_sha512_BYTES; } + // the implementation of the hash-algorithm + ppc::protocol::HashImplName type() const override + { + return ppc::protocol::HashImplName::SHA512; + } + + // calculate-hash + bcos::bytes hash(bcos::bytesConstRef _input) const override + { + bcos::bytes result(crypto_hash_sha512_BYTES); + auto ret = crypto_hash_sha512(result.data(), _input.data(), _input.size()); + if (ret) + { + BOOST_THROW_EXCEPTION(HashException() << bcos::errinfo_comment( + "crypto_hash_sha512 error: " + std::to_string(ret))); + } + return result; + } + + // init the hash-state + HashState::Ptr init() const override + { + auto hashState = std::make_shared(); + auto ret = crypto_hash_sha512_init((crypto_hash_sha512_state*)hashState->state()); + if (ret) + { + BOOST_THROW_EXCEPTION(HashException() << bcos::errinfo_comment( + "crypto_hash_sha512_init error: " + std::to_string(ret))); + } + return hashState; + } + + // update new message into the given hash-state + void update(HashState::Ptr _state, bcos::bytesConstRef _data) const override + { + auto ret = crypto_hash_sha512_update( + (crypto_hash_sha512_state*)_state->state(), _data.data(), _data.size()); + if (ret) + { + BOOST_THROW_EXCEPTION(HashException() << bcos::errinfo_comment( + "crypto_hash_sha512_state error: " + std::to_string(ret))); + } + } + + // obtain the hash-result from the given hash-state + bcos::bytes final(HashState::Ptr _state) const override + { + bcos::bytes result(crypto_hash_sha512_BYTES); + auto ret = + crypto_hash_sha512_final((crypto_hash_sha512_state*)_state->state(), result.data()); + if (ret) + { + BOOST_THROW_EXCEPTION(HashException() << bcos::errinfo_comment( + "crypto_hash_sha512_final error: " + std::to_string(ret))); + } + return result; + } +}; +} // namespace ppc::crypto \ No newline at end of file diff --git a/cpp/wedpr-crypto/ppc-crypto-core/src/ore/FastOre.cpp b/cpp/wedpr-crypto/ppc-crypto-core/src/ore/FastOre.cpp new file mode 100644 index 00000000..c62d63f2 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-crypto-core/src/ore/FastOre.cpp @@ -0,0 +1,230 @@ +/** + * Copyright (C) 2022 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 FastOre.cpp + * @author: shawnhe + * @date 2023-08-18 + */ +#include "FastOre.h" +#include "../Common.h" + +using namespace ppc; +using namespace ppc::crypto; + +// cipher encoded with hex +std::string FastOre::encrypt4String( + bcos::bytesConstRef const& _sk, const std::string& _plaintext) const +{ + bcos::bytes cipher(estimatedCipherSize(_plaintext.size(), false)); + OutputBuffer cipherBuffer{cipher.data(), cipher.size()}; + encrypt4String( + &cipherBuffer, _sk, bcos::bytesConstRef((bcos::byte*)_plaintext.data(), _plaintext.size())); + return bcos::toHex(bcos::bytes{cipher.begin(), cipher.end()}); +} + +void FastOre::encrypt4String(OutputBuffer* _cipher, bcos::bytesConstRef const& _sk, + bcos::bytesConstRef const& _plaintext) const +{ + if (_plaintext.size() == 0) + { + return; + } + auto estimatedSize = estimatedCipherSize(_plaintext.size(), false); + if (_cipher->len < estimatedSize) + { + BOOST_THROW_EXCEPTION( + FastOreException() << bcos::errinfo_comment( + "FastOre4String encrypt failed for unenough cipher buffer, expect at least " + + std::to_string(estimatedSize))); + } + + // enc the first byte + bcos::bytes cipher0(CIPHER_BLOCK_SIZE); + auto tempCipher0 = encWithTruncation( + _sk, bcos::bytesConstRef((const unsigned char*)cipher0.data(), CIPHER_BLOCK_SIZE)); + uint16_t sum0 = (uint8_t)tempCipher0[1] + (uint8_t)_plaintext[0]; + _cipher->data[0] = (uint8_t)tempCipher0[0] + sum0 / 256; + _cipher->data[1] = sum0 % 256; + + // enc the other bytes + for (uint64_t i = 1; i < _plaintext.size(); i++) + { + auto tempCipher = encWithTruncation( + _sk, bcos::bytesConstRef((const unsigned char*)_cipher->data, i * CIPHER_BLOCK_SIZE)); + uint16_t sum = (uint8_t)tempCipher[1] + (uint8_t)_plaintext[i]; + _cipher->data[i * CIPHER_BLOCK_SIZE] = (uint8_t)tempCipher[0] + sum / 256; + _cipher->data[i * CIPHER_BLOCK_SIZE + 1] = sum % 256; + } +} + +// cipher encoded with hex +std::string FastOre::decrypt4String( + bcos::bytesConstRef const& _key, const std::string& _ciphertext) const +{ + bcos::bytes cipher = bcos::fromHex(_ciphertext); + std::string plain; + plain.resize(estimatedPlainSize(_ciphertext.size(), true)); + OutputBuffer resultBuffer{(bcos::byte*)plain.data(), plain.size()}; + decrypt4String(&resultBuffer, _key, bcos::ref(cipher)); + + return plain; +} + +void FastOre::decrypt4String( + OutputBuffer* _plain, bcos::bytesConstRef const& _sk, bcos::bytesConstRef const& _cipher) const +{ + if (_cipher.size() < CIPHER_BLOCK_SIZE) + { + BOOST_THROW_EXCEPTION( + FastOreException() << bcos::errinfo_comment( + "FastOre4String decrypt failed for invalid cipher, min cipher size is: " + + std::to_string(CIPHER_BLOCK_SIZE))); + } + auto blockSize = estimatedPlainSize(_cipher.size(), false); + if (_plain->len < blockSize) + { + BOOST_THROW_EXCEPTION( + FastOreException() << bcos::errinfo_comment( + "FastOre4String decrypt failed for unenough plain buffer, expect at least: " + + std::to_string(blockSize))); + } + + // dec the first byte + bcos::bytes cipher0(CIPHER_BLOCK_SIZE); + auto tempCipher0 = encWithTruncation( + _sk, bcos::bytesConstRef((const unsigned char*)cipher0.data(), CIPHER_BLOCK_SIZE)); + int diff0 = (uint8_t)_cipher[1] - (uint8_t)tempCipher0[1]; + if (diff0 < 0) + { + diff0 += 256; + } + _plain->data[0] = diff0; + + // dec the other bytes + for (uint64_t i = 1; i < blockSize; i++) + { + auto tempCipher = encWithTruncation( + _sk, bcos::bytesConstRef((const unsigned char*)_cipher.data(), i * CIPHER_BLOCK_SIZE)); + int diff = (uint8_t)_cipher[i * CIPHER_BLOCK_SIZE + 1] - (uint8_t)tempCipher[1]; + if (diff < 0) + { + diff += 256; + } + _plain->data[i] = diff; + } +} + +// cipher encoded with base64 +std::string FastOre::encrypt4Integer(bcos::bytesConstRef const& _sk, const int64_t& _plain) const +{ + bcos::bytes cipher(estimatedCipherSize(sizeof(_plain), false)); + OutputBuffer cipherBuffer{cipher.data(), cipher.size()}; + encrypt4Integer(&cipherBuffer, _sk, _plain); + return bcos::toHex(bcos::bytes{cipher.begin(), cipher.end()}); +} + +void FastOre::encrypt4Integer( + OutputBuffer* _cipher, bcos::bytesConstRef const& _sk, const int64_t& _plain) const +{ + int64_t plain = 0; + OutputBuffer plainB{(bcos::byte*)&plain, sizeof(plain)}; + formatNumberPlain(&plainB, _plain); + encrypt4String(_cipher, _sk, bcos::bytesConstRef((bcos::byte*)plainB.data, plainB.len)); +} + +// cipher encoded with base64 +int64_t FastOre::decrypt4Integer(bcos::bytesConstRef const& _key, const std::string& _cipher) const +{ + bcos::bytes cipher = bcos::fromHex(_cipher); + int64_t plain = 0; + decrypt4Integer(&plain, _key, bcos::ref(cipher)); + return plain; +} + +void FastOre::decrypt4Integer( + int64_t* _plain, bcos::bytesConstRef const& _sk, bcos::bytesConstRef const& cipher) const +{ + int64_t plain = 0; + OutputBuffer resultBuffer{(bcos::byte*)&plain, sizeof(plain)}; + decrypt4String(&resultBuffer, _sk, cipher); + *_plain = recoverNumberPlain(resultBuffer); +} + +// cipher encoded with hex +std::string FastOre::encrypt4Float(bcos::bytesConstRef const& _sk, const float50& _plain) const +{ + bcos::bytes cipher(estimatedFloatCipherSize(_plain.str().size(), false)); + OutputBuffer cipherBuffer{cipher.data(), cipher.size()}; + encrypt4Float(&cipherBuffer, _sk, _plain); + return bcos::toHex(bcos::bytes{cipher.begin(), cipher.begin() + cipherBuffer.len}); +} + +void FastOre::encrypt4Float( + OutputBuffer* _cipher, bcos::bytesConstRef const& _sk, const float50& _plain) const +{ + OreFloatingNumber ofn(_plain); + encrypt4String( + _cipher, _sk, bcos::bytesConstRef((bcos::byte*)&ofn.integerPart, sizeof(ofn.integerPart))); + + if (!ofn.decimalPart.empty()) + { + OutputBuffer decimalCipherBuffer{ + _cipher->data + sizeof(ofn.integerPart) * CIPHER_BLOCK_SIZE, + ofn.decimalPart.size() * CIPHER_BLOCK_SIZE}; + encrypt4String(&decimalCipherBuffer, _sk, + bcos::bytesConstRef((bcos::byte*)ofn.decimalPart.data(), ofn.decimalPart.size())); + } + _cipher->len = (sizeof(ofn.integerPart) + ofn.decimalPart.size()) * CIPHER_BLOCK_SIZE; +} + +// cipher encoded with base64 +float50 FastOre::decrypt4Float(bcos::bytesConstRef const& _sk, const std::string& _cipher) const +{ + bcos::bytes cipher = bcos::fromHex(_cipher); + return decrypt4Float(_sk, bcos::ref(cipher)); +} + +float50 FastOre::decrypt4Float( + bcos::bytesConstRef const& _sk, bcos::bytesConstRef const& _cipher) const +{ + OreFloatingNumber ofn; + OutputBuffer integerOut{(bcos::byte*)&ofn.integerPart, sizeof(ofn.integerPart)}; + auto integerCipherSize = sizeof(ofn.integerPart) * CIPHER_BLOCK_SIZE; + decrypt4String(&integerOut, _sk, bcos::bytesConstRef(_cipher.data(), integerCipherSize)); + + if (_cipher.size() > integerCipherSize) + { + auto decimalSize = (_cipher.size() - integerCipherSize) / CIPHER_BLOCK_SIZE; + ofn.decimalPart.resize(decimalSize); + OutputBuffer decimalOut{(bcos::byte*)ofn.decimalPart.data(), decimalSize}; + decrypt4String(&decimalOut, _sk, + bcos::bytesConstRef( + _cipher.data() + integerCipherSize, decimalSize * CIPHER_BLOCK_SIZE)); + } + return ofn.value(); +} + +int FastOre::compare(const std::string& _ciphertext0, const std::string& _ciphertext1) const +{ + return _ciphertext0.compare(_ciphertext1); +} + +int FastOre::compare(InputBuffer const* c1, InputBuffer const* c2) const +{ + std::string str1{c1->data, c1->data + c1->len}; + std::string str2{c2->data, c2->data + c2->len}; + + return str1.compare(str2); +} diff --git a/cpp/wedpr-crypto/ppc-crypto-core/src/ore/FastOre.h b/cpp/wedpr-crypto/ppc-crypto-core/src/ore/FastOre.h new file mode 100644 index 00000000..5ef10a0f --- /dev/null +++ b/cpp/wedpr-crypto/ppc-crypto-core/src/ore/FastOre.h @@ -0,0 +1,177 @@ +/** + * Copyright (C) 2022 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 FastOre.h + * @author: shawnhe + * @date 2023-08-18 + */ + +#pragma once + +#include "ppc-crypto-core/src/sym-crypto/OpenSSLAES.h" +#include "ppc-framework/crypto/Ore.h" +#include "ppc-framework/libwrapper/OreFloatingNumber.h" + +#define CIPHER_BLOCK_SIZE 2 + +namespace ppc::crypto +{ +class FastOre : public Ore +{ +public: + using Ptr = std::shared_ptr; + FastOre() { m_symCrypto = std::make_shared(OpenSSLAES::AESType::AES128); } + ~FastOre() override = default; + + // cipher encoded with base64 + void encrypt4String(OutputBuffer* _cipher, bcos::bytesConstRef const& _sk, + bcos::bytesConstRef const& _plaintext) const override; + std::string encrypt4String( + bcos::bytesConstRef const& _key, const std::string& _plaintext) const override; + + // cipher encoded with base64 + std::string decrypt4String( + bcos::bytesConstRef const& _key, const std::string& _ciphertext) const override; + void decrypt4String(OutputBuffer* plain, bcos::bytesConstRef const& _sk, + bcos::bytesConstRef const& cipher) const override; + + // cipher encoded with base64 + std::string encrypt4Integer( + bcos::bytesConstRef const& _sk, const int64_t& _plain) const override; + void encrypt4Integer(OutputBuffer* _cipher, bcos::bytesConstRef const& _sk, + const int64_t& _plain) const override; + + // cipher encoded with base64 + int64_t decrypt4Integer( + bcos::bytesConstRef const& _sk, const std::string& _cipher) const override; + void decrypt4Integer(int64_t* _plain, bcos::bytesConstRef const& _sk, + bcos::bytesConstRef const& _cipher) const override; + + // cipher encoded with base64 + std::string encrypt4Float(bcos::bytesConstRef const& _sk, const float50& _plain) const override; + void encrypt4Float(OutputBuffer* _cipher, bcos::bytesConstRef const& _sk, + const float50& _plain) const override; + + // cipher encoded with base64 + float50 decrypt4Float( + bcos::bytesConstRef const& _sk, const std::string& _cipher) const override; + float50 decrypt4Float( + bcos::bytesConstRef const& _sk, bcos::bytesConstRef const& _cipher) const override; + + int compare(const std::string& _ciphertext0, const std::string& _ciphertext1) const override; + int compare(InputBuffer const* c1, InputBuffer const* c2) const override; + + int keyBytes() const override { return m_symCrypto->keyBytes(SymCrypto::OperationMode::CBC); } + + bcos::bytes generateKey() const override + { + return m_symCrypto->generateKey(SymCrypto::OperationMode::CBC); + } + + void generateKey(OutputBuffer* sk) const override + { + return m_symCrypto->generateKey(sk, SymCrypto::OperationMode::CBC); + } + + + uint64_t estimatedCipherSize(uint64_t _plainSize, bool hex) const + { + if (!hex) + { + return _plainSize * CIPHER_BLOCK_SIZE; + } + return _plainSize * CIPHER_BLOCK_SIZE * 2; + } + + uint64_t estimatedFloatCipherSize(uint64_t _plainSize, bool hex) const + { + if (!hex) + { + return (sizeof(int64_t) + _plainSize) * CIPHER_BLOCK_SIZE; + } + return (sizeof(int64_t) + _plainSize) * CIPHER_BLOCK_SIZE * 2; + } + + uint64_t estimatedPlainSize(uint64_t cipherSize, bool hex) const + { + uint64_t plainSize = 0; + if (!hex) + { + plainSize = cipherSize / CIPHER_BLOCK_SIZE; + } + else + { + plainSize = cipherSize / CIPHER_BLOCK_SIZE / 2; + } + return plainSize; + } + + static void formatNumberPlain(OutputBuffer* _buffer, const int64_t& _plain) + { + // Note: Add brackets here to adapt to windows compilation + if (_plain > (std::numeric_limits::max)() / 2 || + _plain <= (std::numeric_limits::min)() / 2) + { + BOOST_THROW_EXCEPTION( + FastOreException() << bcos::errinfo_comment( + "plain is too large or too small, must be in range (-2^62, 2^62)")); + } + + int64_t plain = _plain + (std::numeric_limits::max)() / 2; + + for (int i = sizeof(plain) - 1; i >= 0; --i) + { + _buffer->data[i] = static_cast((plain >> (8 * (7 - i))) & 0xFF); + } + _buffer->len = sizeof(plain); + } + + static int64_t recoverNumberPlain(const OutputBuffer& outputBuffer) + { + int64_t result = 0; + + for (uint64_t i = 0; i < outputBuffer.len; ++i) + { + result = (result << 8) | outputBuffer.data[i]; + } + + return result - (std::numeric_limits::max)() / 2; + } + +private: + // keep only the first two bytes + bcos::bytes encWithTruncation( + bcos::bytesConstRef const& _key, bcos::bytesConstRef const& _plaintext) const + { + bcos::bytes iv(0); + bcos::bytes cipher = + m_symCrypto->encrypt(SymCrypto::OperationMode::CBC, _key, bcos::ref(iv), _plaintext); + uint64_t size = cipher.size(); + if (cipher[size - 2] == 0xFF) + { + cipher[size - 2] = 0xFE; + } + + bcos::bytes result(2); + result[0] = cipher[size - 2]; + result[1] = cipher[size - 1]; + return result; + } + +private: + SymCrypto::Ptr m_symCrypto; +}; + +} // namespace ppc::crypto diff --git a/cpp/wedpr-crypto/ppc-crypto-core/src/sym-crypto/OpenSSL3DES.cpp b/cpp/wedpr-crypto/ppc-crypto-core/src/sym-crypto/OpenSSL3DES.cpp new file mode 100644 index 00000000..ea73cf47 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-crypto-core/src/sym-crypto/OpenSSL3DES.cpp @@ -0,0 +1,42 @@ +/** + * Copyright (C) 2022 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 OpenSSL3DES.cpp + * @author: shawnhe + * @date 2023-08-16 + */ + +#include "OpenSSL3DES.h" + +using namespace ppc::crypto; +using namespace ppc::protocol; + +EvpCipherPtr OpenSSL3DES::createCipherMeth(OperationMode _mode) const +{ + switch (_mode) + { + case SymCrypto::OperationMode::ECB: + return EvpCipherPtr(EVP_des_ede3_ecb(), EvpCipherDeleter()); + case SymCrypto::OperationMode::CBC: + return EvpCipherPtr(EVP_des_ede3_cbc(), EvpCipherDeleter()); + case SymCrypto::OperationMode::CFB: + return EvpCipherPtr(EVP_des_ede3_cfb(), EvpCipherDeleter()); + case SymCrypto::OperationMode::OFB: + return EvpCipherPtr(EVP_des_ede3_ofb(), EvpCipherDeleter()); + default: + BOOST_THROW_EXCEPTION(SymCryptoException() << bcos::errinfo_comment( + "unsupported crypto mode: " + std::to_string(int(_mode)))); + } +} \ No newline at end of file diff --git a/cpp/wedpr-crypto/ppc-crypto-core/src/sym-crypto/OpenSSL3DES.h b/cpp/wedpr-crypto/ppc-crypto-core/src/sym-crypto/OpenSSL3DES.h new file mode 100644 index 00000000..7c0d355f --- /dev/null +++ b/cpp/wedpr-crypto/ppc-crypto-core/src/sym-crypto/OpenSSL3DES.h @@ -0,0 +1,50 @@ +/** + * Copyright (C) 2022 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 OpenSSL3DES.h + * @author: shawnhe + * @date 2023-08-16 + */ + +#pragma once + +#include "../Common.h" +#include "OpenSSLCipher.h" + +namespace ppc::crypto +{ +class OpenSSL3DES : public OpenSSLCipher +{ +public: + using Ptr = std::shared_ptr; + + OpenSSL3DES(protocol::DataPaddingType _padding = protocol::DataPaddingType::PKCS7) + : OpenSSLCipher(_padding) + { + // the key size: 168 bits; the block size: 64 bits + m_blockSize = 8; + } + ~OpenSSL3DES() override = default; + + protocol::SymCryptoImplName type() const override + { + return protocol::SymCryptoImplName::DES_EDE3; + } + +public: + EvpCipherPtr createCipherMeth(OperationMode _mode) const override; +}; + +} // namespace ppc::crypto diff --git a/cpp/wedpr-crypto/ppc-crypto-core/src/sym-crypto/OpenSSLAES.cpp b/cpp/wedpr-crypto/ppc-crypto-core/src/sym-crypto/OpenSSLAES.cpp new file mode 100644 index 00000000..71d63f69 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-crypto-core/src/sym-crypto/OpenSSLAES.cpp @@ -0,0 +1,89 @@ +/** + * Copyright (C) 2022 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 OpenSSLAES.cpp + * @author: shawnhe + * @date 2022-11-29 + */ + +#include "OpenSSLAES.h" + +using namespace ppc::crypto; +using namespace ppc::protocol; +EvpCipherPtr OpenSSLAES::createCipherMeth(OperationMode _mode) const +{ + if (m_aesType == AESType::AES128) + { + switch (_mode) + { + case SymCrypto::OperationMode::ECB: + return EvpCipherPtr(EVP_aes_128_ecb(), EvpCipherDeleter()); + case SymCrypto::OperationMode::CBC: + return EvpCipherPtr(EVP_aes_128_cbc(), EvpCipherDeleter()); + case SymCrypto::OperationMode::CFB: + return EvpCipherPtr(EVP_aes_128_cfb(), EvpCipherDeleter()); + case SymCrypto::OperationMode::OFB: + return EvpCipherPtr(EVP_aes_128_ofb(), EvpCipherDeleter()); + case SymCrypto::OperationMode::CTR: + return EvpCipherPtr(EVP_aes_128_ctr(), EvpCipherDeleter()); + default: + BOOST_THROW_EXCEPTION( + SymCryptoException() << bcos::errinfo_comment( + "unsupported mode for AES128: " + std::to_string(int(_mode)))); + } + } + else if (m_aesType == AESType::AES192) + { + switch (_mode) + { + case SymCrypto::OperationMode::ECB: + return EvpCipherPtr(EVP_aes_192_ecb(), EvpCipherDeleter()); + case SymCrypto::OperationMode::CBC: + return EvpCipherPtr(EVP_aes_192_cbc(), EvpCipherDeleter()); + case SymCrypto::OperationMode::CFB: + return EvpCipherPtr(EVP_aes_192_cfb(), EvpCipherDeleter()); + case SymCrypto::OperationMode::OFB: + return EvpCipherPtr(EVP_aes_192_ofb(), EvpCipherDeleter()); + case SymCrypto::OperationMode::CTR: + return EvpCipherPtr(EVP_aes_192_ctr(), EvpCipherDeleter()); + default: + BOOST_THROW_EXCEPTION( + SymCryptoException() << bcos::errinfo_comment( + "unsupported mode for AES192: " + std::to_string(int(_mode)))); + } + } + else if (m_aesType == AESType::AES256) + { + switch (_mode) + { + case SymCrypto::OperationMode::ECB: + return EvpCipherPtr(EVP_aes_256_ecb(), EvpCipherDeleter()); + case SymCrypto::OperationMode::CBC: + return EvpCipherPtr(EVP_aes_256_cbc(), EvpCipherDeleter()); + case SymCrypto::OperationMode::CFB: + return EvpCipherPtr(EVP_aes_256_cfb(), EvpCipherDeleter()); + case SymCrypto::OperationMode::OFB: + return EvpCipherPtr(EVP_aes_256_ofb(), EvpCipherDeleter()); + case SymCrypto::OperationMode::CTR: + return EvpCipherPtr(EVP_aes_256_ctr(), EvpCipherDeleter()); + default: + BOOST_THROW_EXCEPTION( + SymCryptoException() << bcos::errinfo_comment( + "unsupported mode for AES256: " + std::to_string(int(_mode)))); + } + } + BOOST_THROW_EXCEPTION(SymCryptoException() << bcos::errinfo_comment( + "Unsupported aes-algorithm: " + std::to_string((int)m_aesType))); +} diff --git a/cpp/wedpr-crypto/ppc-crypto-core/src/sym-crypto/OpenSSLAES.h b/cpp/wedpr-crypto/ppc-crypto-core/src/sym-crypto/OpenSSLAES.h new file mode 100644 index 00000000..17b54bd2 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-crypto-core/src/sym-crypto/OpenSSLAES.h @@ -0,0 +1,59 @@ +/** + * Copyright (C) 2022 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 OpenSSLAES.h + * @author: shawnhe + * @date 2022-11-29 + */ + +#pragma once + +#include "../Common.h" +#include "OpenSSLCipher.h" + +namespace ppc::crypto +{ +class OpenSSLAES : public OpenSSLCipher +{ +public: + using Ptr = std::shared_ptr; + + enum class AESType : int + { + AES128 = 16, + AES192 = 24, + AES256 = 32, + }; + + OpenSSLAES() = delete; + + ~OpenSSLAES() override = default; + + OpenSSLAES( + AESType _aesType, protocol::DataPaddingType _padding = protocol::DataPaddingType::PKCS7) + : OpenSSLCipher(_padding), m_aesType(_aesType) + {} + + protocol::SymCryptoImplName type() const override { return protocol::SymCryptoImplName::AES; } + + AESType aesType() { return m_aesType; } + + EvpCipherPtr createCipherMeth(OperationMode _mode) const override; + +private: + AESType m_aesType; +}; + +} // namespace ppc::crypto diff --git a/cpp/wedpr-crypto/ppc-crypto-core/src/sym-crypto/OpenSSLCipher.h b/cpp/wedpr-crypto/ppc-crypto-core/src/sym-crypto/OpenSSLCipher.h new file mode 100644 index 00000000..84e68590 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-crypto-core/src/sym-crypto/OpenSSLCipher.h @@ -0,0 +1,218 @@ +/** + * Copyright (C) 2022 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 OpenSSLCipher.h + * @author: shawnhe + * @date 2023-08-17 + */ + +#pragma once + +#include "../Common.h" +#include "ppc-framework/crypto/SymCrypto.h" +#include "ppc-framework/libwrapper/BigNum.h" +#include + +namespace ppc::crypto +{ +struct EvpCipherDeleter +{ +public: + void operator()(EVP_CIPHER const* _cipher) { (void)_cipher; } +}; +using EvpCipherPtr = std::shared_ptr; + +struct EvpCipherCtxDeleter +{ +public: + void operator()(EVP_CIPHER_CTX* _ctx) { EVP_CIPHER_CTX_free(_ctx); } +}; +using EvpCipherCtxPtr = std::shared_ptr; + +class OpenSSLCipher : public SymCrypto +{ +public: + OpenSSLCipher() = delete; + + ~OpenSSLCipher() override = default; + + OpenSSLCipher(protocol::DataPaddingType _padding = protocol::DataPaddingType::PKCS7) + : SymCrypto() + { + m_padding = _padding; + if (int(m_padding) < 0 || int(m_padding) > EVP_PADDING_ZERO) + { + BOOST_THROW_EXCEPTION(SymCryptoException() << bcos::errinfo_comment( + "undefined padding: " + std::to_string(int(_padding)))); + } + } + +private: + virtual EvpCipherPtr createCipherMeth(OperationMode _mode) const = 0; + + virtual void initCipherCtx(OperationMode _mode, bcos::bytesConstRef const& _sk, + bcos::bytesConstRef const& _iv, EVP_CIPHER_CTX* _ctx, int _enc) const + { + auto cipher = createCipherMeth(_mode); + auto keyLength = EVP_CIPHER_key_length(cipher.get()); + auto key = _sk.toBytes(); + key.resize(keyLength); + auto iv = _iv.toBytes(); + iv.resize(m_blockSize); + if (_mode == SymCrypto::OperationMode::ECB) + { + if (1 != EVP_CipherInit_ex(_ctx, cipher.get(), nullptr, key.data(), nullptr, _enc)) + { + BOOST_THROW_EXCEPTION(SymCryptoException() << bcos::errinfo_comment( + "initCipherCtx: EVP_CipherInit_ex failed: " + + std::string(ERR_error_string(ERR_get_error(), NULL)))); + } + return; + } + + if (1 != EVP_CipherInit_ex(_ctx, cipher.get(), nullptr, key.data(), iv.data(), _enc)) + { + BOOST_THROW_EXCEPTION(SymCryptoException() << bcos::errinfo_comment( + "initCipherCtx: EVP_CipherInit_ex failed: " + + std::string(ERR_error_string(ERR_get_error(), NULL)))); + } + } + + virtual EvpCipherCtxPtr createCipherCtx() const + { + return EvpCipherCtxPtr(EVP_CIPHER_CTX_new(), EvpCipherCtxDeleter()); + } + +public: + protocol::DataPaddingType padding() { return m_padding; } + + void encrypt(OutputBuffer* _cipher, OperationMode _mode, bcos::bytesConstRef const& _sk, + bcos::bytesConstRef const& _iv, bcos::bytesConstRef const& _plaintext) const override + { + auto minCipherSize = _plaintext.size() + m_blockSize; + if (_cipher->len < minCipherSize) + { + BOOST_THROW_EXCEPTION(SymCryptoException() << bcos::errinfo_comment( + "The reserved cipher buffer is not enough, at least: " + + std::to_string(minCipherSize))); + } + auto ctx = createCipherCtx(); + initCipherCtx(_mode, _sk, _iv, ctx.get(), 1); + + if (_mode == SymCrypto::OperationMode::ECB || _mode == SymCrypto::OperationMode::CBC) + { + EVP_CIPHER_CTX_set_padding(ctx.get(), int(m_padding)); + } + EVP_CIPHER_CTX_set_padding(ctx.get(), int(m_padding)); + int outLen; + if (1 != EVP_CipherUpdate( + ctx.get(), _cipher->data, &outLen, _plaintext.data(), _plaintext.size())) + { + BOOST_THROW_EXCEPTION(SymCryptoException() << bcos::errinfo_comment( + "encrypt failed for EVP_CipherUpdate exception: " + + std::string(ERR_error_string(ERR_get_error(), NULL)))); + } + + int outLenFinal = 0; + if (1 != EVP_CipherFinal_ex(ctx.get(), _cipher->data + outLen, &outLenFinal)) + { + BOOST_THROW_EXCEPTION(SymCryptoException() << bcos::errinfo_comment( + "encrypt failed for EVP_CipherFinal exception: " + + std::string(ERR_error_string(ERR_get_error(), NULL)))); + } + _cipher->len = outLen + outLenFinal; + } + + bcos::bytes encrypt(OperationMode _mode, bcos::bytesConstRef const& _sk, + bcos::bytesConstRef const& _iv, bcos::bytesConstRef const& _plaintext) const override + { + bcos::bytes cipherResult(_plaintext.size() + blockSize()); + OutputBuffer cipherBuffer{cipherResult.data(), cipherResult.size()}; + encrypt(&cipherBuffer, _mode, _sk, _iv, _plaintext); + cipherResult.resize(cipherBuffer.len); + return cipherResult; + } + + void decrypt(OutputBuffer* plain, OperationMode _mode, bcos::bytesConstRef const& _sk, + bcos::bytesConstRef const& _iv, bcos::bytesConstRef const& _ciphertext) const override + { + auto minPlainDataSize = _ciphertext.size() + m_blockSize; + if (plain->len < minPlainDataSize) + { + BOOST_THROW_EXCEPTION(SymCryptoException() << bcos::errinfo_comment( + "The reserved plainData buffer is not enough, at least: " + + std::to_string(minPlainDataSize))); + } + auto ctx = createCipherCtx(); + initCipherCtx(_mode, _sk, _iv, ctx.get(), 0); + if (_mode == SymCrypto::OperationMode::ECB || _mode == SymCrypto::OperationMode::CBC) + { + EVP_CIPHER_CTX_set_padding(ctx.get(), int(m_padding)); + } + EVP_CIPHER_CTX_set_padding(ctx.get(), int(m_padding)); + + int outLen; + if (1 != EVP_CipherUpdate( + ctx.get(), plain->data, &outLen, _ciphertext.data(), _ciphertext.size())) + { + BOOST_THROW_EXCEPTION(SymCryptoException() << bcos::errinfo_comment( + "decrypt failed for EVP_CipherUpdate exception: " + + std::string(ERR_error_string(ERR_get_error(), NULL)))); + } + + int outLenFinal = 0; + if (1 != EVP_CipherFinal_ex(ctx.get(), plain->data + outLen, &outLenFinal)) + { + BOOST_THROW_EXCEPTION(SymCryptoException() << bcos::errinfo_comment( + "decrypt failed for EVP_CipherFinal exception: " + + std::string(ERR_error_string(ERR_get_error(), NULL)))); + } + plain->len = outLen + outLenFinal; + } + + bcos::bytes decrypt(OperationMode _mode, bcos::bytesConstRef const& _sk, + bcos::bytesConstRef const& _iv, bcos::bytesConstRef const& _ciphertext) const override + { + bcos::bytes result(_ciphertext.size() + m_blockSize, 0); + OutputBuffer resultBuffer{result.data(), result.size()}; + decrypt(&resultBuffer, _mode, _sk, _iv, _ciphertext); + result.resize(resultBuffer.len); + return result; + } + + bcos::bytes generateKey(OperationMode _mode) const override + { + auto key = generateRand(keyBytes(_mode) * 8); + bcos::bytes keyBytes; + key.toBytes(keyBytes, false); + return keyBytes; + } + + void generateKey(OutputBuffer* _key, OperationMode _mode) const override + { + auto key = generateRand(keyBytes(_mode) * 8); + key.toOutputBuffer(_key, false); + } + + virtual unsigned int keyBytes(OperationMode _mode) const override + { + auto cipher = createCipherMeth(_mode); + return EVP_CIPHER_key_length(cipher.get()); + } + +protected: + protocol::DataPaddingType m_padding{protocol::DataPaddingType::PKCS7}; +}; +} // namespace ppc::crypto diff --git a/cpp/wedpr-crypto/ppc-crypto-core/src/sym-crypto/OpenSSLSM4.cpp b/cpp/wedpr-crypto/ppc-crypto-core/src/sym-crypto/OpenSSLSM4.cpp new file mode 100644 index 00000000..aa9452d7 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-crypto-core/src/sym-crypto/OpenSSLSM4.cpp @@ -0,0 +1,44 @@ +/** + * Copyright (C) 2022 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 OpenSSLSM4.cpp + * @author: shawnhe + * @date 2022-11-29 + */ + +#include "OpenSSLSM4.h" + +using namespace ppc::crypto; +using namespace ppc::protocol; + +EvpCipherPtr OpenSSLSM4::createCipherMeth(OperationMode _mode) const +{ + switch (_mode) + { + case SymCrypto::OperationMode::ECB: + return EvpCipherPtr(EVP_sm4_ecb(), EvpCipherDeleter()); + case SymCrypto::OperationMode::CBC: + return EvpCipherPtr(EVP_sm4_cbc(), EvpCipherDeleter()); + case SymCrypto::OperationMode::CFB: + return EvpCipherPtr(EVP_sm4_cfb(), EvpCipherDeleter()); + case SymCrypto::OperationMode::OFB: + return EvpCipherPtr(EVP_sm4_ofb(), EvpCipherDeleter()); + case SymCrypto::OperationMode::CTR: + return EvpCipherPtr(EVP_sm4_ctr(), EvpCipherDeleter()); + default: + BOOST_THROW_EXCEPTION(SymCryptoException() << bcos::errinfo_comment( + "unsupported crypto type: " + std::to_string(int(_mode)))); + } +} diff --git a/cpp/wedpr-crypto/ppc-crypto-core/src/sym-crypto/OpenSSLSM4.h b/cpp/wedpr-crypto/ppc-crypto-core/src/sym-crypto/OpenSSLSM4.h new file mode 100644 index 00000000..e04836bb --- /dev/null +++ b/cpp/wedpr-crypto/ppc-crypto-core/src/sym-crypto/OpenSSLSM4.h @@ -0,0 +1,44 @@ +/** + * Copyright (C) 2022 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 OpenSSLSM4.h + * @author: shawnhe + * @date 2022-11-29 + */ + + +#pragma once + +#include "../Common.h" +#include "OpenSSLCipher.h" + +namespace ppc::crypto +{ +class OpenSSLSM4 : public OpenSSLCipher +{ +public: + using Ptr = std::shared_ptr; + OpenSSLSM4(protocol::DataPaddingType _padding = protocol::DataPaddingType::PKCS7) + : OpenSSLCipher(_padding) + {} + + ~OpenSSLSM4() override = default; + protocol::SymCryptoImplName type() const override { return protocol::SymCryptoImplName::SM4; } + +private: + EvpCipherPtr createCipherMeth(OperationMode _mode) const override; +}; + +} // namespace ppc::crypto diff --git a/cpp/wedpr-crypto/ppc-crypto-core/src/tools/BitVector.cpp b/cpp/wedpr-crypto/ppc-crypto-core/src/tools/BitVector.cpp new file mode 100644 index 00000000..6f21fcf2 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-crypto-core/src/tools/BitVector.cpp @@ -0,0 +1,88 @@ +/** + * Copyright (C) 2022 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 BitVector.cpp + * @author: shawnhe + * @date 2022-12-5 + */ + +#include "BitVector.h" +#include + +using namespace ppc::crypto; + +void BitVector::randomize(PRNG::Ptr _prng, uint32_t _bytesLen) +{ + m_data.clear(); + auto randomBytes = _prng->generate(_bytesLen); + append(randomBytes); +} + +void BitVector::append(const bcos::bytes& _data) +{ + int start = _data.size() - 1; + for (int i = start; i >= 0; --i) + { + auto bits = std::bitset<8>(_data[i]); + for (int j = 0; j < 8; ++j) + { + m_data.push_back(bits[j]); + } + } +} + +void BitVector::append(const std::string& _binary) +{ + auto newBits = boost::dynamic_bitset<>(_binary); + for (uint32_t i = 0; i < newBits.size(); ++i) + { + m_data.push_back(newBits[i]); + } +} + +std::string BitVector::toString() +{ + std::string result; + boost::to_string(m_data, result); + return result; +} + +bcos::bytes BitVector::toBytes() +{ + if (m_data.size() % 8) + { + BOOST_THROW_EXCEPTION( + BitVectorException() << bcos::errinfo_comment("the size must be divisible by 8")); + } + + uint32_t len = m_data.size() / 8; + bcos::bytes result(len); + + for (uint32_t i = 0; i < len; ++i) + { + bcos::byte b = 0; + b |= m_data[i * 8 + 0] << 0; + b |= m_data[i * 8 + 1] << 1; + b |= m_data[i * 8 + 2] << 2; + b |= m_data[i * 8 + 3] << 3; + b |= m_data[i * 8 + 4] << 4; + b |= m_data[i * 8 + 5] << 5; + b |= m_data[i * 8 + 6] << 6; + b |= m_data[i * 8 + 7] << 7; + result[len - 1 - i] = b; + } + + return result; +} \ No newline at end of file diff --git a/cpp/wedpr-crypto/ppc-crypto-core/src/tools/BitVector.h b/cpp/wedpr-crypto/ppc-crypto-core/src/tools/BitVector.h new file mode 100644 index 00000000..7cbcc93c --- /dev/null +++ b/cpp/wedpr-crypto/ppc-crypto-core/src/tools/BitVector.h @@ -0,0 +1,83 @@ +/** + * Copyright (C) 2022 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 BitVector.h + * @author: shawnhe + * @date 2022-12-5 + */ + + +#include "../Common.h" +#include "ppc-framework/crypto/PRNG.h" +#include +#include + +#pragma once + +namespace ppc::crypto +{ +class BitVector +{ +public: + using Ptr = std::shared_ptr; + + BitVector() = default; + ~BitVector() = default; + + // init '_len' bits by '_number' + BitVector(uint32_t _len, uint32_t _number) { m_data = boost::dynamic_bitset<>(_len, _number); } + + // init by binary string + BitVector(const std::string& _binary) { m_data = boost::dynamic_bitset<>(_binary); } + + // init by string + BitVector(const bcos::bytes& _data) { append(_data); } + + // get a bit by location + bool get(uint32_t _location) { return m_data[_location]; } + + // set a bit by location + void set(uint32_t _location, bool _bit) { m_data[_location] = _bit; } + + // generate random '_bytesLen * 8' bits + void randomize(PRNG::Ptr _prng, uint32_t _bytesLen); + + // append from the high position + void append(const std::string& _binary); + + // append from the high position + void append(const bcos::bytes& _data); + + bool equals(const BitVector& _bitVector) { return m_data == _bitVector.data(); } + + boost::dynamic_bitset<>& data() { return m_data; } + + [[nodiscard]] const boost::dynamic_bitset<>& data() const { return m_data; } + + uint32_t size() { return m_data.size(); } + + void resize(uint32_t _size) { m_data.resize(_size); } + + void clear() { m_data.clear(); } + + std::string toString(); + + bcos::bytes toBytes(); + +private: + boost::dynamic_bitset<> m_data; +}; + +} // namespace ppc::crypto diff --git a/cpp/wedpr-crypto/ppc-crypto-core/tests/CMakeLists.txt b/cpp/wedpr-crypto/ppc-crypto-core/tests/CMakeLists.txt new file mode 100644 index 00000000..f38a2d05 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-crypto-core/tests/CMakeLists.txt @@ -0,0 +1,10 @@ +file(GLOB_RECURSE SOURCES "*.cpp" "*.h") + +# cmake settings +set(TEST_BINARY_NAME test-ppc-crypto-core) + +add_executable(${TEST_BINARY_NAME} ${SOURCES}) +target_include_directories(${TEST_BINARY_NAME} PRIVATE .) + +target_link_libraries(${TEST_BINARY_NAME} ${CRYPTO_CORE_TARGET} ${BOOST_UNIT_TEST}) +add_test(NAME test-crypto-core WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} COMMAND ${TEST_BINARY_NAME}) diff --git a/cpp/wedpr-crypto/ppc-crypto-core/tests/TestBitVector.cpp b/cpp/wedpr-crypto/ppc-crypto-core/tests/TestBitVector.cpp new file mode 100644 index 00000000..7441f437 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-crypto-core/tests/TestBitVector.cpp @@ -0,0 +1,60 @@ +/** + * Copyright (C) 2022 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 TestBitvector.cpp + * @author: shawnhe + * @date 2022-12-6 + */ + +#include "ppc-crypto-core/src/tools/BitVector.h" +#include +#include +#include + +using namespace ppc::crypto; +using namespace bcos; +using namespace bcos::test; + +namespace ppc::test +{ +BOOST_FIXTURE_TEST_SUITE(BitvectorTest, TestPromptFixture) + +BOOST_AUTO_TEST_CASE(testBitvector) +{ + auto str = "10011011101"; + BitVector bv(str); + BOOST_CHECK(str == bv.toString()); + + BitVector bv0("10011011101"); + BOOST_CHECK(bv.equals(bv0)); + + BitVector bv1(10, 12345); + BOOST_CHECK("0000111001" == bv1.toString()); + BOOST_CHECK(bv1.get(0) && !bv1.get(1) && bv1.get(3)); + bv1.set(0, 0), bv1.set(1, 1), bv1.set(2, 1); + BOOST_CHECK("0000111110" == bv1.toString()); + + BitVector bv2(bcos::bytes{'a'}); + bv2.append(bcos::bytes{'b'}); + bv2.append(bcos::bytes{'c'}); + BOOST_CHECK("011000110110001001100001" == bv2.toString()); + bcos::bytes bytes1{'c', 'b', 'a'}; + BOOST_CHECK(bytes1 == bv2.toBytes()); + bv2.append("111000111"); + BOOST_CHECK("111000111011000110110001001100001" == bv2.toString()); +} + +BOOST_AUTO_TEST_SUITE_END() +} // namespace ppc::test diff --git a/cpp/wedpr-crypto/ppc-crypto-core/tests/TestHash.cpp b/cpp/wedpr-crypto/ppc-crypto-core/tests/TestHash.cpp new file mode 100644 index 00000000..f520c444 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-crypto-core/tests/TestHash.cpp @@ -0,0 +1,132 @@ +/* + * Copyright (C) 2022 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 applicabl 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 TestHash.cpp + * @author: yujiechen + * @date 2022-11-2 + */ +#include "ppc-crypto-core/src/hash/BLAKE2bHash.h" +#include "ppc-crypto-core/src/hash/MD5Hash.h" +#include "ppc-crypto-core/src/hash/SM3Hash.h" +#include "ppc-crypto-core/src/hash/Sha256Hash.h" +#include "ppc-crypto-core/src/hash/Sha512Hash.h" +#include +#include +#include + +using namespace ppc::crypto; +using namespace bcos; +using namespace bcos::test; + +namespace ppc::test +{ +BOOST_FIXTURE_TEST_SUITE(hashTest, TestPromptFixture) + +void testHash(Hash::Ptr _hashImpl, uint64_t expectedHashLen) +{ + std::string input = "abcdwerwlerkwel" + std::to_string(utcSteadyTime()); + bcos::bytes inputData(input.begin(), input.end()); + // check hash + auto hashResult = _hashImpl->hash(ref(inputData)); + for (int i = 0; i < 1000; i++) + { + BOOST_CHECK(_hashImpl->hash(ref(inputData)) == hashResult); + BOOST_CHECK(hashResult.size() == expectedHashLen); + } + + // check update + auto state = _hashImpl->init(); + _hashImpl->update(state, ref(inputData)); + auto finalHashResult = _hashImpl->final(state); + BOOST_CHECK(finalHashResult == hashResult); + + // check update multiple input + std::string input2 = "werwelr234weweskdsj2342"; + bcos::bytes inputData2(input2.begin(), input2.end()); + state = _hashImpl->init(); + _hashImpl->update(state, ref(inputData)); + _hashImpl->update(state, ref(inputData2)); + finalHashResult = _hashImpl->final(state); + for (int i = 0; i < 1000; i++) + { + state = _hashImpl->init(); + _hashImpl->update(state, ref(inputData)); + _hashImpl->update(state, ref(inputData2)); + BOOST_CHECK(_hashImpl->final(state) == finalHashResult); + } +} + +void checkFixedInput( + Hash::Ptr _hashImpl, std::string const& _input, std::string const& _expectedHash) +{ + bytes inputData(_input.begin(), _input.end()); + auto result = _hashImpl->hash(ref(inputData)); + std::cout << *toHexString(result) << std::endl; + BOOST_CHECK(*toHexString(result) == _expectedHash); +} +BOOST_AUTO_TEST_CASE(testSha256Hash) +{ + testHash(std::make_shared(), 32); + std::string input = "abcdwerwlerkwel"; + std::string expectedSha256 = "d7a5cc8e0f256e5c3f7f1c551d9206a22983da73969eb54b40b111c378ea4b70"; + checkFixedInput(std::make_shared(), input, expectedSha256); +} + +BOOST_AUTO_TEST_CASE(testSha512Hash) +{ + testHash(std::make_shared(), 64); + std::string input = "abcdwerwlerkwel"; + std::string expectedHash = + "f8e36730b763de5699d111fb65aae0e73afaedb914f634ad8210891f4b5b88f8ffc3fcc557c4273f61cc5177a4" + "67481a8d7b91a86a4c2de9ce342e91e7c3144d"; + checkFixedInput(std::make_shared(), input, expectedHash); +} + +BOOST_AUTO_TEST_CASE(testSM3Hash) +{ + testHash(std::make_shared(), 32); + std::string input = "abcdwerwlerkwel"; + std::string expectedHash = "9e057883cc739dc1ee95ae65a0e86b946330c77e48123e9cea2b31a43cb69db1"; + checkFixedInput(std::make_shared(), input, expectedHash); +} + +BOOST_AUTO_TEST_CASE(testMD5Hash) +{ + testHash(std::make_shared(), 16); + std::string input = "abcdwerwlerkwel"; + std::string expectedHash = "a3eeda2c6b29a2518d0945baf3cfd220"; + checkFixedInput(std::make_shared(), input, expectedHash); +} + +BOOST_AUTO_TEST_CASE(testBLAKE2bHash) +{ + testHash(std::make_shared(), 64); + + std::string input = "abcdwerwlerkwel"; + std::string expected512Hash = + "fa693cb55a305997ed33839bf540d88fdcd7f343e6ff4aa34d31fbdfaf6567569e8dd46a535e7d44b77de5e784" + "d8ac2e1a6413b473be3790c9f407594f1ead06"; + checkFixedInput(std::make_shared(), input, expected512Hash); + + + bytes inputData(input.begin(), input.end()); + auto hashImpl = std::make_shared(); + auto result = hashImpl->hash(ref(inputData), 32); + std::string expected256Hash = + "869cf8d5848f78a3a9c076e5d36a0a05ef0f37c2837a952b6590981762b3c9b3"; + BOOST_CHECK(*toHexString(result) == expected256Hash); +} +BOOST_AUTO_TEST_SUITE_END() +} // namespace ppc::test \ No newline at end of file diff --git a/cpp/wedpr-crypto/ppc-crypto-core/tests/TestOre4Float.cpp b/cpp/wedpr-crypto/ppc-crypto-core/tests/TestOre4Float.cpp new file mode 100644 index 00000000..0469b8a2 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-crypto-core/tests/TestOre4Float.cpp @@ -0,0 +1,214 @@ +/** + * Copyright (C) 2022 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 TestOre4Float.cpp + * @author: shawnhe + * @date 2023-12-07 + */ +#pragma execution_character_set("utf-8") +#include "ppc-crypto-core/src/ore/FastOre.h" +#include "ppc-framework/libwrapper/OreFloatingNumber.h" +#include +#include +#include +#include +#include +#include +#include + +using namespace ppc::protocol; +using namespace ppc::crypto; +using namespace bcos; +using namespace bcos::test; +namespace bmp = boost::multiprecision; + +namespace ppc::test +{ +BOOST_FIXTURE_TEST_SUITE(Ore4FloatTest, TestPromptFixture) + +float50 generateRandomFloat50() +{ + std::random_device rd; + std::mt19937_64 gen0(rd()); + std::uniform_int_distribution distribution0(-(1LL << 62) + 2, (1LL << 62) - 2); + int64_t integerPart = distribution0(gen0); + std::mt19937_64 gen1(rd()); + std::uniform_int_distribution distribution1(0, 99999999); + int64_t decimalPart = distribution1(gen1); + float50 randomCppFloat(std::to_string(integerPart) + "." + std::to_string(decimalPart)); + return randomCppFloat; +} + +std::vector generateRandomFloatNumbers(int vectorSize) +{ + std::vector numberVector; + numberVector.reserve(vectorSize); + + for (int i = 0; i < vectorSize; ++i) + { + numberVector.push_back(generateRandomFloat50()); + } + + // Sort the vector of strings + std::sort(numberVector.begin(), numberVector.end()); + return numberVector; +} + +void runOre(bcos::bytes const& key, FastOre::Ptr _ore, const float50& _input) +{ + auto cipher = _ore->encrypt4Float(bcos::ref(key), _input); + auto plain = _ore->decrypt4Float(bcos::ref(key), cipher); + BOOST_CHECK(_input == plain); +} + +void testOreFunctionImpl(bcos::bytes const& key) +{ + auto fastOre = std::make_shared(); + runOre(key, fastOre, float50{"-4611686018427387901.0000000000000213433437899"}); + runOre(key, fastOre, float50{"4611686018427387901.3437899"}); + runOre(key, fastOre, 0); + + auto inputs = generateRandomFloatNumbers(1000); + for (auto input : inputs) + { + runOre(key, fastOre, input); + } +} + +BOOST_AUTO_TEST_CASE(testOreFunction) +{ + auto ore = std::make_shared(); + bcos::bytes key{'a', 'b', 'c', 'd', 'a', 'b', 'c', 'd'}; + testOreFunctionImpl(key); + key = ore->generateKey(); + testOreFunctionImpl(key); +} + +void runOreOrderTest(bcos::bytes const& key, const std::vector& inputs) +{ + auto fastOre = std::make_shared(); + auto preCipher = fastOre->encrypt4Float(bcos::ref(key), inputs[0]); + + for (uint64_t i = 1; i < inputs.size(); i++) + { + auto cipher = fastOre->encrypt4Float(bcos::ref(key), inputs[i]); + BOOST_CHECK(fastOre->compare(preCipher, cipher) <= 0); + preCipher = cipher; + auto plain = fastOre->decrypt4Float(bcos::ref(key), cipher); + BOOST_CHECK(plain == inputs[i]); + } +} + +void testOreOrderImpl(bcos::bytes const& key) +{ + auto inputs = generateRandomFloatNumbers(1000); + runOreOrderTest(key, inputs); +} + +BOOST_AUTO_TEST_CASE(testOreOrder) +{ + bcos::bytes key{'a', 'b', 'c', 'd', 'a', 'b', 'c', 'd'}; + testOreOrderImpl(key); + auto fastOre = std::make_shared(); + key = fastOre->generateKey(); + testOreOrderImpl(key); +} + +void testEnc(FastOre::Ptr _ore, int _count) +{ + bcos::bytes key{'a', 'b', 'c', 'd', 'a', 'b', 'c', 'd'}; + auto start = bcos::utcTimeUs(); + float50 input("7121925678.23456789"); + for (auto i = 0; i < _count; i++) + { + _ore->encrypt4Float(bcos::ref(key), input); + } + std::cout << "Enc, Costs: " << (bcos::utcTimeUs() - start) * 1000 / _count << "ns" << std::endl; +} + +void testDec(FastOre::Ptr _ore, int _count) +{ + bcos::bytes key{'a', 'b', 'c', 'd', 'a', 'b', 'c', 'd'}; + float50 input("7121925678.23456789"); + auto cipher = _ore->encrypt4Float(bcos::ref(key), input); + auto start = bcos::utcTimeUs(); + + for (auto i = 0; i < _count; i++) + { + _ore->decrypt4Float(bcos::ref(key), cipher); + } + std::cout << "Dec, Costs: " << (bcos::utcTimeUs() - start) * 1000 / _count << "ns" << std::endl; +} + +void testCompare(bcos::bytes const& key, FastOre::Ptr _ore, int _count) +{ + auto cipher1 = _ore->encrypt4Float(bcos::ref(key), float50{"7121925678.23456789"}); + auto cipher2 = _ore->encrypt4Float(bcos::ref(key), float50{"7121925678.23456789"}); + auto start = bcos::utcTimeUs(); + + for (auto i = 0; i < _count; i++) + { + _ore->compare(cipher1, cipher2); + } + std::cout << "Com, Costs: " << (bcos::utcTimeUs() - start) * 1000 / _count << "ns" << std::endl; +} + +BOOST_AUTO_TEST_CASE(PerformanceTest) +{ + auto fastOre = std::make_shared(); + testEnc(fastOre, 100000); + testDec(fastOre, 100000); + auto key = fastOre->generateKey(); + testCompare(key, fastOre, 100000); +} + +void testOreFloatingNumber(std::string _value, std::string _target) +{ + float50 cppDecFloatValue(_value); + OreFloatingNumber ofn(cppDecFloatValue); + std::cout << "### valueStr: " << ofn.value().str() << ", target: " << _target << std::endl; + BOOST_CHECK(ofn.value().str() == _target); +} + +BOOST_AUTO_TEST_CASE(testOreFloatingNumberFunc) +{ + testOreFloatingNumber("0.00000", "0"); + testOreFloatingNumber("12374435346556789", "12374435346556789"); + testOreFloatingNumber("1233456789.0", "1233456789"); + testOreFloatingNumber("123456789.000000", "123456789"); + testOreFloatingNumber("12364456789.1234500", "12364456789.12345"); + testOreFloatingNumber("1234566789.000000019", "1234566789.000000019"); + testOreFloatingNumber("1234566789.999999999", "1234566789.999999999"); + testOreFloatingNumber("-1237456789", "-1237456789"); + testOreFloatingNumber("-123456789.000000", "-123456789"); + testOreFloatingNumber("-12364456789.1234500", "-12364456789.12345"); + testOreFloatingNumber("-1234566789.12345678999", "-1234566789.12345678999"); + testOreFloatingNumber("-1234566789.00000001", "-1234566789.00000001"); + testOreFloatingNumber("-12374435346556789.99999999", "-12374435346556789.99999999"); + testOreFloatingNumber("-12374435346556789.88888888", "-12374435346556789.88888888"); + testOreFloatingNumber("-1234566789.8888", "-1234566789.8888"); + + testOreFloatingNumber( + "-12374435346556789.000000000000088888888", "-12374435346556789.000000000000088888888"); + testOreFloatingNumber("12374435346556789.0000000000000000000000000000000000011118888888811111", + "12374435346556789.0000000000000000000000000000000000011118888888811111"); + // precision truncate case + testOreFloatingNumber( + "25347862354.0000000000000000234564564500000000000000023434200000000000456456", + "25347862354.00000000000000002345645645000000000000000234342"); +} + +BOOST_AUTO_TEST_SUITE_END() +} // namespace ppc::test diff --git a/cpp/wedpr-crypto/ppc-crypto-core/tests/TestOre4Integer.cpp b/cpp/wedpr-crypto/ppc-crypto-core/tests/TestOre4Integer.cpp new file mode 100644 index 00000000..6fcabad0 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-crypto-core/tests/TestOre4Integer.cpp @@ -0,0 +1,179 @@ +/** + * Copyright (C) 2022 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 TestOre4Integer.cpp + * @author: shawnhe + * @date 2023-11-22 + */ +#pragma execution_character_set("utf-8") +#include "ppc-crypto-core/src/ore/FastOre.h" +#include +#include +#include +#include +#include +#include +#include + +using namespace ppc::protocol; +using namespace ppc::crypto; +using namespace bcos; +using namespace bcos::test; + +namespace ppc::test +{ +BOOST_FIXTURE_TEST_SUITE(Ore4IntegerTest, TestPromptFixture) + +int64_t generateRandomInt64() +{ + std::random_device rd; + std::mt19937_64 gen(rd()); + std::uniform_int_distribution distribution(-(1LL << 62) + 1, (1LL << 62) - 1); + return distribution(gen); +} + +std::vector generateRandomNumber(int vectorSize) +{ + std::vector numberVector; + numberVector.reserve(vectorSize); + + for (int i = 0; i < vectorSize; ++i) + { + numberVector.push_back(generateRandomInt64()); + } + + // Sort the vector of strings + std::sort(numberVector.begin(), numberVector.end()); + return numberVector; +} + + +void runOre(bcos::bytes const& key, FastOre::Ptr _ore, const int64_t& _input) +{ + auto cipher = _ore->encrypt4Integer(bcos::ref(key), _input); + auto plain = _ore->decrypt4Integer(bcos::ref(key), cipher); + BOOST_CHECK(_input == plain); +} + +void testOreFunctionImpl(bcos::bytes const& key) +{ + auto fastOre = std::make_shared(); + runOre(key, fastOre, -(1LL << 62) + 1); + runOre(key, fastOre, (1LL << 62) - 1); + runOre(key, fastOre, 0); + runOre(key, fastOre, 123456); + runOre(key, fastOre, -234567); + + auto inputs = generateRandomNumber(1000); + for (auto input : inputs) + { + runOre(key, fastOre, input); + } +} + +BOOST_AUTO_TEST_CASE(testOreFunction) +{ + auto ore = std::make_shared(); + int64_t _plain = -123456; + OutputBuffer plain{(bcos::byte*)&_plain, sizeof(_plain)}; + ore->formatNumberPlain(&plain, _plain); + BOOST_CHECK(ore->recoverNumberPlain(plain) == -123456); + + bcos::bytes key{'a', 'b', 'c', 'd', 'a', 'b', 'c', 'd'}; + testOreFunctionImpl(key); + key = ore->generateKey(); + testOreFunctionImpl(key); +} + +void runOreOrderTest(bcos::bytes const& key, const std::vector& inputs) +{ + auto fastOre = std::make_shared(); + auto preCipher = fastOre->encrypt4Integer(bcos::ref(key), inputs[0]); + + for (uint64_t i = 1; i < inputs.size(); i++) + { + auto cipher = fastOre->encrypt4Integer(bcos::ref(key), inputs[i]); + BOOST_CHECK(fastOre->compare(preCipher, cipher) <= 0); + preCipher = cipher; + auto plain = fastOre->decrypt4Integer(bcos::ref(key), cipher); + BOOST_CHECK(plain == inputs[i]); + } +} + +void testOreOrderImpl(bcos::bytes const& key) +{ + auto inputs = generateRandomNumber(1000); + runOreOrderTest(key, inputs); +} + +BOOST_AUTO_TEST_CASE(testOreOrder) +{ + bcos::bytes key{'a', 'b', 'c', 'd', 'a', 'b', 'c', 'd'}; + testOreOrderImpl(key); + auto fastOre = std::make_shared(); + key = fastOre->generateKey(); + testOreOrderImpl(key); +} + +void testEnc(FastOre::Ptr _ore, int _count) +{ + bcos::bytes key{'a', 'b', 'c', 'd', 'a', 'b', 'c', 'd'}; + auto start = bcos::utcTimeUs(); + int64_t input = 712125678; + for (auto i = 0; i < _count; i++) + { + _ore->encrypt4Integer(bcos::ref(key), input); + } + std::cout << "Enc, Costs: " << (bcos::utcTimeUs() - start) * 1000 / _count << "ns" << std::endl; +} + +void testDec(FastOre::Ptr _ore, int _count) +{ + bcos::bytes key{'a', 'b', 'c', 'd', 'a', 'b', 'c', 'd'}; + int64_t input = 8712125678; + auto cipher = _ore->encrypt4Integer(bcos::ref(key), input); + auto start = bcos::utcTimeUs(); + + for (auto i = 0; i < _count; i++) + { + _ore->decrypt4Integer(bcos::ref(key), cipher); + } + std::cout << "Dec, Costs: " << (bcos::utcTimeUs() - start) * 1000 / _count << "ns" << std::endl; +} + +void testCompare(bcos::bytes const& key, FastOre::Ptr _ore, int _count) +{ + auto cipher1 = _ore->encrypt4Integer(bcos::ref(key), 8712125678); + auto cipher2 = _ore->encrypt4Integer(bcos::ref(key), 8712125679); + auto start = bcos::utcTimeUs(); + + for (auto i = 0; i < _count; i++) + { + _ore->compare(cipher1, cipher2); + } + std::cout << "Com, Costs: " << (bcos::utcTimeUs() - start) * 1000 / _count << "ns" << std::endl; +} + +BOOST_AUTO_TEST_CASE(PerformanceTest) +{ + auto fastOre = std::make_shared(); + testEnc(fastOre, 100000); + testDec(fastOre, 100000); + auto key = fastOre->generateKey(); + testCompare(key, fastOre, 100000); +} + +BOOST_AUTO_TEST_SUITE_END() +} // namespace ppc::test diff --git a/cpp/wedpr-crypto/ppc-crypto-core/tests/TestOre4String.cpp b/cpp/wedpr-crypto/ppc-crypto-core/tests/TestOre4String.cpp new file mode 100644 index 00000000..57cea7f5 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-crypto-core/tests/TestOre4String.cpp @@ -0,0 +1,193 @@ +/** + * Copyright (C) 2022 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 TestOre4String.cpp + * @author: shawnhe + * @date 2023-08-18 + */ +#pragma execution_character_set("utf-8") +#include "ppc-crypto-core/src/ore/FastOre.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace ppc::protocol; +using namespace ppc::crypto; +using namespace bcos; +using namespace bcos::test; + +namespace ppc::test +{ +BOOST_FIXTURE_TEST_SUITE(Ore4StringTest, TestPromptFixture) + +std::vector generateRandomString(int vectorSize, int stringLength) +{ + std::srand(static_cast(std::time(nullptr))); + std::vector stringVector; + stringVector.reserve(vectorSize); + + for (int i = 0; i < vectorSize; ++i) + { + std::string randomString; + randomString.reserve(stringLength); + + for (int j = 0; j < stringLength; ++j) + { + char randomChar = static_cast(std::rand() % 256); + randomString.push_back(randomChar); + } + + stringVector.push_back(randomString); + } + + // Sort the vector of strings + std::sort(stringVector.begin(), stringVector.end()); + return stringVector; +} + +void runOre(bcos::bytes const& key, Ore::Ptr _ore) +{ + std::string input1 = "123456781234567812345678"; + std::string input2 = "中文中文中文中文"; + + auto cipher1 = _ore->encrypt4String(bcos::ref(key), input1); + auto cipher2 = _ore->encrypt4String(bcos::ref(key), input2); + + auto plain2 = _ore->decrypt4String(bcos::ref(key), cipher2); + auto plain1 = _ore->decrypt4String(bcos::ref(key), cipher1); + BOOST_CHECK(input1 == plain1); + BOOST_CHECK(input2 == plain2); +} + +void runOre(bcos::bytes const& key, Ore::Ptr _ore, const std::string& _input) +{ + auto cipher = _ore->encrypt4String(bcos::ref(key), _input); + auto plain = _ore->decrypt4String(bcos::ref(key), cipher); + BOOST_CHECK(_input == plain); +} + +void testOreFunctionImpl(bcos::bytes const& key) +{ + auto fastOre = std::make_shared(); + runOre(key, fastOre); + runOre(key, fastOre, "测试生僻字謇鬱齉躞"); + runOre(key, fastOre, "测试标点符号!@#¥%……&*()~"); + runOre(key, fastOre, "测试中文"); + runOre(key, fastOre, "abcd1234"); + + auto inputs = generateRandomString(1000, 24); + for (auto input : inputs) + { + runOre(key, fastOre, input); + } +} + +BOOST_AUTO_TEST_CASE(testOreFunction) +{ + bcos::bytes key{'a', 'b', 'c', 'd', 'a', 'b', 'c', 'd'}; + testOreFunctionImpl(key); + + auto ore = std::make_shared(); + key = ore->generateKey(); + testOreFunctionImpl(key); +} + +void runOreOrderTest(bcos::bytes const& key, const std::vector& inputs) +{ + auto fastOre = std::make_shared(); + auto preCipher = fastOre->encrypt4String(bcos::ref(key), inputs[0]); + + for (uint64_t i = 1; i < inputs.size(); i++) + { + auto cipher = fastOre->encrypt4String(bcos::ref(key), inputs[i]); + BOOST_CHECK(fastOre->compare(preCipher, cipher) <= 0); + preCipher = cipher; + auto plain = fastOre->decrypt4String(bcos::ref(key), cipher); + BOOST_CHECK(plain == inputs[i]); + } +} + +void testOreOrderImpl(bcos::bytes const& key) +{ + auto inputs = generateRandomString(1000, 24); + runOreOrderTest(key, inputs); +} + +BOOST_AUTO_TEST_CASE(testOreOrder) +{ + bcos::bytes key{'a', 'b', 'c', 'd', 'a', 'b', 'c', 'd'}; + testOreOrderImpl(key); + auto fastOre = std::make_shared(); + key = fastOre->generateKey(); + testOreOrderImpl(key); +} + +void testEnc(Ore::Ptr _ore, int _count) +{ + bcos::bytes key{'a', 'b', 'c', 'd', 'a', 'b', 'c', 'd'}; + auto start = bcos::utcSteadyTime(); + std::string input = "2024-10-29 12:19:40"; + for (auto i = 0; i < _count; i++) + { + _ore->encrypt4String(bcos::ref(key), input); + } + std::cout << "FastOre Enc, Costs: " << (bcos::utcSteadyTime() - start) << "ms" << std::endl; + std::cout << "FastOre Enc, us/op: " << (bcos::utcSteadyTime() - start)*1000 / _count << "us" << std::endl; +} + +void testDec(Ore::Ptr _ore, int _count) +{ + bcos::bytes key{'a', 'b', 'c', 'd', 'a', 'b', 'c', 'd'}; + std::string input = "2024-10-29 12:19:40"; + auto cipher = _ore->encrypt4String(bcos::ref(key), input); + auto start = bcos::utcSteadyTime(); + + for (auto i = 0; i < _count; i++) + { + _ore->decrypt4String(bcos::ref(key), cipher); + } + std::cout << "FastOre Dec, Costs: " << (bcos::utcSteadyTime() - start) << "ms" << std::endl; + std::cout << "FastOre Dec, us/op: " << (bcos::utcSteadyTime() - start)*1000 / _count << "us" << std::endl; +} + +void testCompare(bcos::bytes const& key, Ore::Ptr _ore, int _count) +{ + auto cipher1 = _ore->encrypt4String(bcos::ref(key), "500232188712125678"); + auto cipher2 = _ore->encrypt4String(bcos::ref(key), "500232188712125679"); + auto start = bcos::utcTimeUs(); + + for (auto i = 0; i < _count; i++) + { + _ore->compare(cipher1, cipher2); + } + std::cout << "Com, Costs: " << (bcos::utcTimeUs() - start) * 1000 / _count << "ns" << std::endl; +} + +BOOST_AUTO_TEST_CASE(PerformanceTest) +{ + auto fastOre = std::make_shared(); + testEnc(fastOre, 100000); + testDec(fastOre, 100000); + auto key = fastOre->generateKey(); + testCompare(key, fastOre, 100000); +} +BOOST_AUTO_TEST_SUITE_END() +} // namespace ppc::test diff --git a/cpp/wedpr-crypto/ppc-crypto-core/tests/TestSymCrypto.cpp b/cpp/wedpr-crypto/ppc-crypto-core/tests/TestSymCrypto.cpp new file mode 100644 index 00000000..2d6c3ea6 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-crypto-core/tests/TestSymCrypto.cpp @@ -0,0 +1,318 @@ +/** + * Copyright (C) 2022 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 TestSymCrypto.cpp + * @author: shawnhe + * @date 2022-11-29 + */ +#pragma execution_character_set("utf-8") +#include "ppc-crypto-core/src/sym-crypto/OpenSSL3DES.h" +#include "ppc-crypto-core/src/sym-crypto/OpenSSLAES.h" +#include "ppc-crypto-core/src/sym-crypto/OpenSSLSM4.h" +#include +#include +#include + +using namespace ppc::protocol; +using namespace ppc::crypto; +using namespace bcos; +using namespace bcos::test; + +namespace ppc::test +{ +BOOST_FIXTURE_TEST_SUITE(SymCryptoTest, TestPromptFixture) + +void runSymCrypto(SymCrypto::OperationMode _mode, SymCrypto::Ptr _symCryptoEnc, + std::string const& _input, bool _useSpecifiedKey = false) +{ + u128 key = 1234567, iv = 7654321; + bcos::bytes bkey; + bcos::toBigEndian(key, bkey); + bcos::bytes biv; + bcos::toBigEndian(iv, biv); + if (!_useSpecifiedKey) + { + bkey = _symCryptoEnc->generateKey(_mode); + } + auto cipher = _symCryptoEnc->encrypt(_mode, bcos::ref(bkey), bcos::ref(biv), + bcos::bytesConstRef((bcos::byte const*)_input.data(), _input.size())); + auto plain = _symCryptoEnc->decrypt(_mode, bcos::ref(bkey), bcos::ref(biv), bcos::ref(cipher)); + std::cout << "### _input: " << _input << std::endl; + std::cout << "### plain: " << std::string(plain.begin(), plain.end()) << std::endl; + BOOST_CHECK(_input == std::string(plain.begin(), plain.end())); +} + +void runSymCrypto( + SymCrypto::OperationMode _mode, SymCrypto::Ptr _symCryptoEnc, bool _useSpecifiedKey) +{ + runSymCrypto(_mode, _symCryptoEnc, "a1", _useSpecifiedKey); + runSymCrypto(_mode, _symCryptoEnc, "a1b", _useSpecifiedKey); + runSymCrypto(_mode, _symCryptoEnc, "a1b2", _useSpecifiedKey); + runSymCrypto(_mode, _symCryptoEnc, "a1b2c", _useSpecifiedKey); + runSymCrypto(_mode, _symCryptoEnc, "a1b2c3", _useSpecifiedKey); + runSymCrypto(_mode, _symCryptoEnc, "a1b2c3d", _useSpecifiedKey); + runSymCrypto(_mode, _symCryptoEnc, "a1b2c3d4", _useSpecifiedKey); + runSymCrypto(_mode, _symCryptoEnc, "a1b2c3d4e", _useSpecifiedKey); + runSymCrypto(_mode, _symCryptoEnc, "a1b2c3d4e5", _useSpecifiedKey); + runSymCrypto(_mode, _symCryptoEnc, "a1b2c3d4e5f6", _useSpecifiedKey); + runSymCrypto(_mode, _symCryptoEnc, "a1b2c3d4e5f6g7", _useSpecifiedKey); + runSymCrypto(_mode, _symCryptoEnc, "a1b2c3d4e5f6g7h", _useSpecifiedKey); + runSymCrypto(_mode, _symCryptoEnc, "a1b2c3d4e5f6g7h8", _useSpecifiedKey); + runSymCrypto(_mode, _symCryptoEnc, "謇", _useSpecifiedKey); + runSymCrypto(_mode, _symCryptoEnc, "鬱", _useSpecifiedKey); + runSymCrypto(_mode, _symCryptoEnc, "齉", _useSpecifiedKey); + runSymCrypto(_mode, _symCryptoEnc, "躞", _useSpecifiedKey); + runSymCrypto(_mode, _symCryptoEnc, "&", _useSpecifiedKey); + runSymCrypto(_mode, _symCryptoEnc, "^", _useSpecifiedKey); + runSymCrypto(_mode, _symCryptoEnc, "……", _useSpecifiedKey); + runSymCrypto(_mode, _symCryptoEnc, "@", _useSpecifiedKey); + + runSymCrypto(_mode, _symCryptoEnc, + "test symmetric encryption 12345678 12345678 12345678 12345678 12345678 12345678" + "12345678 12345678 12345678 12345678 12345678 12345678 12345678 12345678 12345678 12345678 " + "12345678 12345678 12345678 12345678 12345678 12345678 12345678 12345678 12345678 " + "12345678", + _useSpecifiedKey); + + runSymCrypto(_mode, _symCryptoEnc, + "测试特殊符号*&(……%¥ 123abc 12345678 12345678 12345678 12345678 12345678 12345678" + "12345678 12345678 12345678 12345678 12345678 12345678 12345678 12345678 12345678 12345678 " + "12345678 12345678 12345678 12345678 12345678 12345678 12345678 #$%#&$#$*^&(#%$@#()_()", + _useSpecifiedKey); + + runSymCrypto(_mode, _symCryptoEnc, + "测试生僻字謇鬱齉躞*&(……%¥ 123abc 12345678 12345678 12345678 12345678 12345678 12345678" + "12345678 12345678 12345678 12345678 12345678 12345678 12345678 12345678 12345678 12345678 " + "12345678 12345678 12345678 12345678 12345678 12345678 12345678 #$%#&$#$*^&(#%$@#()_()", + _useSpecifiedKey); +} + +void runSymCryptoEnc(SymCrypto::OperationMode _mode, SymCrypto::Ptr _symCryptoEnc, + const std::string& _input, const std::string& _expected) +{ + std::string key = "0123456789abcdef0123456789abcdef"; + std::string iv = "0123456789abcdef"; + + bcos::bytes bkey(key.begin(), key.end()); + bcos::bytes biv(iv.begin(), iv.end()); + + auto cipher = _symCryptoEnc->encrypt( + _mode, ref(bkey), ref(biv), bcos::bytesConstRef((bcos::byte*)_input.data(), _input.size())); + std::cout << "cipher: " << *toHexString(cipher) << std::endl; + BOOST_CHECK(_expected == *toHexString(cipher)); +} + +void testAESEncDec(bool _useSpecifiedKey) +{ + // test ecb + std::cout << "====== testSM4EncDesc =====" << std::endl; + auto sm4Enc = std::make_shared(); + std::cout << "====== testSM4EncDesc ECB=====" << std::endl; + runSymCrypto(SymCrypto::OperationMode::ECB, sm4Enc, _useSpecifiedKey); + // test cbc + std::cout << "====== testSM4EncDesc CBC=====" << std::endl; + runSymCrypto(SymCrypto::OperationMode::CBC, sm4Enc, _useSpecifiedKey); + std::cout << "====== testSM4EncDesc CFB=====" << std::endl; + runSymCrypto(SymCrypto::OperationMode::CFB, sm4Enc, _useSpecifiedKey); + std::cout << "====== testSM4EncDesc OFB=====" << std::endl; + runSymCrypto(SymCrypto::OperationMode::OFB, sm4Enc, _useSpecifiedKey); + std::cout << "====== testSM4EncDesc CTR=====" << std::endl; + runSymCrypto(SymCrypto::OperationMode::CTR, sm4Enc, _useSpecifiedKey); + std::cout << "====== testSM4EncDesc finished =====" << std::endl; + + std::cout << "====== testAES128EncDec =====" << std::endl; + auto aes128Enc = std::make_shared(OpenSSLAES::AESType::AES128); + std::cout << "====== testAES128EncDec ECB=====" << std::endl; + runSymCrypto(SymCrypto::OperationMode::ECB, aes128Enc, _useSpecifiedKey); + std::cout << "====== testAES128EncDec CBC=====" << std::endl; + runSymCrypto(SymCrypto::OperationMode::CBC, aes128Enc, _useSpecifiedKey); + std::cout << "====== testAES128EncDec CFB=====" << std::endl; + runSymCrypto(SymCrypto::OperationMode::CFB, aes128Enc, _useSpecifiedKey); + std::cout << "====== testAES128EncDec OFB=====" << std::endl; + runSymCrypto(SymCrypto::OperationMode::OFB, aes128Enc, _useSpecifiedKey); + std::cout << "====== testAES128EncDec CTR=====" << std::endl; + runSymCrypto(SymCrypto::OperationMode::CTR, aes128Enc, _useSpecifiedKey); + std::cout << "====== testAES128EncDec finished =====" << std::endl; + + std::cout << "====== testAES192EncDec =====" << std::endl; + auto aes192Enc = std::make_shared(OpenSSLAES::AESType::AES192); + std::cout << "====== testAES192EncDec ECB=====" << std::endl; + runSymCrypto(SymCrypto::OperationMode::ECB, aes192Enc, _useSpecifiedKey); + std::cout << "====== testAES192EncDec CBC=====" << std::endl; + runSymCrypto(SymCrypto::OperationMode::CBC, aes192Enc, _useSpecifiedKey); + std::cout << "====== testAES192EncDec CFB=====" << std::endl; + runSymCrypto(SymCrypto::OperationMode::CFB, aes192Enc, _useSpecifiedKey); + std::cout << "====== testAES192EncDec OFB=====" << std::endl; + runSymCrypto(SymCrypto::OperationMode::OFB, aes192Enc, _useSpecifiedKey); + std::cout << "====== testAES192EncDec CTR=====" << std::endl; + runSymCrypto(SymCrypto::OperationMode::CTR, aes192Enc, _useSpecifiedKey); + std::cout << "====== testAES192EncDec finished=====" << std::endl; + + std::cout << "====== testAES256EncDec =====" << std::endl; + auto aes256Enc = std::make_shared(OpenSSLAES::AESType::AES256); + std::cout << "====== aes256Enc ECB=====" << std::endl; + runSymCrypto(SymCrypto::OperationMode::ECB, aes256Enc, _useSpecifiedKey); + std::cout << "====== aes256Enc CBC=====" << std::endl; + runSymCrypto(SymCrypto::OperationMode::CBC, aes256Enc, _useSpecifiedKey); + std::cout << "====== aes256Enc CFB=====" << std::endl; + runSymCrypto(SymCrypto::OperationMode::CFB, aes256Enc, _useSpecifiedKey); + std::cout << "====== aes256Enc OFB=====" << std::endl; + runSymCrypto(SymCrypto::OperationMode::OFB, aes256Enc, _useSpecifiedKey); + std::cout << "====== aes256Enc CTR=====" << std::endl; + runSymCrypto(SymCrypto::OperationMode::CTR, aes256Enc, _useSpecifiedKey); + std::cout << "====== testAES256EncDec finished=====" << std::endl; + + auto desEnc = std::make_shared(); + std::cout << "====== test3DESEncDec =====" << std::endl; + std::cout << "====== test3DESEncDec: ECB =====" << std::endl; + runSymCrypto(SymCrypto::OperationMode::ECB, desEnc, _useSpecifiedKey); + std::cout << "====== test3DESEncDec: CBC =====" << std::endl; + runSymCrypto(SymCrypto::OperationMode::CBC, desEnc, _useSpecifiedKey); + std::cout << "====== test3DESEncDec: CFB =====" << std::endl; + runSymCrypto(SymCrypto::OperationMode::CFB, desEnc, _useSpecifiedKey); + std::cout << "====== test3DESEncDec: OFB =====" << std::endl; + runSymCrypto(SymCrypto::OperationMode::OFB, desEnc, _useSpecifiedKey); + std::cout << "====== test3DESEncDec finished=====" << std::endl; +} + +BOOST_AUTO_TEST_CASE(testSymCryptoPKCS7) +{ + std::cout << "===== testAESEncDec ======" << std::endl; + testAESEncDec(true); + std::cout << "===== testAESEncDec finished ======" << std::endl; + + std::cout << "===== testAESEncDec and generateKey ======" << std::endl; + testAESEncDec(false); + std::cout << "===== testAESEncDec and generateKey finished ======" << std::endl; +} + +BOOST_AUTO_TEST_CASE(testSymCryptoEncPKCS7) +{ + std::cout << "====== testSymCryptoEncPKCS7 =====" << std::endl; + std::string input = "Hello, World, Hello Tomorrow."; + + // test ecb + auto sm4Enc = std::make_shared(); + runSymCryptoEnc(SymCrypto::OperationMode::ECB, sm4Enc, input, + "b654e713da62ef2899233b2542c234461ef8aa28a7faef3a089bbffd4e7f708b"); + runSymCryptoEnc(SymCrypto::OperationMode::CBC, sm4Enc, input, + "5ac1fe687a1227eb8a03d593b2a9a6d4c2d24d6a5bb08c3f4a9427d917fc6643"); + runSymCryptoEnc(SymCrypto::OperationMode::OFB, sm4Enc, input, + "5b42e00fd81c7e6b7c6eb7dfcad5d3e39645db8c7da36770ebf35f7033"); + runSymCryptoEnc(SymCrypto::OperationMode::CTR, sm4Enc, input, + "5b42e00fd81c7e6b7c6eb7dfcad5d3e39288a332b76f342309f73b9940"); + runSymCryptoEnc(SymCrypto::OperationMode::CFB, sm4Enc, input, + "5b42e00fd81c7e6b7c6eb7dfcad5d3e34b9b7ccde57e48d4309e1aa33a"); + + + auto aes128Enc = std::make_shared(OpenSSLAES::AESType::AES128); + runSymCryptoEnc(SymCrypto::OperationMode::ECB, aes128Enc, input, + "2f491097abdda469351be5c2a86c56fc2804e80bd08ac540cf5c30d11658c7f2"); + runSymCryptoEnc(SymCrypto::OperationMode::CBC, aes128Enc, input, + "edd475c62aae977b0cf5a3e6f94c95dbd19955211fd2cbd3df5517a6888c42a7"); + runSymCryptoEnc(SymCrypto::OperationMode::OFB, aes128Enc, input, + "3a1712e471f0dd566fd5740c5529fd000819bd65e9f99987da63e1160e"); + runSymCryptoEnc(SymCrypto::OperationMode::CTR, aes128Enc, input, + "3a1712e471f0dd566fd5740c5529fd009da1a4302925f3fe44d7212132"); + runSymCryptoEnc(SymCrypto::OperationMode::CFB, aes128Enc, input, + "3a1712e471f0dd566fd5740c5529fd00bfdaf41af70405dfeb98b01730"); + + + auto aes192Enc = std::make_shared(OpenSSLAES::AESType::AES192); + runSymCryptoEnc(SymCrypto::OperationMode::ECB, aes192Enc, input, + "926dcc7c086c08663e4c98628c2cc1c55a1c991fc93c37ca1cf7dbc6c660ee60"); + runSymCryptoEnc(SymCrypto::OperationMode::CBC, aes192Enc, input, + "34d5d3dbd184f0f123c96e98880fe877a3dc3364206c062e1d1427c1570244f7"); + + runSymCryptoEnc(SymCrypto::OperationMode::CFB, aes192Enc, input, + "92096245a9be5272896d356998ca309251817976f6521bd51c4ac87ec7"); + runSymCryptoEnc(SymCrypto::OperationMode::OFB, aes192Enc, input, + "92096245a9be5272896d356998ca30929553d60e30f9d84ce15bbdf080"); + runSymCryptoEnc(SymCrypto::OperationMode::CTR, aes192Enc, input, + "92096245a9be5272896d356998ca3092b92fe5fcc9efeaf1e48a3c56b0"); + + + auto aes256Enc = std::make_shared(OpenSSLAES::AESType::AES256); + runSymCryptoEnc(SymCrypto::OperationMode::ECB, aes256Enc, input, + "11f963d26ca05c4a7551e810e692f122f4d57e90d658c7e1ff88dc1432ec170e"); + runSymCryptoEnc(SymCrypto::OperationMode::CBC, aes256Enc, input, + "8937a782e67fd1d56e6e4b8d614e4afe3b1c9084e60d304ffb6546576e397428"); + runSymCryptoEnc(SymCrypto::OperationMode::CFB, aes256Enc, input, + "b059f60cb320fbcf4eed15b2f9fb5e5050e7b2936fe1ff1be3387e5c35"); + runSymCryptoEnc(SymCrypto::OperationMode::OFB, aes256Enc, input, + "b059f60cb320fbcf4eed15b2f9fb5e501790fa5fbe89d8b1a16de8e49e"); + runSymCryptoEnc(SymCrypto::OperationMode::CTR, aes256Enc, input, + "b059f60cb320fbcf4eed15b2f9fb5e50d9f3075d1b0d4f080e5a633deb"); + + auto desEnc = std::make_shared(); + runSymCryptoEnc(SymCrypto::OperationMode::ECB, desEnc, input, + "0bb66fcb35528a9aae4240b9235cd5b403d4e7648bef133d8f145e5475462c26"); + runSymCryptoEnc(SymCrypto::OperationMode::CBC, desEnc, input, + "a8f91cfb2ab2f98f5f8cb92545a2b3112df69bd94c64e883a9ec84e832cb273d"); + runSymCryptoEnc(SymCrypto::OperationMode::CFB, desEnc, input, + "04c5b63ce04ad91512c7616c0845f64896a1ffdeb94bbc114b3d23d78b"); + runSymCryptoEnc(SymCrypto::OperationMode::OFB, desEnc, input, + "04c5b63ce04ad915d7cc3432e00d338268178b71b2ee5ca31433e57916"); + std::cout << "====== testSymCryptoEncPKCS7 finished =====" << std::endl; +} + +BOOST_AUTO_TEST_CASE(testSm4) +{ + auto sm4Enc = std::make_shared(); + bcos::bytes bkey = sm4Enc->generateKey(SymCrypto::OperationMode::CBC); + bcos::bytes biv; + u128 iv = 7654321; + bcos::toBigEndian(iv, biv); + + bcos::bytes inputs(1024 * 10); + + int count = 10000; + std::vector ciphers(count); + + auto start = bcos::utcTimeUs(); + for(int i = 0; i < count; i++) + { + ciphers[i] = sm4Enc->encrypt(SymCrypto::OperationMode::CBC, bcos::ref(bkey), bcos::ref(biv), + bcos::bytesConstRef((bcos::byte const*)inputs.data(), inputs.size())); + } + std::cout << "CBC, ENC Costs: " << bcos::utcTimeUs() - start<< "us" << std::endl; + + start = bcos::utcTimeUs(); + for(int i = 0; i < count; i++) + { + sm4Enc->decrypt(SymCrypto::OperationMode::CBC, bcos::ref(bkey), bcos::ref(biv), + bcos::bytesConstRef((bcos::byte const*)ciphers[i].data(), ciphers[i].size())); + } + std::cout << "CBC, DEC Costs: " << bcos::utcTimeUs() - start<< "us" << std::endl; + + start = bcos::utcTimeUs(); + for(int i = 0; i < count; i++) + { + ciphers[i] = sm4Enc->encrypt(SymCrypto::OperationMode::CTR, bcos::ref(bkey), bcos::ref(biv), + bcos::bytesConstRef((bcos::byte const*)inputs.data(), inputs.size())); + } + std::cout << "CTR, ENC Costs: " << bcos::utcTimeUs() - start<< "us" << std::endl; + + start = bcos::utcTimeUs(); + for(int i = 0; i < count; i++) + { + sm4Enc->decrypt(SymCrypto::OperationMode::CTR, bcos::ref(bkey), bcos::ref(biv), + bcos::bytesConstRef((bcos::byte const*)ciphers[i].data(), ciphers[i].size())); + } + std::cout << "CTR, DEC Costs: " << bcos::utcTimeUs() - start<< "us" << std::endl; + +} +BOOST_AUTO_TEST_SUITE_END() +} // namespace ppc::test diff --git a/cpp/wedpr-crypto/ppc-crypto-core/tests/main.cpp b/cpp/wedpr-crypto/ppc-crypto-core/tests/main.cpp new file mode 100644 index 00000000..2c06f9b5 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-crypto-core/tests/main.cpp @@ -0,0 +1,2 @@ +#define BOOST_TEST_MAIN +#include \ No newline at end of file diff --git a/cpp/wedpr-crypto/ppc-crypto/CMakeLists.txt b/cpp/wedpr-crypto/ppc-crypto/CMakeLists.txt new file mode 100644 index 00000000..9f27bc5f --- /dev/null +++ b/cpp/wedpr-crypto/ppc-crypto/CMakeLists.txt @@ -0,0 +1,9 @@ +add_subdirectory(src) +if(DEMO) + add_subdirectory(demo) +endif() +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-crypto/ppc-crypto/demo/CMakeLists.txt b/cpp/wedpr-crypto/ppc-crypto/demo/CMakeLists.txt new file mode 100644 index 00000000..5a7678b8 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-crypto/demo/CMakeLists.txt @@ -0,0 +1,7 @@ +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) +# cmake settings +set(BINARY_NAME crypto_bench) +add_executable(${BINARY_NAME} crypto_bench.cpp) +target_link_libraries(${BINARY_NAME} ${CRYPTO_TARGET}) + +unset(CMAKE_RUNTIME_OUTPUT_DIRECTORY) \ No newline at end of file diff --git a/cpp/wedpr-crypto/ppc-crypto/demo/crypto_bench.cpp b/cpp/wedpr-crypto/ppc-crypto/demo/crypto_bench.cpp new file mode 100644 index 00000000..53688fa7 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-crypto/demo/crypto_bench.cpp @@ -0,0 +1,439 @@ +/* + * Copyright (C) 2022 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 crypto_bench.cpp + * @desc: bench for io + * @author: yujiechen + * @date 2022-12-1 + */ +#include "ppc-crypto-core/src/hash/BLAKE2bHash.h" +#include "ppc-crypto-core/src/hash/MD5Hash.h" +#include "ppc-crypto-core/src/hash/SM3Hash.h" +#include "ppc-crypto-core/src/hash/Sha256Hash.h" +#include "ppc-crypto-core/src/hash/Sha512Hash.h" +#include "ppc-crypto-core/src/sym-crypto/OpenSSLAES.h" +#include "ppc-crypto-core/src/sym-crypto/OpenSSLSM4.h" +#include "ppc-crypto/src/ecc/ECDHCryptoImpl.h" +#include "ppc-crypto/src/ecc/Ed25519EccCrypto.h" +#include "ppc-crypto/src/ecc/IppECDHCryptoImpl.h" +#include "ppc-crypto/src/ecc/OpenSSLEccCrypto.h" +#include "ppc-crypto/src/oprf/RA2018Oprf.h" +#include "ppc-framework/io/DataBatch.h" + +using namespace bcos; +using namespace ppc::io; +using namespace ppc::protocol; +using namespace ppc::crypto; + +const std::string HASH_CMD = "hash"; +const std::string ECC_CMD = "ecc"; +const std::string ENCRYPT_CMD = "enc"; +const std::string OPRF_CMD = "oprf"; +const std::string ECDH_CMD = "ecdh"; + + +void Usage(std::string const& _appName) +{ + std::cout << _appName << " [" << HASH_CMD << "/" << ECC_CMD << "/" << ENCRYPT_CMD << "/" + << OPRF_CMD << "/" << ECDH_CMD << "] count" << std::endl; +} + +double getTPS(int64_t _endT, int64_t _startT, size_t _count) +{ + return (1000.0 * (double)_count) / (double)(_endT - _startT); +} + +void hashPerf( + Hash::Ptr _hash, std::string const& _hashName, std::string const& _inputData, size_t _count) +{ + std::cout << std::endl; + std::cout << "----------- " << _hashName << " perf start -----------" << std::endl; + auto startT = utcSteadyTime(); + for (size_t i = 0; i < _count; i++) + { + _hash->hash(bytesConstRef((byte const*)_inputData.c_str(), _inputData.size())); + } + std::cout << "input data size: " << (double)_inputData.size() / 1000.0 + << "KB, loops: " << _count << ", timeCost: " << utcSteadyTime() - startT << " ms" + << std::endl; + std::cout << "TPS of " << _hashName << ": " + << getTPS(utcSteadyTime(), startT, _count) * (double)_inputData.size() / 1000.0 + << " KB/s" << std::endl; + std::cout << "----------- " << _hashName << " perf end -----------" << std::endl; + std::cout << std::endl; +} + +void hashPerf(size_t _count) +{ + std::string inputData = "abcdwer234q4@#2424wdf"; + std::string deltaData = inputData; + for (int i = 0; i < 50; i++) + { + inputData += deltaData; + } + // MD5Hash perf + Hash::Ptr hashImpl = std::make_shared(); + hashPerf(hashImpl, "MD5Hash", inputData, _count); + // Sha256Hash perf + hashImpl = std::make_shared(); + hashPerf(hashImpl, "Sha256Hash", inputData, _count); + // Sha512Hash perf + hashImpl = std::make_shared(); + hashPerf(hashImpl, "Sha512Hash", inputData, _count); + // SM3Hash perf + hashImpl = std::make_shared(); + hashPerf(hashImpl, "SM3Hash", inputData, _count); + // BLAKE2bHash + hashImpl = std::make_shared(); + hashPerf(hashImpl, "BLAKE2bHash", inputData, _count); +} + +void eccCryptoPerf(EccCrypto::Ptr _eccCrypto, std::string const& _eccName, + bcos::bytes const& _hashData, size_t _count) +{ + std::cout << std::endl; + std::cout << "----------- " << _eccName << " perf start -----------" << std::endl; + // generateRandomScalar + auto startT = utcSteadyTime(); + for (size_t i = 0; i < _count; i++) + { + _eccCrypto->generateRandomScalar(); + } + std::cout << "TPS of " << _eccName + << ": generateRandomScalar: " << getTPS(utcSteadyTime(), startT, _count) + << ", timecost:" << (utcSteadyTime() - startT) << " ms" << std::endl; + // hashToCurve + startT = utcSteadyTime(); + for (size_t i = 0; i < _count; i++) + { + _eccCrypto->hashToCurve(_hashData); + } + std::cout << "TPS of " << _eccName + << ": hashToCurve: " << getTPS(utcSteadyTime(), startT, _count) + << ", timecost:" << (utcSteadyTime() - startT) << " ms" << std::endl; + auto point = _eccCrypto->hashToCurve(_hashData); + auto scalar = _eccCrypto->generateRandomScalar(); + // ecMultiply + startT = utcSteadyTime(); + for (size_t i = 0; i < _count; i++) + { + _eccCrypto->ecMultiply(point, scalar); + } + std::cout << "TPS of " << _eccName + << ": ecMultiply: " << getTPS(utcSteadyTime(), startT, _count) + << ", timecost:" << (utcSteadyTime() - startT) << " ms" << std::endl; + // scalarInvert + startT = utcSteadyTime(); + for (size_t i = 0; i < _count; i++) + { + _eccCrypto->scalarInvert(scalar); + } + std::cout << "TPS of " << _eccName + << ": scalarInvert: " << getTPS(utcSteadyTime(), startT, _count) + << ", timecost:" << (utcSteadyTime() - startT) << " ms" << std::endl; + // mulGenerator + startT = utcSteadyTime(); + for (size_t i = 0; i < _count; i++) + { + _eccCrypto->mulGenerator(scalar); + } + std::cout << "TPS of " << _eccName + << ": mulGenerator: " << getTPS(utcSteadyTime(), startT, _count) + << ", timecost:" << (utcSteadyTime() - startT) << " ms" << std::endl; + std::cout << "----------- " << _eccName << " perf end -----------" << std::endl; + std::cout << std::endl; +} + +void eccCryptoPerf(size_t _count) +{ + auto hashImpl = std::make_shared(); + std::string inputStr = "abcdwer234q4@#2424wdf"; + bytes inputData(inputStr.begin(), inputStr.end()); + auto hashData = hashImpl->hash(ref(inputData)); + // ed25519 perf + EccCrypto::Ptr eccCrypto = std::make_shared(); + eccCryptoPerf(eccCrypto, "Ed25519EccCrypto", hashData, _count); + // sm2 perf + eccCrypto = std::make_shared(hashImpl, ECCCurve::SM2); + eccCryptoPerf(eccCrypto, "OpenSSLEccCrypto-SM2", hashData, _count); + // prime256v1 perf + eccCrypto = std::make_shared(hashImpl, ECCCurve::P256); + eccCryptoPerf(eccCrypto, "OpenSSLEccCrypto-P256", hashData, _count); + // secp256k1 perf + eccCrypto = std::make_shared(hashImpl, ECCCurve::SECP256K1); + eccCryptoPerf(eccCrypto, "OpenSSLEccCrypto-SECP256K1", hashData, _count); +} + + +void encryptPerf(SymCrypto::Ptr _encryptor, OpenSSLAES::OperationMode _mode, + std::string const& _inputData, const std::string& _encryptorName, size_t _count) +{ + std::string keyString = "abcdefgwerelkewrwerw"; + bcos::bytes key(keyString.begin(), keyString.end()); + std::string ivData = "12334324"; + bcos::bytes iv(ivData.begin(), ivData.end()); + + std::cout << std::endl; + std::cout << "----------- " << _encryptorName << " perf test start -----------" << std::endl; + // encrypt + bcos::bytes encryptedData; + auto startT = utcSteadyTime(); + for (size_t i = 0; i < _count; i++) + { + encryptedData = _encryptor->encrypt(_mode, ref(key), ref(iv), + bytesConstRef((byte const*)_inputData.c_str(), _inputData.size())); + } + std::cout << "PlainData size:" << (double)_inputData.size() / 1000.0 << " KB, loops: " << _count + << ", timeCost: " << utcSteadyTime() - startT << " ms" << std::endl; + std::cout << "TPS of " << _encryptorName << " encrypt:" + << (getTPS(utcSteadyTime(), startT, _count) * (double)(_inputData.size())) / 1000.0 + << "KB/s" << std::endl; + std::cout << std::endl; + // decrypt + startT = utcSteadyTime(); + bytes decryptedData; + for (size_t i = 0; i < _count; i++) + { + decryptedData = _encryptor->decrypt(_mode, ref(key), ref(iv), ref(encryptedData)); + } + std::cout << "CiperData size:" << (double)encryptedData.size() / 1000.0 + << " KB, loops: " << _count << ", timeCost:" << utcSteadyTime() - startT << " ms" + << std::endl; + std::cout << "TPS of " << _encryptorName << " decrypt:" + << (getTPS(utcSteadyTime(), startT, _count) * (double)_inputData.size()) / 1000.0 + << "KB/s" << std::endl; + bytes plainBytes(_inputData.begin(), _inputData.end()); + assert(plainBytes == decryptedData); + + std::cout << "----------- " << _encryptorName << " perf test end -----------" << std::endl; + std::cout << std::endl; +} + +void encryptPerf(size_t _count) +{ + std::string inputData = "w3rwerk2-304swlerkjewlrjoiur4kslfjsd,fmnsdlfjlwerlwerjw;erwe;rewrew"; + std::string deltaData = inputData; + for (int i = 0; i < 100; i++) + { + inputData += deltaData; + } + + // AES128-CBC + SymCrypto::Ptr encryptor = nullptr; + encryptor = std::make_shared(OpenSSLAES::AESType::AES128); + encryptPerf(encryptor, SymCrypto::OperationMode::CBC, inputData, "AES128-CBC", _count); + + // AES192-CBC + encryptor = std::make_shared(OpenSSLAES::AESType::AES192); + encryptPerf(encryptor, SymCrypto::OperationMode::CBC, inputData, "AES192-CBC", _count); + // AES256-CBC + encryptor = std::make_shared(OpenSSLAES::AESType::AES256); + encryptPerf(encryptor, SymCrypto::OperationMode::CBC, inputData, "AES256-CBC", _count); + // SM4-CBC + encryptor = std::make_shared(); + encryptPerf(encryptor, SymCrypto::OperationMode::CBC, inputData, "SM4-CBC", _count); +} + + +void RA2018OprfCryptoPerf( + RA2018Oprf::Ptr _oprf, std::vector const& _inputData, std::string const& _testCase) +{ + std::cout << std::endl; + std::cout << "----------- " << _testCase << " perf start -----------" << std::endl; + //// FullEvaluate + auto tmpData = _inputData; + auto dataBatch = std::make_shared(); + dataBatch->setData(std::move(tmpData)); + + auto startT = utcSteadyTime(); + std::vector fullEvaluateResult; + _oprf->fullEvaluate(dataBatch, fullEvaluateResult); + std::cout << "fullEvaluate: timecost of " << _testCase << " : " << (utcSteadyTime() - startT) + << " ms" << std::endl; + + /// blind + startT = utcSteadyTime(); + std::vector blindResult; + auto privateKey = _oprf->generatePrivateKey(); + _oprf->blind(dataBatch, privateKey, blindResult); + std::cout << "Blind: timecost of " << _testCase << " : " << (utcSteadyTime() - startT) << " ms" + << std::endl; + + /// evaluate + startT = utcSteadyTime(); + std::vector evaluateData; + _oprf->evaluate(blindResult, evaluateData); + std::cout << "Evaluate: timecost of " << _testCase << " : " << (utcSteadyTime() - startT) + << " ms" << std::endl; + + /// finalize + startT = utcSteadyTime(); + std::vector finalizeResult; + auto invPrivateKey = _oprf->inv(privateKey); + _oprf->finalize(evaluateData, invPrivateKey, finalizeResult); + std::cout << "Finalize: timecost of " << _testCase << " : " << (utcSteadyTime() - startT) + << " ms" << std::endl; + std::cout << "----------- " << _testCase << " perf end -----------" << std::endl; + std::cout << std::endl; +} + +void oprfCryptoPerf(size_t _count) +{ + // fake the input data + std::vector data; + for (size_t i = 0; i < _count; i++) + { + auto inputStr = std::to_string(i); + data.emplace_back(bcos::bytes(inputStr.begin(), inputStr.end())); + } + + EccCrypto::Ptr eccCrypto = std::make_shared(); + // generate the private-key + auto privateKey = eccCrypto->generateRandomScalar(); + auto hashImpl = std::make_shared(); + + /// ed25519 ra2018 oprf + auto oprf = std::make_shared(privateKey, eccCrypto, hashImpl); + RA2018OprfCryptoPerf(oprf, data, "RA2018-OPRF-ED25519"); + // P256 ra2018 oprf + eccCrypto = std::make_shared(hashImpl, ECCCurve::P256); + privateKey = eccCrypto->generateRandomScalar(); + oprf = std::make_shared(privateKey, eccCrypto, hashImpl); + RA2018OprfCryptoPerf(oprf, data, "RA2018-OPRF-P256"); + + /// sm2 ra2018 oprf + eccCrypto = std::make_shared(hashImpl, ECCCurve::SM2); + privateKey = eccCrypto->generateRandomScalar(); + oprf = std::make_shared(privateKey, eccCrypto, hashImpl); + RA2018OprfCryptoPerf(oprf, data, "RA2018-OPRF-SM2"); +} + +void ecdhCryptoPerf(ECDHCrypto::Ptr _ecdhCrypto, std::vector const& _inputData, + std::string const& _testCase) +{ + try + { + std::cout << std::endl; + std::cout << "----------- " << _testCase << " perf start -----------" << std::endl; + //// batchGetPublicKey + auto tmpData = _inputData; + auto dataBatch = std::make_shared(); + dataBatch->setData(std::move(tmpData)); + + auto startT = utcSteadyTime(); + auto publicKeyResult = _ecdhCrypto->batchGetPublicKey(dataBatch); + std::cout << "batchGetPublicKey: timecost of " << _testCase << " : " + << (utcSteadyTime() - startT) << " ms" << std::endl; + + /// batchGetSharedPublicKey + startT = utcSteadyTime(); + auto sharedKeys = _ecdhCrypto->batchGetSharedPublicKey(publicKeyResult); + std::cout << "batchGetSharedPublicKey: timecost of " << _testCase << " : " + << (utcSteadyTime() - startT) << " ms" << std::endl; + std::cout << "----------- " << _testCase << " perf end -----------" << std::endl; + } + catch (std::exception const& e) + { + std::cout << "ecdhCryptoPerf exception, error: " << boost::diagnostic_information(e) + << std::endl; + } + std::cout << std::endl; +} + +void ecdhCryptoPerf(size_t _count) +{ + // fake the input data + std::vector data; + for (size_t i = 0; i < _count; i++) + { + auto inputStr = std::to_string(i); + data.emplace_back(bcos::bytes(inputStr.begin(), inputStr.end())); + } + + EccCrypto::Ptr eccCrypto = std::make_shared(); + // generate the private-key + auto privateKey = eccCrypto->generateRandomScalar(); + auto hashImpl = std::make_shared(); + auto cryptoBox = std::make_shared(hashImpl, eccCrypto); + + /// ed25519 ecdh-crypto + auto ecdhCrypto = std::make_shared(privateKey, cryptoBox); + ecdhCryptoPerf(ecdhCrypto, data, "ECDH-CRYPTO-ED25519"); + // P256 ecdh-crypto + eccCrypto = std::make_shared(hashImpl, ECCCurve::P256); + privateKey = eccCrypto->generateRandomScalar(); + cryptoBox = std::make_shared(hashImpl, eccCrypto); + ecdhCrypto = std::make_shared(privateKey, cryptoBox); + ecdhCryptoPerf(ecdhCrypto, data, "ECDH-CRYPTO-P256"); + + /// sm2 ecdh-crypto + eccCrypto = std::make_shared(hashImpl, ECCCurve::SM2); + privateKey = eccCrypto->generateRandomScalar(); + cryptoBox = std::make_shared(hashImpl, eccCrypto); + ecdhCrypto = std::make_shared(privateKey, cryptoBox); + ecdhCryptoPerf(ecdhCrypto, data, "ECDH-CRYPTO-SM2"); + +// ipp x25519 crypto +#ifdef ENABLE_CRYPTO_MB + if (ppc::CPU_FEATURES.avx512ifma) + { + auto ippEdchCrypto = std::make_shared(privateKey, hashImpl); + ecdhCryptoPerf(ippEdchCrypto, data, "IPP-ECDH-CRYPTO-x25519"); + } + else + { + std::cout << "Ignore IPP-ECDH-CRYPTO-x25519 test for crypto_mb not enabled!" << std::endl; + } +#else + std::cout << "Ignore IPP-ECDH-CRYPTO-x25519 test for crypto_mb not enabled!" << std::endl; +#endif +} + +int main(int argc, char* argv[]) +{ + if (argc < 3) + { + Usage(argv[0]); + return -1; + } + auto cmd = argv[1]; + size_t count = atoi(argv[2]); + if (HASH_CMD == cmd) + { + hashPerf(count); + } + else if (ENCRYPT_CMD == cmd) + { + encryptPerf(count); + } + else if (ECC_CMD == cmd) + { + eccCryptoPerf(count); + } + else if (OPRF_CMD == cmd) + { + oprfCryptoPerf(count); + } + else if (ECDH_CMD == cmd) + { + ecdhCryptoPerf(count); + } + else + { + std::cout << "Invalid subcommand \"" << cmd << "\"" << std::endl; + Usage(argv[0]); + } + return 0; +} diff --git a/cpp/wedpr-crypto/ppc-crypto/src/CMakeLists.txt b/cpp/wedpr-crypto/ppc-crypto/src/CMakeLists.txt new file mode 100644 index 00000000..a11c824f --- /dev/null +++ b/cpp/wedpr-crypto/ppc-crypto/src/CMakeLists.txt @@ -0,0 +1,14 @@ +file(GLOB_RECURSE SRCS *.cpp) +add_library(${CRYPTO_TARGET} ${SRCS}) + + +find_package(OpenSSL REQUIRED) +message(STATUS "OPENSSL_INCLUDE_DIR: ${OPENSSL_INCLUDE_DIR}") +message(STATUS "OPENSSL_LIBRARIES: ${OPENSSL_LIBRARIES}") + +target_link_libraries(${CRYPTO_TARGET} PUBLIC ${BCOS_UTILITIES_TARGET} ${CRYPTO_CORE_TARGET} OpenSSL::Crypto unofficial-sodium::sodium TBB::tbb ${CPU_FEATURES_LIB}) + +if (ENABLE_IPP_CRYPTO) + find_package(ipp-crypto REQUIRED) + target_link_libraries(${CRYPTO_TARGET} PUBLIC ipp-crypto::crypto_mb) +endif () diff --git a/cpp/wedpr-crypto/ppc-crypto/src/Common.h b/cpp/wedpr-crypto/ppc-crypto/src/Common.h new file mode 100644 index 00000000..de36dddc --- /dev/null +++ b/cpp/wedpr-crypto/ppc-crypto/src/Common.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2022 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 Common.h + * @author: yujiechen + * @date 2022-11-2 + */ +#pragma once +#include "ppc-framework/Common.h" +#include +#include + +#define CRYPTO_LOG(LEVEL) BCOS_LOG(LEVEL) << LOG_BADGE("CRYPTO") + +namespace ppc::crypto +{ +DERIVE_PPC_EXCEPTION(OprfFinalizeException); +DERIVE_PPC_EXCEPTION(HashToCurveException); +DERIVE_PPC_EXCEPTION(HashToScalarException); +DERIVE_PPC_EXCEPTION(ScalarInvertException); +DERIVE_PPC_EXCEPTION(ScalarCalculateException); +DERIVE_PPC_EXCEPTION(EcMultipleException); +DERIVE_PPC_EXCEPTION(MulGeneratorError); +DERIVE_PPC_EXCEPTION(EcAddError); +DERIVE_PPC_EXCEPTION(EcSubError); + +DERIVE_PPC_EXCEPTION(ECGroupGetCurveError); +DERIVE_PPC_EXCEPTION(ECGroupGetOrderError); +DERIVE_PPC_EXCEPTION(ECPoint2BNError); +DERIVE_PPC_EXCEPTION(ECPointMulError); +DERIVE_PPC_EXCEPTION(ECPointAddError); +DERIVE_PPC_EXCEPTION(ECPointSubError); +DERIVE_PPC_EXCEPTION(ECPointBn2PointError); + +DERIVE_PPC_EXCEPTION(UnsupportedCurveType); +DERIVE_PPC_EXCEPTION(GenerateRandomScalarError); + +DERIVE_PPC_EXCEPTION(X25519GetSharedKeyError); +} // namespace ppc::crypto diff --git a/cpp/wedpr-crypto/ppc-crypto/src/ecc/ECDHCryptoFactoryImpl.h b/cpp/wedpr-crypto/ppc-crypto/src/ecc/ECDHCryptoFactoryImpl.h new file mode 100644 index 00000000..9fcede1d --- /dev/null +++ b/cpp/wedpr-crypto/ppc-crypto/src/ecc/ECDHCryptoFactoryImpl.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 ECDHCryptoFactoryImpl.h + * @author: yujiechen + * @date 2023-1-3 + */ +#pragma once +#include "../ecc/EccCryptoFactoryImpl.h" +#include "ECDHCryptoImpl.h" +#include "IppECDHCryptoImpl.h" +#include "ppc-crypto-core/src/hash/HashFactoryImpl.h" +#include "ppc-framework/crypto/CryptoBox.h" +namespace ppc::crypto +{ +class ECDHCryptoFactoryImpl : public ECDHCryptoFactory +{ +public: + using Ptr = std::shared_ptr; + ECDHCryptoFactoryImpl(bcos::bytes const& _privateKey) + : m_privateKey(_privateKey), + m_hashFactory(std::make_shared()), + m_eccCryptoFactory(std::make_shared()) + {} + + ~ECDHCryptoFactoryImpl() override = default; + + ECDHCrypto::Ptr createECDHCrypto(int _curveType, int _hashType) const override + { + auto hashImpl = m_hashFactory->createHashImpl(_hashType); +#ifdef ENABLE_CRYPTO_MB + if (ppc::CPU_FEATURES.avx512ifma && _curveType == (int)ppc::protocol::ECCCurve::IPP_X25519) + { + return std::make_shared(m_privateKey, hashImpl); + } +#endif + if (_curveType == (int)ppc::protocol::ECCCurve::IPP_X25519) + { + BOOST_THROW_EXCEPTION( + UnsupportedCurveType() << bcos::errinfo_comment( + "Not supported IPP_X25519 for missing avx512ifma instruction")); + } + auto eccCrypto = m_eccCryptoFactory->createEccCrypto(_curveType, hashImpl); + auto cryptoBox = std::make_shared(hashImpl, eccCrypto); + return std::make_shared(m_privateKey, cryptoBox); + } + + CryptoBox::Ptr createCryptoBox(int8_t _curveType, int8_t _hashType) const override + { + auto hashImpl = m_hashFactory->createHashImpl(_hashType); + auto eccCrypto = m_eccCryptoFactory->createEccCrypto(_curveType, hashImpl); + return std::make_shared(hashImpl, eccCrypto); + } + +private: + bcos::bytes m_privateKey; + HashFactory::Ptr m_hashFactory; + EccCryptoFactory::Ptr m_eccCryptoFactory; +}; +} // namespace ppc::crypto \ No newline at end of file diff --git a/cpp/wedpr-crypto/ppc-crypto/src/ecc/ECDHCryptoImpl.h b/cpp/wedpr-crypto/ppc-crypto/src/ecc/ECDHCryptoImpl.h new file mode 100644 index 00000000..5a21c5f3 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-crypto/src/ecc/ECDHCryptoImpl.h @@ -0,0 +1,74 @@ +/** + * Copyright (C) 2022 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 ECDHCryptoImpl.h + * @author: yujiechen + * @date 2022-12-29 + */ +#pragma once +#include "ppc-framework/crypto/CryptoBox.h" +#include "ppc-framework/crypto/ECDHCrypto.h" +#include + +namespace ppc::crypto +{ +class ECDHCryptoImpl : public ECDHCrypto +{ +public: + using Ptr = std::shared_ptr; + ECDHCryptoImpl(bcos::bytes const& _privateKey, CryptoBox::Ptr const& _cryptoBox) + : m_privateKey(_privateKey), m_cryptoBox(_cryptoBox) + {} + + // calculate the ecdh public-key according to privateKey and input + std::vector batchGetPublicKey(ppc::io::DataBatch::Ptr const& _input) override + { + std::vector result; + result.resize(_input->size()); + tbb::parallel_for(tbb::blocked_range(0U, _input->size()), [&](auto const& range) { + for (auto i = range.begin(); i < range.end(); i++) + { + auto const& data = _input->getBytes(i); + auto hashData = + m_cryptoBox->hashImpl()->hash(bcos::bytesConstRef(data.data(), data.size())); + auto point = m_cryptoBox->eccCrypto()->hashToCurve(hashData); + result[i] = m_cryptoBox->eccCrypto()->ecMultiply(point, m_privateKey); + } + }); + return result; + } + + // calculate the ecdh shared-publicKey according to the publicKey and privateKey + std::vector batchGetSharedPublicKey( + std::vector const& _publicKeys) override + { + std::vector result; + result.resize(_publicKeys.size()); + tbb::parallel_for( + tbb::blocked_range(0U, _publicKeys.size()), [&](auto const& range) { + for (auto i = range.begin(); i < range.end(); i++) + { + result[i] = + m_cryptoBox->eccCrypto()->ecMultiply(_publicKeys.at(i), m_privateKey); + } + }); + return result; + } + +private: + bcos::bytes m_privateKey; + CryptoBox::Ptr m_cryptoBox; +}; +} // namespace ppc::crypto \ No newline at end of file diff --git a/cpp/wedpr-crypto/ppc-crypto/src/ecc/EccCryptoFactoryImpl.h b/cpp/wedpr-crypto/ppc-crypto/src/ecc/EccCryptoFactoryImpl.h new file mode 100644 index 00000000..ae428660 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-crypto/src/ecc/EccCryptoFactoryImpl.h @@ -0,0 +1,52 @@ +/** + * 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 EccCryptoFactoryImpl.h + * @author: yujiechen + * @date 2023-1-3 + */ +#pragma once +#include "../Common.h" +#include "Ed25519EccCrypto.h" +#include "OpenSSLEccCrypto.h" +#include "ppc-framework/protocol/Protocol.h" + +namespace ppc::crypto +{ +class EccCryptoFactoryImpl : public EccCryptoFactory +{ +public: + using Ptr = std::shared_ptr; + EccCryptoFactoryImpl() = default; + ~EccCryptoFactoryImpl() override = default; + + EccCrypto::Ptr createEccCrypto(int8_t _curveType, Hash::Ptr const& _hashImpl) const override + { + switch (_curveType) + { + case (int8_t)ppc::protocol::ECCCurve::ED25519: + return std::make_shared(); + case (int8_t)ppc::protocol::ECCCurve::SM2: + case (int8_t)ppc::protocol::ECCCurve::SECP256K1: + case (int8_t)ppc::protocol::ECCCurve::P256: + return std::make_shared( + _hashImpl, (ppc::protocol::ECCCurve)_curveType); + default: + BOOST_THROW_EXCEPTION(UnsupportedCurveType() << bcos::errinfo_comment( + "unsupported curveType: " + std::to_string(_curveType))); + } + } +}; +} // namespace ppc::crypto \ No newline at end of file diff --git a/cpp/wedpr-crypto/ppc-crypto/src/ecc/Ed25519EccCrypto.cpp b/cpp/wedpr-crypto/ppc-crypto/src/ecc/Ed25519EccCrypto.cpp new file mode 100644 index 00000000..0619c17a --- /dev/null +++ b/cpp/wedpr-crypto/ppc-crypto/src/ecc/Ed25519EccCrypto.cpp @@ -0,0 +1,207 @@ +/* + * Copyright (C) 2022 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 Ed25519EccCrypto.cpp + * @author: yujiechen + * @date 2022-11-2 + */ +#include "Ed25519EccCrypto.h" +#include "../Common.h" +#include +using namespace ppc::crypto; +using namespace bcos; + +uint32_t Ed25519EccCrypto::pointSizeInBytes() const +{ + return crypto_core_ed25519_BYTES; +} + +bcos::bytes Ed25519EccCrypto::generateRandomScalar() const +{ + bcos::bytes scalar(crypto_core_ed25519_SCALARBYTES); + crypto_core_ed25519_random(scalar.data()); + bcos::bytes reducedResult(crypto_core_ed25519_SCALARBYTES); + // Note: must reduce here to mod L + crypto_core_ed25519_scalar_reduce(reducedResult.data(), scalar.data()); + return reducedResult; +} + +bcos::bytes Ed25519EccCrypto::hashToCurve(bcos::bytes&& _hashData) const +{ + if (_hashData.size() < crypto_core_ed25519_HASHBYTES) + { + _hashData.resize(crypto_core_ed25519_HASHBYTES); + } + return convertHashToCurve(_hashData); +} + +bcos::bytes Ed25519EccCrypto::hashToCurve(bcos::bytes const& _hashData) const +{ + if (_hashData.size() < crypto_core_ed25519_HASHBYTES) + { + bcos::bytes tmpData(_hashData.begin(), _hashData.end()); + tmpData.resize(crypto_core_ed25519_HASHBYTES); + return convertHashToCurve(tmpData); + } + return convertHashToCurve(_hashData); +} + +// convert the hashData into ec-point over the given curve +bcos::bytes Ed25519EccCrypto::convertHashToCurve(bcos::bytes const& _hashData) const +{ + bcos::bytes ecPoint(crypto_core_ed25519_BYTES); + auto ret = crypto_core_ed25519_from_hash(ecPoint.data(), _hashData.data()); + if (ret) + { + BOOST_THROW_EXCEPTION( + HashToCurveException() << errinfo_comment( + "call crypto_core_ed25519_from_hash error, code: " + std::to_string(ret))); + } + return ecPoint; +} + +// get the multiplicative inverse of _data over the given curve +bcos::bytes Ed25519EccCrypto::scalarInvert(bcos::bytes const& _data) const +{ + if (_data.size() < crypto_core_ed25519_SCALARBYTES) + { + BOOST_THROW_EXCEPTION(ScalarInvertException() << errinfo_comment( + "the length of scalar-data must be no smaller than: " + + std::to_string(crypto_core_ed25519_SCALARBYTES))); + } + bcos::bytes invertedScalar(crypto_core_ed25519_SCALARBYTES); + auto ret = crypto_core_ed25519_scalar_invert(invertedScalar.data(), _data.data()); + if (ret) + { + BOOST_THROW_EXCEPTION( + HashToCurveException() << errinfo_comment( + "call crypto_core_ed25519_scalar_invert error, code: " + std::to_string(ret))); + } + return invertedScalar; +} + +// multiply the _ecPoint by _scalar +bcos::bytes Ed25519EccCrypto::ecMultiply( + bcos::bytes const& _ecPoint, bcos::bytes const& _scalar) const +{ + if (_ecPoint.size() < crypto_scalarmult_ed25519_BYTES) + { + BOOST_THROW_EXCEPTION(EcMultipleException() << errinfo_comment( + "the ecpoint for ed25519 must be no smaller than: " + + std::to_string(crypto_scalarmult_ed25519_BYTES))); + } + if (_scalar.size() < crypto_scalarmult_ed25519_SCALARBYTES) + { + BOOST_THROW_EXCEPTION(EcMultipleException() << errinfo_comment( + "the scalar for ed25519 must be no smaller than: " + + std::to_string(crypto_scalarmult_ed25519_SCALARBYTES))); + } + bcos::bytes result(crypto_scalarmult_ed25519_BYTES); + auto ret = crypto_scalarmult_ed25519_noclamp(result.data(), _scalar.data(), _ecPoint.data()); + if (ret) + { + BOOST_THROW_EXCEPTION(EcMultipleException() << errinfo_comment( + "crypto_scalarmult_ed25519 error: " + std::to_string(ret))); + } + return result; +} + +bcos::bytes Ed25519EccCrypto::ecAdd( + bcos::bytes const& _ecPointA, bcos::bytes const& _ecPointB) const +{ + if (_ecPointA.size() < crypto_scalarmult_ed25519_BYTES || + _ecPointB.size() < crypto_scalarmult_ed25519_BYTES) + { + BOOST_THROW_EXCEPTION(EcMultipleException() << errinfo_comment( + "the ecpoint for ed25519 must be no smaller than: " + + std::to_string(crypto_scalarmult_ed25519_BYTES))); + } + + bcos::bytes result(crypto_scalarmult_ed25519_BYTES); + auto ret = crypto_core_ed25519_add(result.data(), _ecPointA.data(), _ecPointB.data()); + if (ret) + { + BOOST_THROW_EXCEPTION(EcMultipleException() << errinfo_comment( + "crypto_core_ed25519_add error: " + std::to_string(ret))); + } + return result; +} + +bcos::bytes Ed25519EccCrypto::ecSub( + bcos::bytes const& _ecPointA, bcos::bytes const& _ecPointB) const +{ + if (_ecPointA.size() < crypto_scalarmult_ed25519_BYTES || + _ecPointB.size() < crypto_scalarmult_ed25519_BYTES) + { + BOOST_THROW_EXCEPTION(EcMultipleException() << errinfo_comment( + "the ecpoint for ed25519 must be no smaller than: " + + std::to_string(crypto_scalarmult_ed25519_BYTES))); + } + + bcos::bytes result(crypto_scalarmult_ed25519_BYTES); + auto ret = crypto_core_ed25519_sub(result.data(), _ecPointA.data(), _ecPointB.data()); + if (ret) + { + BOOST_THROW_EXCEPTION(EcMultipleException() << errinfo_comment( + "crypto_core_ed25519_sub error: " + std::to_string(ret))); + } + return result; +} + +bool Ed25519EccCrypto::isValidEcPoint(bcos::bytes const& _ecPoint) const +{ + if (_ecPoint.size() < crypto_core_ed25519_SCALARBYTES) + { + return false; + } + // Note: if _ecPoint is not a valid point, return 0 + return (crypto_core_ed25519_is_valid_point(_ecPoint.data()) != 0); +} + +bcos::bytes Ed25519EccCrypto::mulGenerator(bcos::bytes const& _scalar) const +{ + bcos::bytes result(crypto_scalarmult_ed25519_SCALARBYTES); + auto ret = crypto_scalarmult_ed25519_base_noclamp(result.data(), _scalar.data()); + if (ret) + { + BOOST_THROW_EXCEPTION( + EcMultipleException() << errinfo_comment( + "crypto_scalarmult_ed25519_base_noclamp error: " + std::to_string(ret))); + } + return result; +} + +bcos::bytes Ed25519EccCrypto::hashToScalar(bcos::bytes const& _hashData) const +{ + BOOST_THROW_EXCEPTION(UnsupportedCurveType() << errinfo_comment("method not support: ")); +} + +bcos::bytes Ed25519EccCrypto::scalarAdd( + bcos::bytes const& _scalarA, bcos::bytes const& _scalarB) const +{ + BOOST_THROW_EXCEPTION(UnsupportedCurveType() << errinfo_comment("method not support: ")); +} + +bcos::bytes Ed25519EccCrypto::scalarSub( + bcos::bytes const& _scalarA, bcos::bytes const& _scalarB) const +{ + BOOST_THROW_EXCEPTION(UnsupportedCurveType() << errinfo_comment("method not support: ")); +} + +bcos::bytes Ed25519EccCrypto::scalarMul( + bcos::bytes const& _scalarA, bcos::bytes const& _scalarB) const +{ + BOOST_THROW_EXCEPTION(UnsupportedCurveType() << errinfo_comment("method not support: ")); +} diff --git a/cpp/wedpr-crypto/ppc-crypto/src/ecc/Ed25519EccCrypto.h b/cpp/wedpr-crypto/ppc-crypto/src/ecc/Ed25519EccCrypto.h new file mode 100644 index 00000000..baa39675 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-crypto/src/ecc/Ed25519EccCrypto.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2022 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 Ed25519EccCrypto.h + * @author: yujiechen + * @date 2022-11-2 + */ +#pragma once +#include "ppc-framework/crypto/EccCrypto.h" +#include "ppc-framework/protocol/Protocol.h" + +namespace ppc::crypto +{ +class Ed25519EccCrypto : public EccCrypto +{ +public: + using Ptr = std::shared_ptr; + Ed25519EccCrypto() = default; + ~Ed25519EccCrypto() override = default; + + uint32_t pointSizeInBytes() const override; + // get the curve + ppc::protocol::ECCCurve getCurve() const override { return ppc::protocol::ECCCurve::ED25519; } + + bcos::bytes generateRandomScalar() const override; + // convert the hashData into ec-point over the given curve + bcos::bytes hashToCurve(bcos::bytes&& _hashData) const override; + bcos::bytes hashToCurve(bcos::bytes const& _hashData) const override; + // get the multiplicative inverse of _data over the given curve + bcos::bytes scalarInvert(bcos::bytes const& _data) const override; + // multiply the _ecPoint by _scalar + bcos::bytes ecMultiply(bcos::bytes const& _ecPoint, bcos::bytes const& _scalar) const override; + bcos::bytes ecAdd(bcos::bytes const& _ecPointA, bcos::bytes const& _ecPointB) const override; + bcos::bytes ecSub(bcos::bytes const& _ecPointA, bcos::bytes const& _ecPointB) const override; + bool isValidEcPoint(bcos::bytes const& _ecPoint) const override; + bcos::bytes mulGenerator(bcos::bytes const& _scalar) const override; + + bcos::bytes hashToScalar(bcos::bytes const& _hashData) const override; + bcos::bytes scalarAdd(bcos::bytes const& _scalarA, bcos::bytes const& _scalarB) const override; + bcos::bytes scalarSub(bcos::bytes const& _scalarA, bcos::bytes const& _scalarB) const override; + bcos::bytes scalarMul(bcos::bytes const& _scalarA, bcos::bytes const& _scalarB) const override; + + +private: + bcos::bytes convertHashToCurve(bcos::bytes const& _hashData) const; +}; +} // namespace ppc::crypto \ No newline at end of file diff --git a/cpp/wedpr-crypto/ppc-crypto/src/ecc/IppECDHCryptoImpl.h b/cpp/wedpr-crypto/ppc-crypto/src/ecc/IppECDHCryptoImpl.h new file mode 100644 index 00000000..5b4579a5 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-crypto/src/ecc/IppECDHCryptoImpl.h @@ -0,0 +1,121 @@ +/* + * 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 IppECDHCryptoImpl.h + * @author: yujiechen + * @date 2023-1-3 + */ +#ifdef ENABLE_CRYPTO_MB +#pragma once +#include "../Common.h" +#include "ppc-framework/crypto/ECDHCrypto.h" +#include "ppc-framework/crypto/Hash.h" +#include +#include + +namespace ppc::crypto +{ +class IppECDHCryptoImpl : public ECDHCrypto +{ +public: + IppECDHCryptoImpl(bcos::bytes const& _privateKey, Hash::Ptr const& _hashImpl) + : m_privateKeyData(_privateKey), m_hashImpl(_hashImpl) + { + std::fill(m_privateKey.begin(), m_privateKey.end(), + static_cast(&m_privateKeyData[0])); + } + ~IppECDHCryptoImpl() override = default; + + // calculate the ecdh public-key according to privateKey and input + std::vector batchGetPublicKey(ppc::io::DataBatch::Ptr const& _input) override + { + // calculate hash for the input + std::vector hashResult; + hashResult.resize(_input->size()); + tbb::parallel_for(tbb::blocked_range(0U, _input->size()), [&](auto const& range) { + for (auto i = range.begin(); i < range.end(); i++) + { + auto const& data = _input->get(i); + hashResult[i] = m_hashImpl->hash(bcos::bytesConstRef(data.data(), data.size())); + } + }); + return batchGetSharedPublicKeyImpl(hashResult); + } + + // calculate the ecdh shared-publicKey according to the publicKey and privateKey + std::vector batchGetSharedPublicKey( + std::vector const& _publicKey) override + { + return batchGetSharedPublicKeyImpl(_publicKey); + } + +protected: + virtual std::vector batchGetSharedPublicKeyImpl( + std::vector const& _inputPoints) + { + std::vector result; + result.resize(_inputPoints.size()); + uint64_t dataBatchSize = + (_inputPoints.size() + CRYPTO_MB_BATCH_SIZE - 1) / CRYPTO_MB_BATCH_SIZE; + tbb::parallel_for(tbb::blocked_range(0U, dataBatchSize), [&](auto const& range) { + for (auto i = range.begin(); i < range.end(); i++) + { + std::array pk; + std::array sharedKey; + auto startOffset = i * CRYPTO_MB_BATCH_SIZE; + uint64_t k = 0; + int8u junkBuffer[CRYPTO_MB_BATCH_SIZE][X25519_ELEMENT_SIZE]; // Junk buffer + for (uint64_t j = startOffset; j < startOffset + 8; j++) + { + if (j < result.size()) + { + result[j].resize(X25519_ELEMENT_SIZE); + pk[k] = static_cast(_inputPoints[j].data()); + sharedKey[k] = static_cast(result[j].data()); + } + else + { + pk[k] = static_cast(_inputPoints[startOffset].data()); + sharedKey[k] = (int8u*)junkBuffer[k]; + } + k++; + } + // call mbx_x25519_mb8 + auto status = mbx_x25519_mb8(sharedKey.data(), m_privateKey.data(), pk.data()); + if (status != 0) + { + BOOST_THROW_EXCEPTION( + X25519GetSharedKeyError() << bcos::errinfo_comment( + "mbx_x25519_mb8 error, status: " + std::to_string(status))); + } + } + }); + return result; + } + +private: + // enforce the life-time of the privateKey + bcos::bytes m_privateKeyData; + // store the address of the privateKey + std::array m_privateKey; + Hash::Ptr m_hashImpl; + + // 32 bytes + constexpr static int X25519_ELEMENT_SIZE = 32; + // 8 elements per crypto_mb calls + constexpr static int CRYPTO_MB_BATCH_SIZE = 8; +}; +} // namespace ppc::crypto +#endif \ No newline at end of file diff --git a/cpp/wedpr-crypto/ppc-crypto/src/ecc/OpenSSLEccCrypto.cpp b/cpp/wedpr-crypto/ppc-crypto/src/ecc/OpenSSLEccCrypto.cpp new file mode 100644 index 00000000..b640f6d7 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-crypto/src/ecc/OpenSSLEccCrypto.cpp @@ -0,0 +1,309 @@ +/** + * Copyright (C) 2022 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 OpenSSLEccCrypto.cpp + * @author: yujiechen + * @date 2022-12-5 + */ +#include "OpenSSLEccCrypto.h" +#include "openssl/obj_mac.h" +#include "ppc-framework/libwrapper/BigNum.h" +using namespace ppc::crypto; +using namespace ppc::protocol; +using namespace bcos; + +OpenSSLEccCrypto::OpenSSLEccCrypto(Hash::Ptr _hashImpl, ppc::protocol::ECCCurve const& _curve) + : m_hashImpl(std::move(_hashImpl)), m_curve(_curve) +{ + switch (_curve) + { + case ECCCurve::SM2: + { + m_group = EcGroup(SM2_POINT_BYTES_LEN, NID_sm2); + m_keySize = SM2_KEY_SIZE; + break; + } + case ECCCurve::SECP256K1: + { + m_group = EcGroup(SECP256K1_POINT_BYTES_LEN, NID_secp256k1); + m_keySize = SECP256K1_KEY_SIZE; + break; + } + case ECCCurve::P256: + { + m_group = EcGroup(P256_POINT_BYTES_LEN, NID_X9_62_prime256v1); + m_keySize = P256_KEY_SIZE; + break; + } + default: + { + BOOST_THROW_EXCEPTION(UnsupportedCurveType() << errinfo_comment( + "Not supported curve type " + std::to_string((int)_curve))); + } + } +} + +// generate a random group-element +bcos::bytes OpenSSLEccCrypto::generateRandomScalar() const +{ + bcos::bytes result; + generateRandomScalarImpl().toBytes(result); + return result; +} + + +// convert the hashData into ec-point over the given curve +bcos::bytes OpenSSLEccCrypto::hashToCurve(bcos::bytes&& _hashData) const +{ + bcos::bytes result; + hashToCurveImpl(_hashData).toBytes(result); + return result; +} + +bcos::bytes OpenSSLEccCrypto::hashToCurve(bcos::bytes const& _hashData) const +{ + bcos::bytes result; + hashToCurveImpl(_hashData).toBytes(result); + return result; +} + +// get the multiplicative inverse of _data over the given curve +bcos::bytes OpenSSLEccCrypto::scalarInvert(bcos::bytes const& _data) const +{ + try + { + bcos::bytes result; + invertImpl(_data).toBytes(result); + return result; + } + catch (std::exception const& e) + { + BOOST_THROW_EXCEPTION(ScalarInvertException() + << errinfo_comment("OpenSSLEccCrypto scalarInvert error: " + + std::string(boost::diagnostic_information(e)))); + } +} + + +bcos::bytes OpenSSLEccCrypto::scalarAdd( + bcos::bytes const& _scalarA, bcos::bytes const& _scalarB) const +{ + try + { + bcos::bytes result; + result.resize(_scalarA.size()); + addImpl(_scalarA, _scalarB).toBytes(result); + return result; + } + catch (std::exception const& e) + { + BOOST_THROW_EXCEPTION(ScalarCalculateException() + << errinfo_comment("OpenSSLEccCrypto scalarAdd error: " + + std::string(boost::diagnostic_information(e)))); + } +} + +bcos::bytes OpenSSLEccCrypto::scalarSub( + bcos::bytes const& _scalarA, bcos::bytes const& _scalarB) const +{ + try + { + bcos::bytes result; + result.resize(_scalarA.size()); + subImpl(_scalarA, _scalarB).toBytes(result); + return result; + } + catch (std::exception const& e) + { + BOOST_THROW_EXCEPTION(ScalarCalculateException() + << errinfo_comment("OpenSSLEccCrypto scalarSub error: " + + std::string(boost::diagnostic_information(e)))); + } +} + + +bcos::bytes OpenSSLEccCrypto::scalarMul( + bcos::bytes const& _scalarA, bcos::bytes const& _scalarB) const +{ + try + { + bcos::bytes result; + result.resize(_scalarA.size()); + mulImpl(_scalarA, _scalarB).toBytes(result); + return result; + } + catch (std::exception const& e) + { + BOOST_THROW_EXCEPTION(ScalarCalculateException() + << errinfo_comment("OpenSSLEccCrypto scalscalarMularSub error: " + + std::string(boost::diagnostic_information(e)))); + } +} + +bcos::bytes OpenSSLEccCrypto::hashToScalar(const bcos::bytes& _hashData) const +{ + try + { + BigNum x; + auto hashResult = m_hashImpl->hash(ref(_hashData)); + x.fromBytesModP(ref(hashResult), m_group.p()); + bcos::bytes result; + result.resize(hashResult.size()); + x.toBytes(result); + return result; + } + catch (std::exception const& e) + { + BOOST_THROW_EXCEPTION(HashToScalarException() + << errinfo_comment("OpenSSLEccCrypto hashToScalar error: " + + std::string(boost::diagnostic_information(e)))); + } +} + + +EcPoint OpenSSLEccCrypto::hashToCurveImpl(bcos::bytes const& _hashData) const +{ + try + { + auto bnContext = createBNContext(); + BigNum x; + // Note: After actual measurement, sm2 will always retry once, so for the sm2 elliptic + // curve, will hash the hashData again + if (m_curve == ECCCurve::SM2) + { + auto hashResult = m_hashImpl->hash(ref(_hashData)); + x.fromBytesModP(ref(hashResult), m_group.p()); + } + else + { + x.fromBytesModP(ref(_hashData), m_group.p()); + } + int retryCount = 0; + EcPoint point(m_group); + while (true) + { + if (EC_POINT_set_compressed_coordinates(m_group.ecGroup().get(), point.point().get(), + x.bn().get(), 0, bnContext.get()) == 1) + { + break; + } + // re-hash the x + bcos::bytes xBytes; + x.toBytes(xBytes); + auto hashResult = m_hashImpl->hash(ref(xBytes)); + x.fromBytesModP(ref(hashResult), m_group.p()); + retryCount++; + } + return point; + } + catch (std::exception const& e) + { + BOOST_THROW_EXCEPTION(HashToCurveException() + << errinfo_comment("OpenSSLEccCrypto hashToCurve error: " + + std::string(boost::diagnostic_information(e)))); + } +} + +// multiply the _ecPoint by _scalar +bcos::bytes OpenSSLEccCrypto::ecMultiply( + bcos::bytes const& _ecPoint, bcos::bytes const& _scalar) const +{ + try + { + // convert bytes to EcPoint + EcPoint point(m_group, ref(_ecPoint)); + // convert bytes to BigNumber + BigNum sk(ref(_scalar)); + bcos::bytes result; + point.ecMultiply(sk).toBytes(result); + return result; + } + catch (std::exception const& e) + { + BOOST_THROW_EXCEPTION( + EcMultipleException() << errinfo_comment( + "ecMultiply error:" + std::string(boost::diagnostic_information(e)))); + } +} + +bool OpenSSLEccCrypto::isValidEcPoint(bcos::bytes const& _ecPoint) const +{ + // try to convert to EcPoint + try + { + EcPoint point(m_group, ref(_ecPoint)); + return true; + } + catch (std::exception const& e) + { + CRYPTO_LOG(WARNING) << LOG_DESC("isValidEcPoint: convert bytes to ecPoint error") + << LOG_KV("exception", boost::diagnostic_information(e)); + return false; + } +} + +bcos::bytes OpenSSLEccCrypto::mulGenerator(bcos::bytes const& _scalar) const +{ + try + { + BigNum sk(ref(_scalar)); + bcos::bytes result; + basePointMultiply(m_group, sk).toBytes(result); + return result; + } + catch (std::exception const& e) + { + BOOST_THROW_EXCEPTION( + MulGeneratorError() << errinfo_comment("OpenSSLEccCrypto mulGenerator error: " + + std::string(boost::diagnostic_information(e)))); + } +} + +bcos::bytes OpenSSLEccCrypto::ecAdd( + bcos::bytes const& _ecPointA, bcos::bytes const& _ecPointB) const +{ + try + { + EcPoint pointA(m_group, ref(_ecPointA)); + EcPoint pointB(m_group, ref(_ecPointB)); + bcos::bytes result; + pointA.add(pointB).toBytes(result); + return result; + } + catch (std::exception const& e) + { + BOOST_THROW_EXCEPTION( + EcAddError() << errinfo_comment( + "OpenSSLEccCrypto ecAdd error: " + std::string(boost::diagnostic_information(e)))); + } +} +bcos::bytes OpenSSLEccCrypto::ecSub( + bcos::bytes const& _ecPointA, bcos::bytes const& _ecPointB) const +{ + try + { + EcPoint pointA(m_group, ref(_ecPointA)); + EcPoint pointB(m_group, ref(_ecPointB)); + bcos::bytes result; + pointA.sub(pointB).toBytes(result); + return result; + } + catch (std::exception const& e) + { + BOOST_THROW_EXCEPTION( + EcSubError() << errinfo_comment( + "OpenSSLEccCrypto ecSub error: " + std::string(boost::diagnostic_information(e)))); + } +} \ No newline at end of file diff --git a/cpp/wedpr-crypto/ppc-crypto/src/ecc/OpenSSLEccCrypto.h b/cpp/wedpr-crypto/ppc-crypto/src/ecc/OpenSSLEccCrypto.h new file mode 100644 index 00000000..c20f1077 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-crypto/src/ecc/OpenSSLEccCrypto.h @@ -0,0 +1,115 @@ +/** + * Copyright (C) 2022 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 OpenSSLEccCrypto.h + * @author: yujiechen + * @date 2022-12-5 + */ +#pragma once +#include "core/EcPoint.h" +#include "openssl/rand.h" +#include "ppc-framework/crypto/EccCrypto.h" +#include "ppc-framework/crypto/Hash.h" +#include "ppc-framework/libwrapper/BigNum.h" +namespace ppc::crypto +{ +class OpenSSLEccCrypto : public EccCrypto +{ +public: + using Ptr = std::shared_ptr; + OpenSSLEccCrypto(Hash::Ptr _hashImpl, ppc::protocol::ECCCurve const& _curve); + ~OpenSSLEccCrypto() override = default; + + uint32_t pointSizeInBytes() const override { return m_group.pointBytesLen(); } + // get the curve + ppc::protocol::ECCCurve getCurve() const override { return m_curve; } + + // generate a random group-element + bcos::bytes generateRandomScalar() const override; + // convert the hashData into ec-point over the given curve + bcos::bytes hashToCurve(bcos::bytes&& _hashData) const override; + bcos::bytes hashToCurve(bcos::bytes const& _hashData) const override; + + // get the multiplicative inverse of _data over the given curve + bcos::bytes scalarInvert(bcos::bytes const& _data) const override; + // multiply the _ecPoint by _scalar + bcos::bytes ecMultiply(bcos::bytes const& _ecPoint, bcos::bytes const& _scalar) const override; + bool isValidEcPoint(bcos::bytes const& _ecPoint) const override; + bcos::bytes mulGenerator(bcos::bytes const& _scalar) const override; + + bcos::bytes ecAdd(bcos::bytes const& _ecPointA, bcos::bytes const& _ecPointB) const override; + bcos::bytes ecSub(bcos::bytes const& _ecPointA, bcos::bytes const& _ecPointB) const override; + + bcos::bytes hashToScalar(bcos::bytes const& _hashData) const override; + bcos::bytes scalarAdd(bcos::bytes const& _scalarA, bcos::bytes const& _scalarB) const override; + bcos::bytes scalarSub(bcos::bytes const& _scalarA, bcos::bytes const& _scalarB) const override; + bcos::bytes scalarMul(bcos::bytes const& _scalarA, bcos::bytes const& _scalarB) const override; + + EcGroup const& group() const { return m_group; } + EcPoint hashToCurveImpl(bcos::bytes const& _hashData) const; + BigNum generateRandomScalarImpl() const + { + bcos::bytes result; + result.resize(m_keySize); + if (RAND_bytes(result.data(), m_keySize) != 1) + { + BOOST_THROW_EXCEPTION(GenerateRandomScalarError()); + } + return BigNum(bcos::bytesConstRef(result.data(), result.size()), m_group.n(), false); + } + + // get the multiplicative inverse of _data over the given curve + BigNum invertImpl(bcos::bytes const& _data) const + { + BigNum value(bcos::bytesConstRef(_data.data(), _data.size())); + return value.Invert(m_group.n()); + } + + BigNum addImpl(bcos::bytes const& _data1, bcos::bytes const& _data2) const + { + BigNum value1(bcos::bytesConstRef(_data1.data(), _data1.size())); + BigNum value2(bcos::bytesConstRef(_data2.data(), _data2.size())); + return value1.add(value2, m_group.n()); + } + + BigNum subImpl(bcos::bytes const& _data1, bcos::bytes const& _data2) const + { + BigNum value1(bcos::bytesConstRef(_data1.data(), _data1.size())); + BigNum value2(bcos::bytesConstRef(_data2.data(), _data2.size())); + return value1.sub(value2, m_group.n()); + } + + BigNum mulImpl(bcos::bytes const& _data1, bcos::bytes const& _data2) const + { + BigNum value1(bcos::bytesConstRef(_data1.data(), _data1.size())); + BigNum value2(bcos::bytesConstRef(_data2.data(), _data2.size())); + return value1.mul(value2, m_group.n()); + } + +private: + Hash::Ptr m_hashImpl; + ppc::protocol::ECCCurve m_curve; + int m_keySize; + EcGroup m_group; + + constexpr static int SM2_KEY_SIZE = 32; + constexpr static int SECP256K1_KEY_SIZE = 32; + constexpr static int P256_KEY_SIZE = 32; + + constexpr static int SM2_POINT_BYTES_LEN = 33; + constexpr static int SECP256K1_POINT_BYTES_LEN = 33; + constexpr static int P256_POINT_BYTES_LEN = 33; +}; +} // namespace ppc::crypto \ No newline at end of file diff --git a/cpp/wedpr-crypto/ppc-crypto/src/ecc/core/EcPoint.h b/cpp/wedpr-crypto/ppc-crypto/src/ecc/core/EcPoint.h new file mode 100644 index 00000000..2085f83d --- /dev/null +++ b/cpp/wedpr-crypto/ppc-crypto/src/ecc/core/EcPoint.h @@ -0,0 +1,191 @@ +/** + * Copyright (C) 2022 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 EcPoint.h + * @author: yujiechen + * @date 2022-12-5 + */ +#pragma once +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#include "../../Common.h" +#include "openssl/ec.h" +#include "openssl/obj_mac.h" +#include "ppc-framework/libwrapper/BigNum.h" +#include +#include + +namespace ppc::crypto +{ +struct EcGroupDeleter +{ +public: + void operator()(EC_GROUP* _group) { EC_GROUP_free(_group); } +}; +using EcGroupPtr = std::shared_ptr; + +///// The ec-group +class EcGroup +{ +public: + EcGroup() = default; + EcGroup(int _pointBytesLen, EC_GROUP* _group) + : m_pointBytesLen(_pointBytesLen), m_ecGroup(EcGroupPtr(_group, EcGroupDeleter())) + { + auto bnContext = createBNContext(); + // obtain the curve params + if (EC_GROUP_get_curve(m_ecGroup.get(), m_p.bn().get(), m_a.bn().get(), m_b.bn().get(), + bnContext.get()) != 1) + { + BOOST_THROW_EXCEPTION(ECGroupGetCurveError()); + } + // get the order + if (EC_GROUP_get_order(m_ecGroup.get(), m_n.bn().get(), bnContext.get()) != 1) + { + BOOST_THROW_EXCEPTION(ECGroupGetOrderError()); + } + } + EcGroup(int _pointBytesLen, int _nid) + : EcGroup(_pointBytesLen, EC_GROUP_new_by_curve_name(_nid)) + {} + BigNum const& p() const { return m_p; } + + BigNum const& a() const { return m_a; } + BigNum const& b() const { return m_b; } + BigNum const& n() const { return m_n; } + + EcGroupPtr const& ecGroup() const { return m_ecGroup; } + int pointBytesLen() const { return m_pointBytesLen; } + +private: + int m_pointBytesLen; + BigNum m_p; + BigNum m_a; + BigNum m_b; + + BigNum m_n; + EcGroupPtr m_ecGroup; +}; + +///// The ec-point +struct ECPointDeleter +{ +public: + void operator()(EC_POINT* point) { EC_POINT_clear_free(point); } +}; +using ECPointPtr = std::shared_ptr; + +class EcPoint +{ +public: + EcPoint(EcGroup _group) + : m_group(std::move(_group)), + m_point(ECPointPtr(EC_POINT_new(m_group.ecGroup().get()), ECPointDeleter())) + {} + EcPoint(EcGroup _group, bcos::bytesConstRef const& _data) : EcPoint(std::move(_group)) + { + fromBytes(_data); + } + + ~EcPoint() = default; + + // convert bytes to the point + void fromBytes(bcos::bytesConstRef const& _data) + { + auto bnContext = createBNContext(); + BigNum pointNum; + pointNum.fromBigEndianBytes((bcos::byte*)(_data.data()), _data.size(), false); + auto bn = EC_POINT_bn2point( + m_group.ecGroup().get(), pointNum.bn().get(), m_point.get(), bnContext.get()); + if (!bn) + { + BOOST_THROW_EXCEPTION(ECPointBn2PointError()); + } + } + + // convert the point to bytes + void toBytes(bcos::bytes& _data) + { + auto bnContext = createBNContext(); + unsigned char* buf = NULL; + auto bufferLen = EC_POINT_point2buf(m_group.ecGroup().get(), m_point.get(), + POINT_CONVERSION_COMPRESSED, &buf, bnContext.get()); + if (bufferLen == 0) + { + BOOST_THROW_EXCEPTION(ECPoint2BNError()); + } + _data.resize(bufferLen); + memcpy(_data.data(), buf, bufferLen); + OPENSSL_free(buf); + } + + // ecMultiply + EcPoint ecMultiply(BigNum const& _sk) const + { + auto bnContext = createBNContext(); + EcPoint result(m_group); + if (EC_POINT_mul(m_group.ecGroup().get(), result.point().get(), NULL, m_point.get(), + _sk.bn().get(), bnContext.get()) != 1) + { + BOOST_THROW_EXCEPTION(ECPointMulError()); + } + return result; + } + + EcPoint add(EcPoint const& _point) const + { + auto bnContext = createBNContext(); + EcPoint result(m_group); + if (EC_POINT_add(m_group.ecGroup().get(), result.point().get(), m_point.get(), + _point.point().get(), bnContext.get()) != 1) + { + BOOST_THROW_EXCEPTION(ECPointAddError()); + } + return result; + } + + EcPoint sub(EcPoint& _point) const + { + auto bnContext = createBNContext(); + // invert the point + if (EC_POINT_invert(m_group.ecGroup().get(), _point.point().get(), bnContext.get()) != 1) + { + BOOST_THROW_EXCEPTION( + ECPointSubError() << bcos::errinfo_comment("EcPoint sub error for invert failed")); + } + return add(_point); + } + + EcGroup const& group() const { return m_group; } + ECPointPtr const& point() const { return m_point; } + +private: + EcGroup m_group; + ECPointPtr m_point; +}; + +// basePointMultiply +inline EcPoint basePointMultiply(EcGroup const& _group, BigNum const& _sk) +{ + auto bnContext = createBNContext(); + EcPoint result(_group); + if (EC_POINT_mul(_group.ecGroup().get(), result.point().get(), _sk.bn().get(), NULL, NULL, + bnContext.get()) != 1) + { + BOOST_THROW_EXCEPTION(ECPointMulError()); + } + return result; +} + +} // namespace ppc::crypto \ No newline at end of file diff --git a/cpp/wedpr-crypto/ppc-crypto/src/oprf/EcdhOprf.cpp b/cpp/wedpr-crypto/ppc-crypto/src/oprf/EcdhOprf.cpp new file mode 100644 index 00000000..dd791aae --- /dev/null +++ b/cpp/wedpr-crypto/ppc-crypto/src/oprf/EcdhOprf.cpp @@ -0,0 +1,183 @@ +/** + * Copyright (C) 2022 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 EcdhOprf.cpp + * @author: shawnhe + * @date 2022-11-3 + */ + +#include "EcdhOprf.h" +#include "../Common.h" +#include + +using namespace ppc::protocol; +using namespace ppc::crypto; + +// H1(_input)^r +bcos::bytes ppc::crypto::EcdhOprfClient::blind(std::string_view _input) const +{ + bcos::bytesConstRef inputData((const unsigned char*)_input.data(), _input.size()); + auto hashResult = m_hash->hash(inputData); + auto ecPoint = m_eccCrypto->hashToCurve(hashResult); + + return m_eccCrypto->ecMultiply(ecPoint, m_privateKey); +} + +bcos::bytes ppc::crypto::EcdhOprfClient::blind(const bcos::bytes& _input) const +{ + bcos::bytesConstRef inputData(_input.data(), _input.size()); + auto hashResult = m_hash->hash(inputData); + auto ecPoint = m_eccCrypto->hashToCurve(hashResult); + + return m_eccCrypto->ecMultiply(ecPoint, m_privateKey); +} + +std::vector ppc::crypto::EcdhOprfClient::blind( + const std::vector& _inputs) const +{ + auto inputsSize = _inputs.size(); + + std::vector results; + results.reserve(inputsSize); + results.resize(inputsSize); + + tbb::parallel_for(tbb::blocked_range(0U, inputsSize), [&](auto const& range) { + for (auto i = range.begin(); i < range.end(); i++) + { + results[i] = blind(_inputs[i]); + } + }); + return results; +} + +// H2(_input,_evaluatedItem^(1/r)) +bcos::bytes ppc::crypto::EcdhOprfClient::finalize( + std::string_view _input, const bcos::bytes& _evaluatedItem) const +{ + auto invertR = m_eccCrypto->scalarInvert(m_privateKey); + auto unblindedItem = m_eccCrypto->ecMultiply(_evaluatedItem, invertR); + + auto hashState = m_hash->init(); + bcos::bytesConstRef inputData((const unsigned char*)_input.data(), _input.size()); + m_hash->update(hashState, inputData); + m_hash->update(hashState, + bcos::bytesConstRef((const unsigned char*)unblindedItem.data(), unblindedItem.size())); + + auto finalH = m_hash->final(hashState); + finalH.resize(m_outputSize); + return finalH; +} + +std::vector ppc::crypto::EcdhOprfClient::finalize( + const std::vector& _inputs, const std::vector& _evaluatedItems) const +{ + auto inputsSize = _inputs.size(); + if (inputsSize != _evaluatedItems.size()) + { + BOOST_THROW_EXCEPTION(OprfFinalizeException() << bcos::errinfo_comment( + "The number of input does not match the evaluated element")); + } + + std::vector results; + results.reserve(inputsSize); + results.resize(inputsSize); + + tbb::parallel_for(tbb::blocked_range(0U, inputsSize), [&](auto const& range) { + for (auto i = range.begin(); i < range.end(); i++) + { + results[i] = finalize(_inputs[i], _evaluatedItems[i]); + } + }); + + return results; +} + +// (_blindedItem)^sk +bcos::bytes EcdhOprfServer::evaluate(const bcos::bytes& _blindedItem) const +{ + return m_eccCrypto->ecMultiply(_blindedItem, m_privateKey); +} + +std::vector ppc::crypto::EcdhOprfServer::evaluate( + const std::vector& _blindedItems) const +{ + auto inputsSize = _blindedItems.size(); + + std::vector results; + results.reserve(inputsSize); + results.resize(inputsSize); + + tbb::parallel_for(tbb::blocked_range(0U, inputsSize), [&](auto const& range) { + for (auto i = range.begin(); i < range.end(); i++) + { + results[i] = evaluate(_blindedItems[i]); + } + }); + + return results; +} + +// OPRF(_input, sk) = H2(x, H1(_input)^sk) +bcos::bytes ppc::crypto::EcdhOprfServer::fullEvaluate(const bcos::bytes& _input) const +{ + bcos::bytesConstRef inputData(_input.data(), _input.size()); + auto hashResult = m_hash->hash(inputData); + auto ecPoint = m_eccCrypto->hashToCurve(hashResult); + auto blindedItem = m_eccCrypto->ecMultiply(ecPoint, m_privateKey); + + auto hashState = m_hash->init(); + m_hash->update(hashState, inputData); + m_hash->update(hashState, + bcos::bytesConstRef((const unsigned char*)blindedItem.data(), blindedItem.size())); + + auto finalH = m_hash->final(hashState); + finalH.resize(m_outputSize); + return finalH; +} + +bcos::bytes ppc::crypto::EcdhOprfServer::fullEvaluate(const std::string_view _input) const +{ + bcos::bytesConstRef inputData((const unsigned char*)_input.data(), _input.size()); + auto hashResult = m_hash->hash(inputData); + auto ecPoint = m_eccCrypto->hashToCurve(hashResult); + auto blindedItem = m_eccCrypto->ecMultiply(ecPoint, m_privateKey); + + auto hashState = m_hash->init(); + m_hash->update(hashState, inputData); + m_hash->update(hashState, + bcos::bytesConstRef((const unsigned char*)blindedItem.data(), blindedItem.size())); + + auto finalH = m_hash->final(hashState); + finalH.resize(m_outputSize); + return finalH; +} + +std::vector ppc::crypto::EcdhOprfServer::fullEvaluate( + const std::vector& _inputs) const +{ + auto inputsSize = _inputs.size(); + + std::vector results; + results.reserve(inputsSize); + results.resize(inputsSize); + + tbb::parallel_for(tbb::blocked_range(0U, inputsSize), [&](auto const& range) { + for (auto i = range.begin(); i < range.end(); i++) + { + results[i] = fullEvaluate(_inputs[i]); + } + }); + return results; +} diff --git a/cpp/wedpr-crypto/ppc-crypto/src/oprf/EcdhOprf.h b/cpp/wedpr-crypto/ppc-crypto/src/oprf/EcdhOprf.h new file mode 100644 index 00000000..44dedbd0 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-crypto/src/oprf/EcdhOprf.h @@ -0,0 +1,115 @@ +/** + * Copyright (C) 2022 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 EcdhOprf.h + * @author: shawnhe + * @date 2022-11-3 + */ + +#pragma once +#include "ppc-framework/crypto/EccCrypto.h" +#include "ppc-framework/crypto/Hash.h" +#include "ppc-framework/crypto/Oprf.h" + +namespace ppc::crypto +{ +/** + * + * reference: JKK14 + * title: Round-optimal password-protected secret sharing and T-PAKE in the password-only model + * url: https://eprint.iacr.org/2014/650.pdf + * + * OPRF(x, sk) = H2(x, H1(x)^sk) + * + * Client: y, r Server: x, sk + * ------------------------------------------------------------------------------------- + * blindedElement = H1(y)^r + * + * blindedElement + * ----------> + * + * evaluatedElement = H1(y)^r)^sk + * + * evaluatedElement + * <---------- + * + * output = H2(y,(H1(y)^r)^sk^(1/r))=H2(y,H1(y)^sk) + */ + +class EcdhOprfClient : public OprfClient +{ +public: + using Ptr = std::shared_ptr; + EcdhOprfClient() = delete; + EcdhOprfClient(uint16_t _outputSize, Hash::Ptr _hash, EccCrypto::Ptr _eccCrypto) + : OprfClient(ppc::protocol::OprfType::EcdhOprf, _outputSize), + m_hash(std::move(_hash)), + m_eccCrypto(std::move(_eccCrypto)) + { + m_type = protocol::OprfType::EcdhOprf; + + // init private key + m_privateKey = m_eccCrypto->generateRandomScalar(); + } + + virtual ~EcdhOprfClient() = default; + + // blind input by private key + bcos::bytes blind(const bcos::bytes& _input) const override; + bcos::bytes blind(std::string_view _input) const override; + std::vector blind(const std::vector& _inputs) const override; + + // unblind evaluated item, and hash with input + bcos::bytes finalize(std::string_view _input, const bcos::bytes& _evaluatedItem) const override; + std::vector finalize(const std::vector& _inputs, + const std::vector& _evaluatedItems) const override; + +private: + Hash::Ptr m_hash; + EccCrypto::Ptr m_eccCrypto; +}; + +class EcdhOprfServer : public OprfServer +{ +public: + using Ptr = std::shared_ptr; + EcdhOprfServer() = delete; + EcdhOprfServer(uint16_t _outputSize, Hash::Ptr _hash, EccCrypto::Ptr _eccCrypto) + : OprfServer(ppc::protocol::OprfType::EcdhOprf, _outputSize), + m_hash(std::move(_hash)), + m_eccCrypto(std::move(_eccCrypto)) + { + m_type = protocol::OprfType::EcdhOprf; + + // init private key + m_privateKey = m_eccCrypto->generateRandomScalar(); + } + + virtual ~EcdhOprfServer() = default; + + // evaluate blinded item by private key + bcos::bytes evaluate(const bcos::bytes& _blindedItem) const override; + std::vector evaluate(const std::vector& _blindedItems) const override; + + // compute the OPRF output with server's private key + bcos::bytes fullEvaluate(const bcos::bytes& _input) const override; + bcos::bytes fullEvaluate(const std::string_view _input) const override; + std::vector fullEvaluate(const std::vector& _inputs) const override; + +private: + Hash::Ptr m_hash; + EccCrypto::Ptr m_eccCrypto; +}; +} // namespace ppc::crypto \ No newline at end of file diff --git a/cpp/wedpr-crypto/ppc-crypto/src/oprf/RA2018Oprf.cpp b/cpp/wedpr-crypto/ppc-crypto/src/oprf/RA2018Oprf.cpp new file mode 100644 index 00000000..66d9513d --- /dev/null +++ b/cpp/wedpr-crypto/ppc-crypto/src/oprf/RA2018Oprf.cpp @@ -0,0 +1,78 @@ +/** + * Copyright (C) 2022 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 RA2018Oprf.cpp + * @author: yujiechen + * @date 2022-12-6 + */ +#include "RA2018Oprf.h" + +using namespace ppc::crypto; +using namespace ppc::io; +using namespace bcos; + +void RA2018Oprf::blind(ppc::io::DataBatch::Ptr const& _plainData, bcos::bytes const& _privateKey, + std::vector& _blindResult) +{ + // H1(yj)^Bj + _blindResult.resize(_plainData->size()); + tbb::parallel_for(tbb::blocked_range(0U, _plainData->size()), [&](auto const& range) { + for (auto i = range.begin(); i < range.end(); i++) + { + blindImpl(_plainData->getBytes(i), _privateKey, _blindResult[i]); + } + }); +} + + +void RA2018Oprf::finalize(std::vector const& _evaluatedData, + bcos::bytes const& _invPrivateKey, std::vector& _finalizedResult) +{ + _finalizedResult.resize(_evaluatedData.size()); + // (aj)^(1/Bj) + tbb::parallel_for( + tbb::blocked_range(0U, _evaluatedData.size()), [&](auto const& range) { + for (auto i = range.begin(); i < range.end(); i++) + { + finalizeImpl(_invPrivateKey, _evaluatedData.at(i), _finalizedResult[i]); + } + }); +} + +void RA2018Oprf::fullEvaluate( + ppc::io::DataBatch::Ptr const& _input, std::vector& _result) +{ + _result.resize(_input->size()); + // H1(xi)^aj + tbb::parallel_for(tbb::blocked_range(0U, _input->size()), [&](auto const& range) { + for (auto i = range.begin(); i < range.end(); i++) + { + fullEvaluateImpl(_input->get(i), _result[i]); + } + }); +} + +void RA2018Oprf::evaluate( + std::vector const& _blindData, std::vector& _result) +{ + _result.resize(_blindData.size()); + // (aj)^a + tbb::parallel_for(tbb::blocked_range(0U, _blindData.size()), [&](auto const& range) { + for (auto i = range.begin(); i < range.end(); i++) + { + evaluateImpl(_blindData.at(i), _result[i]); + } + }); +} diff --git a/cpp/wedpr-crypto/ppc-crypto/src/oprf/RA2018Oprf.h b/cpp/wedpr-crypto/ppc-crypto/src/oprf/RA2018Oprf.h new file mode 100644 index 00000000..6b70ecda --- /dev/null +++ b/cpp/wedpr-crypto/ppc-crypto/src/oprf/RA2018Oprf.h @@ -0,0 +1,88 @@ +/** + * Copyright (C) 2022 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 RA2018Oprf.h + * @author: yujiechen + * @date 2022-12-6 + */ +#pragma once +#include "../ecc/OpenSSLEccCrypto.h" +#include "ppc-framework/crypto/EccCrypto.h" +#include "ppc-framework/crypto/Hash.h" +#include "ppc-framework/crypto/RA2018OprfInterface.h" +#include "ppc-framework/io/DataBatch.h" +#include +#include + +namespace ppc::crypto +{ +class RA2018Oprf : public RA2018OprfInterface +{ +public: + using Ptr = std::shared_ptr; + RA2018Oprf(bcos::bytes _privateKey, EccCrypto::Ptr _eccCrypto, Hash::Ptr _hashImpl) + : m_privateKey(std::move(_privateKey)), m_eccCrypto(_eccCrypto), m_hashImpl(_hashImpl) + {} + ~RA2018Oprf() override = default; + + bcos::bytes generatePrivateKey() override { return m_eccCrypto->generateRandomScalar(); } + bcos::bytes inv(bcos::bytes const& _data) override { return m_eccCrypto->scalarInvert(_data); } + + void blind(ppc::io::DataBatch::Ptr const& _plainData, bcos::bytes const& _privateKey, + std::vector& _blindResult) override; + + void finalize(std::vector const& _evaluatedData, bcos::bytes const& _invPrivateKey, + std::vector& _finalizedResult) override; + + void fullEvaluate( + ppc::io::DataBatch::Ptr const& _input, std::vector& _result) override; + void evaluate( + std::vector const& _blindData, std::vector& _result) override; + + +protected: + virtual void blindImpl( + bcos::bytes const& _input, bcos::bytes const& _privateKey, bcos::bytes& _blindResult) + { + auto hashResult = m_hashImpl->hash(bcos::bytesConstRef(_input.data(), _input.size())); + auto ecPoint = m_eccCrypto->hashToCurve(std::move(hashResult)); + _blindResult = m_eccCrypto->ecMultiply(ecPoint, _privateKey); + } + + virtual void finalizeImpl(bcos::bytes const& _invPrivateKey, bcos::bytes const& _evaluatedData, + bcos::bytes& _finalizedResult) + { + // recover the plainData + _finalizedResult = m_eccCrypto->ecMultiply(_evaluatedData, _invPrivateKey); + } + virtual void fullEvaluateImpl(bcos::bytes const& _input, bcos::bytes& _result) + { + auto hashResult = m_hashImpl->hash( + bcos::bytesConstRef((const unsigned char*)_input.data(), _input.size())); + auto ecPoint = m_eccCrypto->hashToCurve(std::move(hashResult)); + _result = m_eccCrypto->ecMultiply(ecPoint, m_privateKey); + } + + virtual void evaluateImpl(bcos::bytes const& _blindData, bcos::bytes& _result) + { + _result = m_eccCrypto->ecMultiply(_blindData, m_privateKey); + } + +protected: + bcos::bytes m_privateKey; + EccCrypto::Ptr m_eccCrypto; + Hash::Ptr m_hashImpl; +}; +} // namespace ppc::crypto \ No newline at end of file diff --git a/cpp/wedpr-crypto/ppc-crypto/src/prng/AESPRNG.cpp b/cpp/wedpr-crypto/ppc-crypto/src/prng/AESPRNG.cpp new file mode 100644 index 00000000..145ca91f --- /dev/null +++ b/cpp/wedpr-crypto/ppc-crypto/src/prng/AESPRNG.cpp @@ -0,0 +1,76 @@ +/** + * Copyright (C) 2022 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 AESPRNG.cpp + * @author: shawnhe + * @date 2022-11-29 + */ + +#include "AESPRNG.h" +#include + +namespace ppc::crypto +{ +// generate `_bytesLen` bytes random numbers +void AESPRNG::generate(bcos::byte* _dest, uint64_t _bytesLen) +{ + uint64_t bytesIdx = m_totalOutputs % BUFFER_CAPACITY; + + uint64_t step = std::min(_bytesLen, BUFFER_CAPACITY - bytesIdx); + memcpy(_dest, m_buffer.data() + bytesIdx, step); + _dest += step; + m_totalOutputs += step; + + _bytesLen -= step; + uint64_t round = _bytesLen / BUFFER_CAPACITY; + uint64_t remain = _bytesLen % BUFFER_CAPACITY; + + if (round) + { + parallelGen(_dest, m_totalOutputs / BUFFER_CAPACITY, round); + _dest += round * BUFFER_CAPACITY; + m_totalOutputs += round * BUFFER_CAPACITY; + } + + uint64_t currentIndex = m_totalOutputs / BUFFER_CAPACITY; + bcos::bytes indexData( + (bcos::byte*)(¤tIndex), (bcos::byte*)(¤tIndex) + sizeof(uint64_t)); + indexData.resize(BUFFER_CAPACITY); + m_buffer = m_aes->encrypt( + SymCrypto::OperationMode::CBC, bcos::ref(m_key), bcos::ref(m_iv), bcos::ref(indexData)); + + if (remain) + { + memcpy(_dest, m_buffer.data(), remain); + m_totalOutputs += remain; + } +} + +void AESPRNG::parallelGen(bcos::byte* _dest, uint64_t _currentRound, uint64_t _remainRound) +{ + tbb::parallel_for(tbb::blocked_range(0U, _remainRound), [&](auto const& range) { + for (auto i = range.begin(); i < range.end(); i++) + { + uint64_t currentIndex = _currentRound + i; + bcos::bytes indexData(BUFFER_CAPACITY); + memcpy(indexData.data(), (bcos::byte*)(¤tIndex), sizeof(uint64_t)); + auto temp = m_aes->encrypt(SymCrypto::OperationMode::CBC, bcos::ref(m_key), + bcos::ref(m_iv), bcos::ref(indexData)); + memcpy(_dest + i * BUFFER_CAPACITY, temp.data(), BUFFER_CAPACITY); + } + }); +} + +} // namespace ppc::crypto diff --git a/cpp/wedpr-crypto/ppc-crypto/src/prng/AESPRNG.h b/cpp/wedpr-crypto/ppc-crypto/src/prng/AESPRNG.h new file mode 100644 index 00000000..c69b960a --- /dev/null +++ b/cpp/wedpr-crypto/ppc-crypto/src/prng/AESPRNG.h @@ -0,0 +1,61 @@ +/** + * Copyright (C) 2022 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 AESPRNG.h + * @author: shawnhe + * @date 2022-11-29 + */ + +#pragma once +#include "ppc-crypto-core/src/sym-crypto/OpenSSLAES.h" +#include "ppc-framework/crypto/PRNG.h" + +namespace ppc::crypto +{ +class AESPRNG : public PRNG +{ +public: + using Ptr = std::shared_ptr; + static constexpr uint64_t BUFFER_CAPACITY = 1024; + + // default constructor is not allowed + AESPRNG() = delete; + virtual ~AESPRNG() = default; + + AESPRNG(const bcos::bytes& _seed) : PRNG(_seed), m_key(_seed), m_iv(bcos::byte()) + { + m_aes = std::make_shared(OpenSSLAES::AESType::AES128); + bcos::bytes index(BUFFER_CAPACITY); + m_buffer = m_aes->encrypt( + SymCrypto::OperationMode::CBC, bcos::ref(m_key), bcos::ref(m_iv), bcos::ref(index)); + } + + ppc::protocol::PRNGImplName type() const override { return ppc::protocol::PRNGImplName::AES; } + + // generate `_bytesLen` bytes random numbers, saved in _dest + void generate(bcos::byte* _dest, uint64_t _bytesLen) override; + +private: + void parallelGen(bcos::byte* _dest, uint64_t _currentRound, uint64_t _remainRound); + + OpenSSLAES::Ptr m_aes; + bcos::bytes m_key; + bcos::bytes m_iv; + + // record current buffer + bcos::bytes m_buffer; +}; + +} // namespace ppc::crypto diff --git a/cpp/wedpr-crypto/ppc-crypto/src/prng/BLAKE2bPRNG.cpp b/cpp/wedpr-crypto/ppc-crypto/src/prng/BLAKE2bPRNG.cpp new file mode 100644 index 00000000..a8907360 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-crypto/src/prng/BLAKE2bPRNG.cpp @@ -0,0 +1,74 @@ +/** + * Copyright (C) 2022 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 BLAKE2bPRNG.cpp + * @author: shawnhe + * @date 2022-12-4 + */ + +#include "BLAKE2bPRNG.h" +#include + +namespace ppc::crypto +{ + +// generate `_bytesLen` bytes random numbers +void BLAKE2bPRNG::generate(bcos::byte* _dest, uint64_t _bytesLen) +{ + uint64_t bytesIdx = m_totalOutputs % BUFFER_CAPACITY; + + uint64_t step = std::min(_bytesLen, BUFFER_CAPACITY - bytesIdx); + memcpy(_dest, m_buffer.data() + bytesIdx, step); + _dest += step; + m_totalOutputs += step; + + _bytesLen -= step; + uint64_t round = _bytesLen / BUFFER_CAPACITY; + uint64_t remain = _bytesLen % BUFFER_CAPACITY; + + if (round) + { + parallelGen(_dest, m_totalOutputs / BUFFER_CAPACITY, round); + _dest += round * BUFFER_CAPACITY; + m_totalOutputs += round * BUFFER_CAPACITY; + } + + uint64_t currentIndex = m_totalOutputs / BUFFER_CAPACITY; + bcos::bytes indexData( + (bcos::byte*)(¤tIndex), (bcos::byte*)(¤tIndex) + sizeof(uint64_t)); + m_buffer = m_blake2Hash->hash(bcos::ref(indexData), bcos::ref(m_seeds), BUFFER_CAPACITY); + + if (remain) + { + memcpy(_dest, m_buffer.data(), remain); + m_totalOutputs += remain; + } +} + +void BLAKE2bPRNG::parallelGen(bcos::byte* _dest, uint64_t _currentRound, uint64_t _remainRound) +{ + tbb::parallel_for(tbb::blocked_range(0U, _remainRound), [&](auto const& range) { + for (auto i = range.begin(); i < range.end(); i++) + { + uint64_t currentIndex = _currentRound + i; + bcos::bytes indexData( + (bcos::byte*)(¤tIndex), (bcos::byte*)(¤tIndex) + sizeof(uint64_t)); + auto temp = m_blake2Hash->hash(bcos::ref(indexData), bcos::ref(m_seeds), BUFFER_CAPACITY); + memcpy(_dest + i * BUFFER_CAPACITY, temp.data(), BUFFER_CAPACITY); + } + }); +} + +} // namespace ppc::crypto diff --git a/cpp/wedpr-crypto/ppc-crypto/src/prng/BLAKE2bPRNG.h b/cpp/wedpr-crypto/ppc-crypto/src/prng/BLAKE2bPRNG.h new file mode 100644 index 00000000..62904e0f --- /dev/null +++ b/cpp/wedpr-crypto/ppc-crypto/src/prng/BLAKE2bPRNG.h @@ -0,0 +1,61 @@ +/** + * Copyright (C) 2022 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 BLAKE2bPRNG.h + * @author: shawnhe + * @date 2022-12-4 + */ + +#pragma once +#include "ppc-crypto-core/src/hash/BLAKE2bHash.h" +#include "ppc-framework/crypto/PRNG.h" + +namespace ppc::crypto +{ +class BLAKE2bPRNG : public PRNG +{ +public: + using Ptr = std::shared_ptr; + static constexpr uint32_t BUFFER_CAPACITY = 64; + + // default constructor is not allowed + BLAKE2bPRNG() = delete; + virtual ~BLAKE2bPRNG() = default; + + BLAKE2bPRNG(const bcos::bytes& _seed) : PRNG(_seed) + { + m_blake2Hash = std::make_shared(); + bcos::bytes index(BUFFER_CAPACITY); + m_buffer = m_blake2Hash->hash(bcos::ref(index), bcos::ref(m_seeds), BUFFER_CAPACITY); + } + + ppc::protocol::PRNGImplName type() const override + { + return ppc::protocol::PRNGImplName::BLAKE2b; + } + + // generate `_bytesLen` bytes random numbers, saved in _dest + void generate(bcos::byte* _dest, uint64_t _bytesLen) override; + +private: + void parallelGen(bcos::byte* _dest, uint64_t _currentRound, uint64_t _remainRound); + + BLAKE2bHash::Ptr m_blake2Hash; + + // record current buffer + bcos::bytes m_buffer; +}; + +} // namespace ppc::crypto diff --git a/cpp/wedpr-crypto/ppc-crypto/src/randomot/SimplestOT.cpp b/cpp/wedpr-crypto/ppc-crypto/src/randomot/SimplestOT.cpp new file mode 100644 index 00000000..ed330a8d --- /dev/null +++ b/cpp/wedpr-crypto/ppc-crypto/src/randomot/SimplestOT.cpp @@ -0,0 +1,100 @@ +/** + * Copyright (C) 2021 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 SimplestOT.cpp + * @author: shawnhe + * @date 2022-07-06 + */ + +#include "SimplestOT.h" +#include + +using namespace ppc::crypto; +using namespace ppc::protocol; + +std::pair> SimplestOT::receiverGeneratePointsB( + BitVector::Ptr _choices, bcos::bytesPointer _pointA) +{ + auto otNumber = _choices->size(); + bcos::bytesPointer bytesB = std::make_shared(otNumber * m_ecc->pointSizeInBytes()); + std::vector scalars(otNumber); + + for (uint32_t i = 0; i < otNumber; ++i) + { + scalars[i] = m_ecc->generateRandomScalar(); + std::array pairB; + pairB[0] = m_ecc->mulGenerator(scalars[i]); + pairB[1] = m_ecc->ecAdd(*_pointA, pairB[0]); + memcpy(bytesB->data() + i * m_ecc->pointSizeInBytes(), pairB[_choices->get(i)].data(), + m_ecc->pointSizeInBytes()); + } + + return {bytesB, scalars}; +} + +std::vector SimplestOT::finishReceiver( + bcos::bytesPointer _pointA, std::vector _bScalars) +{ + auto otNumber = _bScalars.size(); + std::vector keys(otNumber); + + for (uint32_t i = 0; i < otNumber; ++i) + { + auto point = m_ecc->ecMultiply(*_pointA, _bScalars[i]); + auto state = m_hash->init(); + m_hash->update(state, bcos::ref(point)); + bcos::bytes indexData((bcos::byte*)(&i), (bcos::byte*)(&i) + sizeof(uint32_t)); + m_hash->update(state, bcos::ref(indexData)); + keys[i] = m_hash->final(state); + } + return keys; +} + +std::pair SimplestOT::senderGeneratePointA() +{ + auto a = m_ecc->generateRandomScalar(); + auto A = m_ecc->mulGenerator(a); + return {a, std::make_shared(A)}; +} + +std::vector> SimplestOT::finishSender( + bcos::bytes _aScalar, bcos::bytesPointer _pointA, bcos::bytesPointer _pointsB) +{ + uint32_t otNumber = _pointsB->size() / m_ecc->pointSizeInBytes(); + std::vector> keys(otNumber); + + auto A = m_ecc->ecMultiply(*_pointA, _aScalar); + + for (uint32_t i = 0; i < otNumber; ++i) + { + bcos::bytes indexData((bcos::byte*)(&i), (bcos::byte*)(&i) + sizeof(uint32_t)); + + bcos::bytes B(_pointsB->begin() + i * m_ecc->pointSizeInBytes(), + _pointsB->begin() + (i + 1) * m_ecc->pointSizeInBytes()); + auto point0 = m_ecc->ecMultiply(B, _aScalar); + auto state0 = m_hash->init(); + m_hash->update(state0, bcos::ref(point0)); + m_hash->update(state0, bcos::ref(indexData)); + keys[i][0] = m_hash->final(state0); + + auto point1 = m_ecc->ecSub(point0, A); + auto state1 = m_hash->init(); + m_hash->update(state1, bcos::ref(point1)); + m_hash->update(state1, bcos::ref(indexData)); + keys[i][1] = m_hash->final(state1); + } + + return keys; +} diff --git a/cpp/wedpr-crypto/ppc-crypto/src/randomot/SimplestOT.h b/cpp/wedpr-crypto/ppc-crypto/src/randomot/SimplestOT.h new file mode 100644 index 00000000..425ca330 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-crypto/src/randomot/SimplestOT.h @@ -0,0 +1,65 @@ +/** + * Copyright (C) 2022 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 SimplestOT.h + * @author: shawnhe + * @date 2022-12-5 + */ + +#pragma once + +#include "ppc-crypto-core/src/tools/BitVector.h" +#include "ppc-framework/Common.h" +#include "ppc-framework/crypto/EccCrypto.h" +#include "ppc-framework/crypto/Hash.h" +#include "ppc-framework/protocol/Protocol.h" +#include +#include + +namespace ppc::crypto +{ +class SimplestOT : public std::enable_shared_from_this +{ +public: + using Ptr = std::shared_ptr; + + SimplestOT() = delete; + ~SimplestOT() = default; + + SimplestOT(EccCrypto::Ptr _ecc, Hash::Ptr _hash) + : m_ecc(std::move(_ecc)), m_hash(std::move(_hash)) + {} + + // receive point A and evaluate multi points B, return Bs bytes and multi scalar bs bytes + std::pair> receiverGeneratePointsB( + BitVector::Ptr _choices, bcos::bytesPointer _pointA); + + // return keys + std::vector finishReceiver( + bcos::bytesPointer _pointA, std::vector _bScalars); + + // generate a random point A + std::pair senderGeneratePointA(); + + // receive multi points B and generate keys + std::vector> finishSender( + bcos::bytes _aScalar, bcos::bytesPointer _pointA, bcos::bytesPointer _pointsB); + +private: + EccCrypto::Ptr m_ecc; + Hash::Ptr m_hash; +}; + +} // namespace ppc::crypto diff --git a/cpp/wedpr-crypto/ppc-crypto/tests/CMakeLists.txt b/cpp/wedpr-crypto/ppc-crypto/tests/CMakeLists.txt new file mode 100644 index 00000000..cb482575 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-crypto/tests/CMakeLists.txt @@ -0,0 +1,10 @@ +file(GLOB_RECURSE SOURCES "*.cpp" "*.h") + +# cmake settings +set(TEST_BINARY_NAME test-ppc-crypto) + +add_executable(${TEST_BINARY_NAME} ${SOURCES}) +target_include_directories(${TEST_BINARY_NAME} PRIVATE .) + +target_link_libraries(${TEST_BINARY_NAME} ${CRYPTO_TARGET} ${BOOST_UNIT_TEST}) +add_test(NAME test-crypto WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} COMMAND ${TEST_BINARY_NAME}) \ No newline at end of file diff --git a/cpp/wedpr-crypto/ppc-crypto/tests/TestEccCrypto.cpp b/cpp/wedpr-crypto/ppc-crypto/tests/TestEccCrypto.cpp new file mode 100644 index 00000000..7b5c561d --- /dev/null +++ b/cpp/wedpr-crypto/ppc-crypto/tests/TestEccCrypto.cpp @@ -0,0 +1,264 @@ +/* + * Copyright (C) 2022 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 applicabl 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 TestEccCrypto.cpp + * @author: yujiechen + * @date 2022-11-2 + */ +#include "ppc-crypto-core/src/hash/SM3Hash.h" +#include "ppc-crypto-core/src/hash/Sha256Hash.h" +#include "ppc-crypto-core/src/hash/Sha512Hash.h" +#include "ppc-crypto/src/Common.h" +#include "ppc-crypto/src/ecc/ECDHCryptoImpl.h" +#include "ppc-crypto/src/ecc/Ed25519EccCrypto.h" +#include "ppc-crypto/src/ecc/IppECDHCryptoImpl.h" +#include "ppc-crypto/src/ecc/OpenSSLEccCrypto.h" +#include "ppc-framework/io/DataBatch.h" +#include +#include +#include + +using namespace ppc::crypto; +using namespace ppc::protocol; +using namespace bcos; +using namespace ppc::io; +using namespace bcos::test; + +namespace ppc::test +{ +BOOST_FIXTURE_TEST_SUITE(eccCryptoTest, TestPromptFixture) + +void testOpenSSLEccCrypto(OpenSSLEccCrypto::Ptr _eccCryptoImpl, Hash::Ptr _hashImpl) +{ + std::string inputStr = "wer234lkejskdf"; + bcos::bytes inputData(inputStr.begin(), inputStr.end()); + auto hashResult = _hashImpl->hash(ref(inputData)); + + auto ecPointBytes = _eccCryptoImpl->hashToCurve(hashResult); + + EcPoint point(_eccCryptoImpl->group(), ref(ecPointBytes)); + bcos::bytes result; + point.toBytes(result); + BOOST_CHECK(ecPointBytes == result); + + EcPoint decodedPoint(_eccCryptoImpl->group(), ref(result)); + bcos::bytes result2; + decodedPoint.toBytes(result2); + BOOST_CHECK(result == result2); +} + +void testEccCrypto( + EccCrypto::Ptr _eccCryptoImpl, Hash::Ptr _hashImpl, bool _ed25519, bool _testIppCrypto) +{ + std::string inputStr = "wer234lkejskdf"; + bcos::bytes inputData(inputStr.begin(), inputStr.end()); + auto hashResult = _hashImpl->hash(ref(inputData)); + + // test hashToCurve + auto randomScalar = _eccCryptoImpl->generateRandomScalar(); + auto invRandomScalar = _eccCryptoImpl->scalarInvert(randomScalar); + // check the scalarInvert value + for (int i = 0; i < 1000; i++) + { + BOOST_CHECK(invRandomScalar == _eccCryptoImpl->scalarInvert(randomScalar)); + } + + // scalarInvert the invRandomScalar + std::cout << "#### randomScalar: " << *toHexString(randomScalar) << std::endl; + std::cout << "#### invRandomScalar : " << *toHexString(invRandomScalar) << std::endl; + std::cout << "#### invinvRandomScalar : " + << *toHexString(_eccCryptoImpl->scalarInvert(invRandomScalar)) << std::endl; + + auto ecPoint = _eccCryptoImpl->hashToCurve(hashResult); + BOOST_CHECK(_eccCryptoImpl->isValidEcPoint(ecPoint)); + // check (ecPoint^randomScalar)^invRandomScalar == ecPoint + auto multiPoint = _eccCryptoImpl->ecMultiply(ecPoint, randomScalar); + for (int i = 0; i < 1000; i++) + { + BOOST_CHECK(_eccCryptoImpl->ecMultiply(ecPoint, randomScalar) == multiPoint); + } + BOOST_CHECK(_eccCryptoImpl->isValidEcPoint(multiPoint)); + auto invPoint = _eccCryptoImpl->ecMultiply(multiPoint, invRandomScalar); + for (int i = 0; i < 1000; i++) + { + BOOST_CHECK(_eccCryptoImpl->ecMultiply(multiPoint, invRandomScalar) == invPoint); + } + BOOST_CHECK(_eccCryptoImpl->isValidEcPoint(invPoint)); + std::cout << "#### invPoint: " << *toHexString(invPoint) << std::endl; + std::cout << "#### eccPoint : " << *toHexString(ecPoint) << std::endl; + BOOST_CHECK(invPoint == ecPoint); + // check the point size + BOOST_CHECK(invPoint.size() == _eccCryptoImpl->pointSizeInBytes()); + BOOST_CHECK(ecPoint.size() == _eccCryptoImpl->pointSizeInBytes()); + + // test ecPointAdd and Sub + auto addResult = _eccCryptoImpl->ecAdd(invPoint, ecPoint); + BOOST_CHECK(_eccCryptoImpl->isValidEcPoint(addResult)); + auto subResult = _eccCryptoImpl->ecSub(addResult, invPoint); + BOOST_CHECK(_eccCryptoImpl->isValidEcPoint(subResult)); + BOOST_CHECK(subResult == ecPoint); + + + bytes invalidPoint; + BOOST_CHECK(_eccCryptoImpl->isValidEcPoint(invalidPoint) == false); + + // invalid point multipy + ecPoint.resize(16); + BOOST_CHECK_THROW(_eccCryptoImpl->ecMultiply(ecPoint, randomScalar), EcMultipleException); + // mul G + std::string scalar = "abbc1415ad291c4c2d3a6f26a2a6c7dc0da2690418e55e9fe73342b9fed69a03"; + std::string mulGPoint = "5efd75e128f35f24158920bfa597a720883d876698c52d9a02d916e46599fc11"; + if (_ed25519) + { + BOOST_CHECK( + _eccCryptoImpl->mulGenerator(*fromHexString(scalar)) == *fromHexString(mulGPoint)); + } + + // batch for mul G + for (int i = 0; i < 1000; i++) + { + BOOST_CHECK(_eccCryptoImpl->mulGenerator(randomScalar) == + _eccCryptoImpl->mulGenerator(randomScalar)); + } + // test ECDHCryptoImpl + auto cryptoBox = std::make_shared(_hashImpl, _eccCryptoImpl); + ECDHCrypto::Ptr serverEcdhCrypto = nullptr; + ECDHCrypto::Ptr clientEcdhCrypto = nullptr; + auto serverPrivateKey = _eccCryptoImpl->generateRandomScalar(); + auto clientPrivateKey = _eccCryptoImpl->generateRandomScalar(); + if (!_testIppCrypto) + { + serverEcdhCrypto = std::make_shared(serverPrivateKey, cryptoBox); + clientEcdhCrypto = std::make_shared(clientPrivateKey, cryptoBox); + } + else + { +#ifdef ENABLE_CRYPTO_MB + if (ppc::CPU_FEATURES.avx512ifma) + { + std::cout << "#### test IppECDHCryptoImpl" << std::endl; + serverEcdhCrypto = std::make_shared(serverPrivateKey, _hashImpl); + clientEcdhCrypto = std::make_shared(clientPrivateKey, _hashImpl); + } + else + { + std::cout << "#### return directly without test IppECDHCryptoImpl for not support " + "avx512ifma instruction" + << std::endl; + return; + } +#else + return; +#endif + } + // batchGetPublicKey + auto dataBatch = std::make_shared(); + dataBatch->setDataSchema(DataSchema::Bytes); + std::vector inputDatas; + for (int i = 0; i < 100; i++) + { + std::string item = std::to_string(i); + inputDatas.emplace_back(bcos::bytes(item.begin(), item.end())); + } + dataBatch->setData(std::move(inputDatas)); + + auto publicKeys = serverEcdhCrypto->batchGetPublicKey(dataBatch); + auto sharedPublicKeys1 = clientEcdhCrypto->batchGetSharedPublicKey(publicKeys); + + publicKeys = clientEcdhCrypto->batchGetPublicKey(dataBatch); + auto sharedPublicKeys2 = serverEcdhCrypto->batchGetSharedPublicKey(publicKeys); + + // check the result + BOOST_CHECK(sharedPublicKeys1.size() == sharedPublicKeys2.size()); + for (uint64_t i = 0; i < sharedPublicKeys1.size(); i++) + { + BOOST_CHECK(sharedPublicKeys1.at(i) == sharedPublicKeys2.at(i)); + } +} + +BOOST_AUTO_TEST_CASE(testEd25519EccCrypto) +{ + Hash::Ptr hashImpl = std::make_shared(); + testEccCrypto(std::make_shared(), hashImpl, true, false); + testEccCrypto(std::make_shared(), hashImpl, true, true); + + hashImpl = std::make_shared(); + testEccCrypto(std::make_shared(), hashImpl, true, false); + testEccCrypto(std::make_shared(), hashImpl, true, true); + + hashImpl = std::make_shared(); + testEccCrypto(std::make_shared(), hashImpl, true, false); + testEccCrypto(std::make_shared(), hashImpl, true, true); +} +BOOST_AUTO_TEST_CASE(testSM2EccCrypto) +{ + Hash::Ptr hashImpl = std::make_shared(); + OpenSSLEccCrypto::Ptr eccCrypto = std::make_shared(hashImpl, ECCCurve::SM2); + testOpenSSLEccCrypto(eccCrypto, hashImpl); + testEccCrypto(eccCrypto, hashImpl, false, false); + testEccCrypto(eccCrypto, hashImpl, false, true); + + hashImpl = std::make_shared(); + testOpenSSLEccCrypto(eccCrypto, hashImpl); + testEccCrypto(eccCrypto, hashImpl, false, false); + testEccCrypto(eccCrypto, hashImpl, false, true); + + hashImpl = std::make_shared(); + testOpenSSLEccCrypto(eccCrypto, hashImpl); + testEccCrypto(eccCrypto, hashImpl, false, false); + testEccCrypto(eccCrypto, hashImpl, false, true); +} + +BOOST_AUTO_TEST_CASE(testSecp256K1EccCrypto) +{ + Hash::Ptr hashImpl = std::make_shared(); + OpenSSLEccCrypto::Ptr eccCrypto = + std::make_shared(hashImpl, ECCCurve::SECP256K1); + testOpenSSLEccCrypto(eccCrypto, hashImpl); + testEccCrypto(eccCrypto, hashImpl, false, false); + testEccCrypto(eccCrypto, hashImpl, false, true); + + hashImpl = std::make_shared(); + testOpenSSLEccCrypto(eccCrypto, hashImpl); + testEccCrypto(eccCrypto, hashImpl, false, false); + testEccCrypto(eccCrypto, hashImpl, false, true); + + hashImpl = std::make_shared(); + testOpenSSLEccCrypto(eccCrypto, hashImpl); + testEccCrypto(eccCrypto, hashImpl, false, false); + testEccCrypto(eccCrypto, hashImpl, false, true); +} + +BOOST_AUTO_TEST_CASE(testP256EccCrypto) +{ + Hash::Ptr hashImpl = std::make_shared(); + OpenSSLEccCrypto::Ptr eccCrypto = std::make_shared(hashImpl, ECCCurve::P256); + testOpenSSLEccCrypto(eccCrypto, hashImpl); + testEccCrypto(eccCrypto, hashImpl, false, false); + testEccCrypto(eccCrypto, hashImpl, false, true); + + hashImpl = std::make_shared(); + testOpenSSLEccCrypto(eccCrypto, hashImpl); + testEccCrypto(eccCrypto, hashImpl, false, false); + testEccCrypto(eccCrypto, hashImpl, false, true); + + hashImpl = std::make_shared(); + testOpenSSLEccCrypto(eccCrypto, hashImpl); + testEccCrypto(eccCrypto, hashImpl, false, false); + testEccCrypto(eccCrypto, hashImpl, false, true); +} + +BOOST_AUTO_TEST_SUITE_END() +} // namespace ppc::test diff --git a/cpp/wedpr-crypto/ppc-crypto/tests/TestOprf.cpp b/cpp/wedpr-crypto/ppc-crypto/tests/TestOprf.cpp new file mode 100644 index 00000000..08dbf180 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-crypto/tests/TestOprf.cpp @@ -0,0 +1,110 @@ +/** + * Copyright (C) 2022 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 TestOprf.cpp + * @author: shawnhe + * @date 2022-11-3 + */ + +#include "ppc-crypto-core/src/hash/HashFactoryImpl.h" +#include "ppc-crypto/src/ecc/EccCryptoFactoryImpl.h" +#include +#include +#include +#include + +using namespace ppc::crypto; +using namespace bcos; +using namespace bcos::test; + +namespace ppc::test +{ +BOOST_FIXTURE_TEST_SUITE(EcdhOprfTest, TestPromptFixture) + +void runEcdhOprf(EccCrypto::Ptr _clientEcc, EccCrypto::Ptr _serverEcc, Hash::Ptr _clientHash, + Hash::Ptr _serverHash) +{ + uint16_t outputSize = 32; + auto client = std::make_shared(outputSize, _clientHash, _clientEcc); + auto server = std::make_shared(outputSize, _serverHash, _serverEcc); + + // test one item + std::string inputStr = "wer23dfddd4lkejskdf"; + bcos::bytes inputData(inputStr.begin(), inputStr.end()); + + auto blindedItem = client->blind(inputStr); + auto evaluatedItem = server->evaluate(blindedItem); + auto outputC = client->finalize(inputStr, evaluatedItem); + auto outputS = server->fullEvaluate(inputStr); + + std::cout << "#### oprf client output: " << *toHexString(outputC) << std::endl; + std::cout << "#### oprf server output: " << *toHexString(outputS) << std::endl; + BOOST_CHECK(outputC == outputS); + + // test batch + std::vector inputs; + for (uint64_t i = 0; i < 1024; i++) + { + inputs.emplace_back(inputStr + std::to_string(i)); + } + + auto blindedItems = client->blind(inputs); + auto evaluatedItems = server->evaluate(blindedItems); + auto outputCs = client->finalize(inputs, evaluatedItems); + auto outputSs = server->fullEvaluate(inputs); + + for (uint64_t i = 0; i < 1024; i++) + { + BOOST_CHECK(outputCs[i] == outputSs[i]); + } +} + + +BOOST_AUTO_TEST_CASE(testEcdhOprf) +{ + auto eccFactory = std::make_shared(); + auto hashFactory = std::make_shared(); + + // test sm + auto sm3Hash = hashFactory->createHashImpl((int8_t)ppc::protocol::HashImplName::SM3); + auto sm2Ecc0 = eccFactory->createEccCrypto((int8_t)ppc::protocol::ECCCurve::SM2, sm3Hash); + auto sm2Ecc1 = eccFactory->createEccCrypto((int8_t)ppc::protocol::ECCCurve::SM2, sm3Hash); + runEcdhOprf(sm2Ecc0, sm2Ecc1, sm3Hash, sm3Hash); + + // test others + std::vector hashSet = { + hashFactory->createHashImpl((int8_t)ppc::protocol::HashImplName::SHA256), + hashFactory->createHashImpl((int8_t)ppc::protocol::HashImplName::SHA512), + hashFactory->createHashImpl((int8_t)ppc::protocol::HashImplName::BLAKE2b)}; + + for (auto& hashImpl : hashSet) + { + std::vector eccSet0 = { + eccFactory->createEccCrypto((int8_t)ppc::protocol::ECCCurve::ED25519, hashImpl), + eccFactory->createEccCrypto((int8_t)ppc::protocol::ECCCurve::SECP256K1, hashImpl), + eccFactory->createEccCrypto((int8_t)ppc::protocol::ECCCurve::P256, hashImpl)}; + std::vector eccSet1 = { + eccFactory->createEccCrypto((int8_t)ppc::protocol::ECCCurve::ED25519, hashImpl), + eccFactory->createEccCrypto((int8_t)ppc::protocol::ECCCurve::SECP256K1, hashImpl), + eccFactory->createEccCrypto((int8_t)ppc::protocol::ECCCurve::P256, hashImpl)}; + for (uint64_t i = 0; i < eccSet0.size(); i++) + { + runEcdhOprf(eccSet0[i], eccSet1[i], hashImpl, hashImpl); + } + } +} + +BOOST_AUTO_TEST_SUITE_END() +} // namespace ppc::test diff --git a/cpp/wedpr-crypto/ppc-crypto/tests/TestPRNG.cpp b/cpp/wedpr-crypto/ppc-crypto/tests/TestPRNG.cpp new file mode 100644 index 00000000..f4ce8a5c --- /dev/null +++ b/cpp/wedpr-crypto/ppc-crypto/tests/TestPRNG.cpp @@ -0,0 +1,112 @@ +/** + * Copyright (C) 2022 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 TestPRNG.cpp + * @author: shawnhe + * @date 2022-11-29 + */ +#include "ppc-crypto-core/src/tools/BitVector.h" +#include "ppc-crypto/src/prng/AESPRNG.h" +#include "ppc-crypto/src/prng/BLAKE2bPRNG.h" +#include +#include +#include + +using namespace ppc::crypto; +using namespace bcos; +using namespace bcos::test; + +namespace ppc::test +{ +BOOST_FIXTURE_TEST_SUITE(PRNGTest, TestPromptFixture) + +void runPRNG(PRNG::Ptr _prng1, PRNG::Ptr _prng2) +{ + auto output11 = _prng1->generate(4511); + auto output12 = _prng1->generate(3275122); + auto output13 = _prng1->generate(25480233); + + auto output21 = _prng2->generate(4511); + auto output22 = _prng2->generate(3275122); + auto output23 = _prng2->generate(25480233); + + BOOST_CHECK(output11 == output21 && output11.size() == 4511); + BOOST_CHECK(output12 == output22 && output12.size() == 3275122); + BOOST_CHECK(output13 == output23 && output13.size() == 25480233); +} + +void runPRNGFunc(PRNG::Ptr _prng1, PRNG::Ptr _prng2) +{ + auto output11 = _prng1->generate(1234); + auto output12 = _prng1->generate(23456); + auto output13 = _prng1->generate(345678); + + auto output2 = _prng2->generate(370368); + + BOOST_CHECK(output11 + output12 + output13 == output2 && output2.size() == 370368); + + int intOut1 = _prng1->generate(); + int intOut2 = _prng2->generate(); + BOOST_CHECK(intOut1 == intOut2); + + bool boolOut1 = _prng1->generate(); + bool boolOut2 = _prng2->generate(); + BOOST_CHECK(boolOut1 == boolOut2); + + std::vector dest1(1024); + std::vector dest2(1024); + _prng1->generate(dest1.data(), 1024); + _prng2->generate(dest2.data(), 1024); + BOOST_CHECK(dest1 == dest2); +} + + +BOOST_AUTO_TEST_CASE(testAESPRNG) +{ + bcos::bytes seed1{'a', 'b', 'c'}; + auto prng1 = std::make_shared(seed1); + auto prng2 = std::make_shared(seed1); + runPRNG(prng1, prng2); + + bcos::bytes seed2{'c', 'd', '3'}; + prng1 = std::make_shared(seed2); + prng2 = std::make_shared(seed2); + runPRNGFunc(prng1, prng2); +} + +BOOST_AUTO_TEST_CASE(testBLAKE2bPRNG) +{ + bcos::bytes seed1{'a', 'b', 'c'}; + auto prng1 = std::make_shared(seed1); + auto prng2 = std::make_shared(seed1); + runPRNG(prng1, prng2); + + bcos::bytes seed2{'c', 'd', '3'}; + prng1 = std::make_shared(seed2); + prng2 = std::make_shared(seed2); + runPRNGFunc(prng1, prng2); + + BitVector bv0("10011011101"); + BitVector bv1(10, 12345); + bcos::bytes seed{'a', 'b', 'c'}; + auto prng0 = std::make_shared(seed); + auto prng4 = std::make_shared(seed); + bv0.randomize(prng0, 16); + bv1.randomize(prng4, 16); + BOOST_CHECK(bv1.equals(bv0)); +} + +BOOST_AUTO_TEST_SUITE_END() +} // namespace ppc::test diff --git a/cpp/wedpr-crypto/ppc-crypto/tests/TestRandomot.cpp b/cpp/wedpr-crypto/ppc-crypto/tests/TestRandomot.cpp new file mode 100644 index 00000000..cea3a056 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-crypto/tests/TestRandomot.cpp @@ -0,0 +1,102 @@ +/** + * Copyright (C) 2022 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 TestRandomot.cpp + * @author: shawnhe + * @date 2022-12-6 + */ + + +#include "ppc-crypto-core/src/hash/HashFactoryImpl.h" +#include "ppc-crypto-core/src/tools/BitVector.h" +#include "ppc-crypto/src/ecc/EccCryptoFactoryImpl.h" +#include "ppc-crypto/src/prng/AESPRNG.h" +#include "ppc-crypto/src/randomot/SimplestOT.h" +#include +#include + +using namespace ppc::crypto; +using namespace bcos; +using namespace bcos::test; + +namespace ppc::test +{ +BOOST_FIXTURE_TEST_SUITE(RandomotTest, TestPromptFixture) + +void runRandomOT(EccCrypto::Ptr _clientEcc, EccCrypto::Ptr _serverEcc, Hash::Ptr _clientHash, + Hash::Ptr _serverHash) +{ + auto simplestOt0 = std::make_shared(_clientEcc, _clientHash); + auto simplestOt1 = std::make_shared(_serverEcc, _serverHash); + + auto chooses = std::make_shared(); + bcos::bytes seed{'b', '1', 'c', '0'}; + auto prng = std::make_shared(seed); + + uint32_t otNumber = 1024; + chooses->randomize(prng, otNumber / 8); + + std::string ch = chooses->toString(); + + std::pair pairA = simplestOt0->senderGeneratePointA(); + std::pair> parsBs = + simplestOt1->receiverGeneratePointsB(chooses, pairA.second); + std::vector receiverKeys = + simplestOt0->finishReceiver(pairA.second, parsBs.second); + std::vector> senderKeys = + simplestOt1->finishSender(pairA.first, pairA.second, parsBs.first); + + for (uint32_t i = 0; i < otNumber; ++i) + { + BOOST_CHECK(receiverKeys[i] == senderKeys[i][chooses->get(i)]); + } +} + +BOOST_AUTO_TEST_CASE(testRandomot) +{ + auto eccFactory = std::make_shared(); + auto hashFactory = std::make_shared(); + + // test sm + auto sm3Hash = hashFactory->createHashImpl((int8_t)ppc::protocol::HashImplName::SM3); + auto sm2Ecc0 = eccFactory->createEccCrypto((int8_t)ppc::protocol::ECCCurve::SM2, sm3Hash); + auto sm2Ecc1 = eccFactory->createEccCrypto((int8_t)ppc::protocol::ECCCurve::SM2, sm3Hash); + runRandomOT(sm2Ecc0, sm2Ecc1, sm3Hash, sm3Hash); + + // test others + std::vector hashSet = { + hashFactory->createHashImpl((int8_t)ppc::protocol::HashImplName::SHA256), + hashFactory->createHashImpl((int8_t)ppc::protocol::HashImplName::SHA512), + hashFactory->createHashImpl((int8_t)ppc::protocol::HashImplName::BLAKE2b)}; + + for (auto& hashImpl : hashSet) + { + std::vector eccSet0 = { + eccFactory->createEccCrypto((int8_t)ppc::protocol::ECCCurve::ED25519, hashImpl), + eccFactory->createEccCrypto((int8_t)ppc::protocol::ECCCurve::SECP256K1, hashImpl), + eccFactory->createEccCrypto((int8_t)ppc::protocol::ECCCurve::P256, hashImpl)}; + std::vector eccSet1 = { + eccFactory->createEccCrypto((int8_t)ppc::protocol::ECCCurve::ED25519, hashImpl), + eccFactory->createEccCrypto((int8_t)ppc::protocol::ECCCurve::SECP256K1, hashImpl), + eccFactory->createEccCrypto((int8_t)ppc::protocol::ECCCurve::P256, hashImpl)}; + for (uint64_t i = 0; i < eccSet0.size(); i++) + { + runRandomOT(eccSet0[i], eccSet1[i], hashImpl, hashImpl); + } + } +} + +BOOST_AUTO_TEST_SUITE_END() +} // namespace ppc::test diff --git a/cpp/wedpr-crypto/ppc-crypto/tests/main.cpp b/cpp/wedpr-crypto/ppc-crypto/tests/main.cpp new file mode 100644 index 00000000..2c06f9b5 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-crypto/tests/main.cpp @@ -0,0 +1,2 @@ +#define BOOST_TEST_MAIN +#include \ No newline at end of file diff --git a/cpp/wedpr-crypto/ppc-homo/CMakeLists.txt b/cpp/wedpr-crypto/ppc-homo/CMakeLists.txt new file mode 100644 index 00000000..06f891dc --- /dev/null +++ b/cpp/wedpr-crypto/ppc-homo/CMakeLists.txt @@ -0,0 +1,12 @@ +add_subdirectory(codec) +add_subdirectory(paillier) +add_subdirectory(fahe) +add_subdirectory(ihc) +if(DEMO) + add_subdirectory(demo) +endif() +if (TESTS) + enable_testing() + set(CTEST_OUTPUT_ON_FAILURE TRUE) + add_subdirectory(tests) +endif() diff --git a/cpp/wedpr-crypto/ppc-homo/codec/CMakeLists.txt b/cpp/wedpr-crypto/ppc-homo/codec/CMakeLists.txt new file mode 100644 index 00000000..c623ef00 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-homo/codec/CMakeLists.txt @@ -0,0 +1,5 @@ +file(GLOB_RECURSE SRCS *.cpp) +add_library(${CRYPTO_CODEC_TARGET} ${SRCS}) + +find_package(OpenSSL REQUIRED) +target_link_libraries(${CRYPTO_CODEC_TARGET} PUBLIC ${BCOS_UTILITIES_TARGET} OpenSSL::Crypto ${CPU_FEATURES_LIB}) \ No newline at end of file diff --git a/cpp/wedpr-crypto/ppc-homo/codec/Common.h b/cpp/wedpr-crypto/ppc-homo/codec/Common.h new file mode 100644 index 00000000..e89aeddf --- /dev/null +++ b/cpp/wedpr-crypto/ppc-homo/codec/Common.h @@ -0,0 +1,58 @@ + + + +/** + * Copyright (C) 2022 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 Common.h + * @author: asherli + * @date 2023-12-29 + */ +#pragma once +#include "FloatingPointCipher.h" +#include "openssl/bn.h" +namespace ppc::homo +{ +inline void precisionAlign(FloatingPointCipher& _c1, FloatingPointCipher& _c2, + std::function const& + _alignFunc) +{ + if (_c1.exponent() == _c2.exponent()) + { + return; + } + auto alignedCipher = &_c1; + int exp = 0; + // c1.exp < c2.exp, align exponent of c2 to the exponent of c1 + if (_c1.exponent() < _c2.exponent()) + { + alignedCipher = &_c2; + exp = _c2.exponent() - _c1.exponent(); + alignedCipher->setExponent(_c1.exponent()); + } + else + { + // c1 > c2, align exponent of c1 to the exponent of c2 + exp = _c1.exponent() - _c2.exponent(); + alignedCipher->setExponent(_c2.exponent()); + } + ppc::crypto::BigNum expBN(exp); + auto ctx = ppc::crypto::createBNContext(); + ppc::crypto::BigNum c_base = ppc::crypto::BigNum(10); + auto v = c_base.exp(expBN.bn().get(), ctx.get()); + auto cipher = _alignFunc(v.bn().get(), bcos::ref(alignedCipher->cipher())); + alignedCipher->setCipher(std::move(cipher)); +} +} // namespace ppc::homo \ No newline at end of file diff --git a/cpp/wedpr-crypto/ppc-homo/codec/FloatingPointCipher.h b/cpp/wedpr-crypto/ppc-homo/codec/FloatingPointCipher.h new file mode 100644 index 00000000..2f1ae330 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-homo/codec/FloatingPointCipher.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 FloatingPointCipher.h + * @author: yujiechen + * @date 2023-08-17 + */ +#pragma once +#include "ppc-framework/libwrapper/Buffer.h" +#include "ppc-tools/src/codec/CodecUtility.h" +#include +#include +namespace ppc::homo +{ +DERIVE_PPC_EXCEPTION(FloatingPointCipherException); +class FloatingPointCipher +{ +public: + using Ptr = std::shared_ptr; + FloatingPointCipher(bcos::bytes&& _cipher, int16_t _exponent) + : m_cipher(std::move(_cipher)), m_exponent(_exponent) + {} + FloatingPointCipher(bcos::bytesConstRef const& _data) { decode(_data); } + + virtual ~FloatingPointCipher() = default; + + virtual void decode(bcos::bytesConstRef const& _data) + { + auto bufferLen = _data.size(); + // exponent + auto offset = decodeInteger(m_exponent, _data.data(), bufferLen, 0); + // cipher + decodeBuffer(m_cipher, _data.data(), bufferLen, offset); + } + + virtual void encode(OutputBuffer* _output) const + { + auto pEnd = _output->data + _output->len; + // exponent + auto p = encodeInteger(_output->data, pEnd, m_exponent); + // cipher + p = encodeBuffer(p, pEnd, bcos::ref(m_cipher)); + _output->len = (p - _output->data); + } + + int maxEncodedSize() const { return m_cipher.size() + sizeof(uint16_t) + sizeof(int16_t); } + + bcos::bytes const& cipher() const { return m_cipher; } + int16_t exponent() const { return m_exponent; } + + void setCipher(bcos::bytes&& _cipher) { m_cipher = std::move(_cipher); } + void setExponent(int16_t _exponent) { m_exponent = _exponent; } + +private: + // the cipher + bcos::bytes m_cipher; + // the exponent + int16_t m_exponent; +}; +} // namespace ppc::homo \ No newline at end of file diff --git a/cpp/wedpr-crypto/ppc-homo/codec/FloatingPointCodec.cpp b/cpp/wedpr-crypto/ppc-homo/codec/FloatingPointCodec.cpp new file mode 100644 index 00000000..e6812537 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-homo/codec/FloatingPointCodec.cpp @@ -0,0 +1,95 @@ +/** + * Copyright (C) 2022 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 FloatingPointCodec.cpp + * @author: yujiechen + * @date 2023-08-23 + */ +#include "FloatingPointCodec.h" +#include +#include +#include + +using namespace ppc::homo; +using namespace ppc::crypto; +using namespace ppc; +using namespace bcos; + +s1024 FloatingPointCodec::fpToS1024(ppc::FloatingPointNumber const& _value) +{ + auto ctx = createBNContext(); + BigNum exponent(_value.exponent); + auto result = C_BASE.exp(exponent.bn().get(), ctx.get()); + _value.value.mul(result.bn().get(), result.bn().get(), ctx.get()); + return result.toS1024(); +} + +float50 FloatingPointCodec::toFloat50(ppc::FloatingPointNumber const& _value) +{ + if (_value.exponent >= 0) + { + return float50(fpToS1024(_value)); + } + return toDecimal(_value); +} + +float50 FloatingPointCodec::toDecimal(ppc::FloatingPointNumber const& _value) +{ + auto ctx = createBNContext(); + BigNum exponent(-_value.exponent); + auto divider = C_BASE.exp(exponent.bn().get(), ctx.get()); + return (float50)_value.value.toS1024() / (float50)divider.toS1024(); +} + +s1024 FloatingPointCodec::toInt(ppc::FloatingPointNumber const& _value) +{ + if (_value.exponent >= 0) + { + return fpToS1024(_value); + } + else + { + return s1024(toDecimal(_value)); + } +} +ppc::FloatingPointNumber FloatingPointCodec::toFloatingPoint(std::string const& _valueStr) +{ + float50 value(_valueStr); + auto pos = _valueStr.find("."); + auto exp = 0; + if (pos != std::string::npos) + { + exp = -(_valueStr.size() - 1 - pos); + } + // 10^exp + auto baseExp = boost::multiprecision::pow(s1024(10), -exp); + // convert the value to int + auto significant = (s1024)(float50(baseExp) * float50(value)); + FloatingPointNumber result; + result.exponent = exp; + // convert the significant to BigNum + BigNum significantBn(significant); + result.value = significantBn; + return result; +} + +ppc::FloatingPointNumber FloatingPointCodec::toFloatingPoint(s1024 const& _value) +{ + FloatingPointNumber result; + BigNum value(_value); + result.value = value; + result.exponent = 0; + return result; +} diff --git a/cpp/wedpr-crypto/ppc-homo/codec/FloatingPointCodec.h b/cpp/wedpr-crypto/ppc-homo/codec/FloatingPointCodec.h new file mode 100644 index 00000000..54f5b9ce --- /dev/null +++ b/cpp/wedpr-crypto/ppc-homo/codec/FloatingPointCodec.h @@ -0,0 +1,47 @@ +/** + * Copyright (C) 2022 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 FloatingPointCodec.h + * @author: yujiechen + * @date 2023-08-23 + */ +#pragma once +#include +#include +#include +namespace ppc::homo +{ +DERIVE_PPC_EXCEPTION(FloatingPointCodecException); + +class FloatingPointCodec +{ +public: + using Ptr = std::shared_ptr; + FloatingPointCodec() = default; + virtual ~FloatingPointCodec() = default; + s1024 toInt(ppc::FloatingPointNumber const& _value); + float50 toFloat50(ppc::FloatingPointNumber const& _value); + + ppc::FloatingPointNumber toFloatingPoint(std::string const& _value); + ppc::FloatingPointNumber toFloatingPoint(s1024 const& _value); + +private: + s1024 fpToS1024(ppc::FloatingPointNumber const& _value); + float50 toDecimal(ppc::FloatingPointNumber const& _value); + +private: + const ppc::crypto::BigNum C_BASE = ppc::crypto::BigNum(10); +}; +} // namespace ppc::homo \ No newline at end of file diff --git a/cpp/wedpr-crypto/ppc-homo/codec/SignedNumberCodec.h b/cpp/wedpr-crypto/ppc-homo/codec/SignedNumberCodec.h new file mode 100644 index 00000000..7cddcf21 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-homo/codec/SignedNumberCodec.h @@ -0,0 +1,109 @@ +/** + * Copyright (C) 2022 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 SignedNumberCodec.h + * @author: yujiechen + * @date 2023-08-09 + */ +#pragma once +#include "ppc-framework/Common.h" +#include "ppc-framework/libwrapper/BigNum.h" +#include + +namespace ppc::homo +{ +DERIVE_PPC_EXCEPTION(BigNumOutOfRange); +DERIVE_PPC_EXCEPTION(SignedNumberCodecException); +class SignedNumberCodec +{ +public: + using Ptr = std::shared_ptr; + SignedNumberCodec(unsigned _maxBits) + { + ppc::crypto::BigNum one(1); + if (BN_lshift(m_n.bn().get(), one.bn().get(), _maxBits) != 1) + { + BOOST_THROW_EXCEPTION( + SignedNumberCodecException() << bcos::errinfo_comment( + "BN_lshift error: " + std::string(ERR_error_string(ERR_get_error(), NULL)))); + } + init(); + } + // n is the public key + SignedNumberCodec(ppc::crypto::BigNum const& _n) + { + m_n = _n; + init(); + } + + // _v mod n + ppc::crypto::BigNum encode(BIGNUM const* v) const + { + check(v); + auto ctx = ppc::crypto::createBNContext(); + ppc::crypto::BigNum result; + BN_nnmod(result.bn().get(), v, m_n.bn().get(), ctx.get()); + // for negative case check + check(result.bn().get()); + return result; + } + + // _v - ( v >= N/3) * _v + ppc::crypto::BigNum decode(ppc::crypto::BigNum const& _v) const + { + check(_v.bn().get()); + if (BN_cmp(_v.bn().get(), m_maxPositive.bn().get()) < 0) + { + return _v; + } + return _v.sub(m_n.bn().get()); + } + ppc::crypto::BigNum const& n() const { return m_n; } + ppc::crypto::BigNum const& maxPositive() const { return m_maxPositive; } + ppc::crypto::BigNum const& negativeZero() const { return m_negativeZero; } + +private: + void check(BIGNUM const* v) const + { + if (BN_cmp(v, m_n.bn().get()) >= 0) + { + BOOST_THROW_EXCEPTION( + SignedNumberCodecException() << bcos::errinfo_comment("Invalid number for over N")); + } + if (BN_cmp(v, m_maxPositive.bn().get()) > 0 && BN_cmp(v, m_negativeZero.bn().get()) < 0) + { + BOOST_THROW_EXCEPTION(SignedNumberCodecException() + << bcos::errinfo_comment("Invalid number for overflow")); + } + } + + void init() + { + ppc::crypto::BigNum three(3); + auto ctx = ppc::crypto::createBNContext(); + // calculate m_maxPositive + m_n.div(m_maxPositive.bn().get(), NULL, three.bn().get(), ctx.get()); + // calculate m_negativeZero + ppc::crypto::BigNum two(2); + m_n.mul(m_negativeZero.bn().get(), two.bn().get(), ctx.get()); + m_negativeZero.div(m_negativeZero.bn().get(), NULL, three.bn().get(), ctx.get()); + } + +private: + ppc::crypto::BigNum m_n; + ppc::crypto::BigNum m_maxPositive; // N/3 + ppc::crypto::BigNum m_negativeZero; // 2*N/3 +}; +} // namespace ppc::homo \ No newline at end of file diff --git a/cpp/wedpr-crypto/ppc-homo/demo/CMakeLists.txt b/cpp/wedpr-crypto/ppc-homo/demo/CMakeLists.txt new file mode 100644 index 00000000..452de552 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-homo/demo/CMakeLists.txt @@ -0,0 +1,7 @@ +# file(GLOB SRC_LIST "*.cpp") +# file(GLOB HEADERS "*.h") + +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) +add_executable(homo_perf_demo homo_perf_demo.cpp) +# add_executable(homo_perf_demo ${SRC_LIST} ${HEADERS}) +target_link_libraries(homo_perf_demo PUBLIC ${PAILLIER_TARGET} ${FAHE_TARGET}) diff --git a/cpp/wedpr-crypto/ppc-homo/demo/homo_perf_demo.cpp b/cpp/wedpr-crypto/ppc-homo/demo/homo_perf_demo.cpp new file mode 100644 index 00000000..4ce504ea --- /dev/null +++ b/cpp/wedpr-crypto/ppc-homo/demo/homo_perf_demo.cpp @@ -0,0 +1,311 @@ +/* + * Copyright (C) 2022 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 homo_perf_demo.cpp + * @author: yujiechen + * @date 2023-08-09 + */ +#include "ppc-framework/libwrapper/BigNum.h" +#include "ppc-homo/codec/FloatingPointCodec.h" +#include "ppc-homo/codec/SignedNumberCodec.h" +#include "ppc-homo/fahe/Fahe.h" +#include "ppc-homo/paillier/FloatingPointPaillier.h" +#include "ppc-homo/paillier/OpenSSLPaillier.h" + +using namespace bcos; +using namespace ppc; +using namespace ppc::crypto; +using namespace ppc::homo; + +std::pair getTPS(int64_t _endT, int64_t _startT, size_t _count) +{ + auto tps = (1000000.0 * (double)_count) / (double)(_endT - _startT); + auto timeCostUs = (1000000.0) / tps; + return std::make_pair(tps, timeCostUs); +} + +void paillierPerf(int const _keyBits, size_t _loopCount) +{ + auto paillier = std::make_shared(); + + std::cout << "----------- paillier perf start -----------" << std::endl; + std::cout << "\t keyBits: " << _keyBits << " , loopCount: " << _loopCount << std::endl; + srand(bcos::utcSteadyTime()); + /// generate keyPair + KeyPair::UniquePtr keyPair; + auto startT = utcSteadyTimeUs(); + for (size_t i = 0; i < _loopCount; i++) + { + keyPair = paillier->generateKeyPair(_keyBits); + } + auto pk = (PaillierPublicKey*)(keyPair->pk()); + auto codec = std::make_shared(pk->n); + auto generateKeyPairTPS = getTPS(utcSteadyTimeUs(), startT, _loopCount); + std::cout << "* GenerateKeyPair TPS: " << generateKeyPairTPS.first + << "\ttimecost per count: " << generateKeyPairTPS.second << " us" << std::endl; + + /// encrypt + startT = utcSteadyTimeUs(); + bcos::bytes cipherData; + int64_t value = 0; + for (size_t i = 0; i < _loopCount; i++) + { + value = i % 2 ? rand() : (-rand()); + BigNum v(value); + cipherData = paillier->encrypt_with_crt(v.bn().get(), (void*)keyPair.get()); + } + auto encryptTPS = getTPS(utcSteadyTimeUs(), startT, _loopCount); + std::cout << "* Encrypt TPS: " << encryptTPS.first + << "\t\ttimecost per count: " << encryptTPS.second << " us" << std::endl; + + /// decrypt + startT = utcSteadyTimeUs(); + for (size_t i = 0; i < _loopCount; i++) + { + auto result = paillier->decrypt(bcos::ref(cipherData), (void*)keyPair.get()); + } + auto decryptTPS = getTPS(utcSteadyTimeUs(), startT, _loopCount); + std::cout << "* Decrypt TPS: " << decryptTPS.first + << "\t\ttimecost per count: " << decryptTPS.second << " us" << std::endl; + + /// paillier add + startT = utcSteadyTimeUs(); + bcos::bytes addCipher; + for (size_t i = 0; i < _loopCount; i++) + { + addCipher = paillier->add(bcos::ref(cipherData), bcos::ref(cipherData), keyPair->pk()); + } + auto addTPS = getTPS(utcSteadyTimeUs(), startT, _loopCount); + std::cout << "* Add TPS: " << addTPS.first << "\t\ttimecost per count: " << addTPS.second + << " us" << std::endl; + + /// paillier sub + startT = utcSteadyTimeUs(); + bcos::bytes subCipher; + for (size_t i = 0; i < _loopCount; i++) + { + subCipher = paillier->sub(bcos::ref(cipherData), bcos::ref(cipherData), keyPair->pk()); + } + auto subTPS = getTPS(utcSteadyTimeUs(), startT, _loopCount); + std::cout << "* Sub TPS: " << subTPS.first << "\t\ttimecost per count: " << subTPS.second + << " us" << std::endl; + /// paillier scalaMul + startT = utcSteadyTimeUs(); + bcos::bytes scalaMulCipher; + for (size_t i = 0; i < _loopCount; i++) + { + BigNum v(value); + scalaMulCipher = paillier->scalaMul(v.bn().get(), bcos::ref(cipherData), keyPair->pk()); + } + auto scalaMulTPS = getTPS(utcSteadyTimeUs(), startT, _loopCount); + std::cout << "* ScalaMul TPS: " << scalaMulTPS.first + << "\t\ttimecost per count: " << scalaMulTPS.second << " us" << std::endl; + std::cout << "----------- paillier perf end -----------" << std::endl; + std::cout << std::endl; +} + +void floatingPointPaillierPerf(int const _keyBits, size_t _loopCount, bool _needAlign) +{ + std::cout << "----------- floating-point-paillier perf start, need align: " << _needAlign + << "-----------" << std::endl; + std::cout << "\t keyBits: " << _keyBits << " , loopCount: " << _loopCount << std::endl; + auto paillierImpl = std::make_shared(); + auto fpPaillier = std::make_shared(paillierImpl); + /// prepare + // generate keyPair + auto keyPair = paillierImpl->generateKeyPair(_keyBits); + auto pk = keyPair->pk(); + std::string s1("1.23432"); + std::string s2("234234.234234324"); + std::string s3("23423.133243"); + + float50 m1(s1); + float50 m2(s2); + float50 v(s3); + /// Note: the align operation has the overhead of scalaMul + if (!_needAlign) + { + m1 = float50("10.0"); + m2 = float50("20.0"); + v = float50("1"); + } + auto codec = std::make_shared(); + auto c1Fp = codec->toFloatingPoint(s1); + auto c2Fp = codec->toFloatingPoint(s2); + auto vFp = codec->toFloatingPoint(s3); + // precision to 10 + double epsilon = 0.00000000001; + /// encrypt + bcos::bytes c1(FloatingPointPaillier::maxCipherBytesLen(_keyBits)); + OutputBuffer c1Buffer{c1.data(), c1.size()}; + bcos::bytes c2(FloatingPointPaillier::maxCipherBytesLen(_keyBits)); + OutputBuffer c2Buffer{c2.data(), c2.size()}; + auto startT = utcSteadyTimeUs(); + for (size_t i = 0; i < _loopCount; i++) + { + fpPaillier->encrypt(&c1Buffer, c1Fp, pk); + } + auto encryptTPS = getTPS(utcSteadyTimeUs(), startT, _loopCount); + std::cout << "* Encrypt TPS: " << encryptTPS.first + << "\t\ttimecost per count: " << encryptTPS.second << " us" << std::endl; + fpPaillier->encrypt(&c2Buffer, c2Fp, pk); + /// decrypt + startT = utcSteadyTimeUs(); + FloatingPointNumber result; + for (size_t i = 0; i < _loopCount; i++) + { + result = fpPaillier->decrypt(ref(c1), (void*)keyPair.get()); + } + auto decryptTPS = getTPS(utcSteadyTimeUs(), startT, _loopCount); + std::cout << "* Decrypt TPS: " << decryptTPS.first + << "\t\ttimecost per count: " << decryptTPS.second << " us" << std::endl; + // check the result + assert(fabs(codec->toFloat50(result) - m1) <= epsilon); + /// add + bcos::bytes addResult(FloatingPointPaillier::maxCipherBytesLen(_keyBits)); + OutputBuffer addResultBuffer{addResult.data(), addResult.size()}; + startT = utcSteadyTimeUs(); + for (size_t i = 0; i < _loopCount; i++) + { + fpPaillier->add(&addResultBuffer, ref(c1), ref(c2), pk); + } + auto addTPS = getTPS(utcSteadyTimeUs(), startT, _loopCount); + std::cout << "* Add TPS: " << addTPS.first << "\t\ttimecost per count: " << addTPS.second + << " us" << std::endl; + + /// sub + bcos::bytes subResult(FloatingPointPaillier::maxCipherBytesLen(_keyBits)); + OutputBuffer subResultBuffer{subResult.data(), subResult.size()}; + startT = utcSteadyTimeUs(); + for (size_t i = 0; i < _loopCount; i++) + { + fpPaillier->sub(&subResultBuffer, ref(c1), ref(c2), pk); + } + auto subTPS = getTPS(utcSteadyTimeUs(), startT, _loopCount); + std::cout << "* Sub TPS: " << subTPS.first << "\t\ttimecost per count: " << subTPS.second + << " us" << std::endl; + /// scalaMul + bcos::bytes scalaMulResult(FloatingPointPaillier::maxCipherBytesLen(_keyBits)); + OutputBuffer scalaMulResultBuffer{scalaMulResult.data(), scalaMulResult.size()}; + startT = utcSteadyTimeUs(); + for (size_t i = 0; i < _loopCount; i++) + { + fpPaillier->scalaMul(&scalaMulResultBuffer, vFp, ref(c1), pk); + } + auto scalaMulTPS = getTPS(utcSteadyTimeUs(), startT, _loopCount); + std::cout << "* ScalaMul TPS: " << scalaMulTPS.first + << "\t\ttimecost per count: " << scalaMulTPS.second << " us" << std::endl; + std::cout << "----------- floating-point-paillier perf finished -----------" << std::endl; +} + +void fahePerf(int lambda, int alpha, int mmax, size_t loopCount) +{ + std::cout << "----------- fahe perf start -----------" << std::endl; + std::cout << "* lambda: " << lambda << std::endl; + std::cout << "* alpha: " << alpha << std::endl; + std::cout << "* mmax: " << mmax << std::endl; + std::cout << "* loopCount: " << loopCount << std::endl; + auto faheImpl = std::make_shared(); + FaheKey::UniquePtr key; + auto startT = utcSteadyTimeUs(); + for (size_t i = 0; i < loopCount; i++) + { + key = faheImpl->generateKey(lambda, mmax, alpha); + } + auto genKeyTPS = getTPS(utcSteadyTimeUs(), startT, loopCount); + std::cout << "* generateKey TPS: " << genKeyTPS.first + << "\t\ttimecost per count: " << genKeyTPS.second << " us" << std::endl; + // encrypt + BigNum m1(123213231 + bcos::utcSteadyTime()); + BigNum c1; + startT = utcSteadyTimeUs(); + for (size_t i = 0; i < loopCount; i++) + { + c1 = faheImpl->encrypt(m1.bn().get(), key.get()); + } + auto encryptTPS = getTPS(utcSteadyTimeUs(), startT, loopCount); + std::cout << "* encrypt TPS: " << encryptTPS.first + << "\t\ttimecost per count: " << encryptTPS.second << " us" << std::endl; + BigNum m2(-(1232231 + bcos::utcSteadyTime())); + auto c2 = faheImpl->encrypt(m2.bn().get(), key.get()); + + // add + BigNum addResult; + startT = utcSteadyTimeUs(); + for (size_t i = 0; i < loopCount; i++) + { + addResult = faheImpl->add(c1.bn().get(), c2.bn().get()); + } + auto addTPS = getTPS(utcSteadyTimeUs(), startT, loopCount); + std::cout << "* fahe add TPS: " << addTPS.first << "\t\ttimecost per count: " << addTPS.second + << " us" << std::endl; + // decrypt + BigNum decryptedResult; + startT = utcSteadyTimeUs(); + for (size_t i = 0; i < loopCount; i++) + { + decryptedResult = faheImpl->decrypt(addResult.bn().get(), key.get()); + } + auto decryptTPS = getTPS(utcSteadyTimeUs(), startT, loopCount); + std::cout << "* fahe decrypt TPS: " << decryptTPS.first + << "\t\ttimecost per count: " << decryptTPS.second << " us" << std::endl; + // check the result + auto expectedAddResult = m1.add(m2.bn().get()); + assert(expectedAddResult.cmp(decryptedResult.bn().get()) == 0); + std::cout << "----------- fahe perf end -----------" << std::endl; + + /// check the correctness of fahe + std::cout << "----------- fahe perf correctness check -----------" << std::endl; + uint64_t count = 1000000; + srand(utcSteadyTime()); + for (size_t i = 0; i < count; i++) + { + BigNum randM1(rand() + utcSteadyTime()); + BigNum randM2(rand() + utcSteadyTimeUs()); + auto randC1 = faheImpl->encrypt(randM1.bn().get(), key.get()); + auto randC2 = faheImpl->encrypt(randM2.bn().get(), key.get()); + // add + auto addCipher = faheImpl->add(randC1.bn().get(), randC2.bn().get()); + // decrypt + auto addResult = faheImpl->decrypt(addCipher.bn().get(), key.get()); + auto expectedAddResult = randM1.add(randM2.bn().get()); + assert(expectedAddResult.cmp(addResult.bn().get()) == 0); + } + std::cout << "----------- fahe perf correctness check finished -----------" << std::endl; +} + +int main(int argc, char* argv[]) +{ + if (argc < 2) + { + std::cout << "Usage: " << argv[0] << "\n loopCount [required]" + << "\n keyBitLength[optional]: default is 2048" << std::endl; + return -1; + } + int keyBits = 2048; + int loopCount = atol(argv[1]); + if (argc >= 3) + { + keyBits = atol(argv[2]); + } + paillierPerf(keyBits, loopCount); + floatingPointPaillierPerf(keyBits, loopCount, false); + floatingPointPaillierPerf(keyBits, loopCount, true); + int lambda = 128; + int alpha = 33; + int mmax = 64; + fahePerf(lambda, alpha, mmax, loopCount); + return 0; +} \ No newline at end of file diff --git a/cpp/wedpr-crypto/ppc-homo/fahe/CMakeLists.txt b/cpp/wedpr-crypto/ppc-homo/fahe/CMakeLists.txt new file mode 100644 index 00000000..af920edf --- /dev/null +++ b/cpp/wedpr-crypto/ppc-homo/fahe/CMakeLists.txt @@ -0,0 +1,5 @@ +file(GLOB_RECURSE SRCS *.cpp) +add_library(${FAHE_TARGET} ${SRCS}) + +find_package(OpenSSL REQUIRED) +target_link_libraries(${FAHE_TARGET} PUBLIC ${CRYPTO_CODEC_TARGET} ${BCOS_UTILITIES_TARGET} OpenSSL::Crypto ${CPU_FEATURES_LIB}) \ No newline at end of file diff --git a/cpp/wedpr-crypto/ppc-homo/fahe/Fahe.cpp b/cpp/wedpr-crypto/ppc-homo/fahe/Fahe.cpp new file mode 100644 index 00000000..3ff270ff --- /dev/null +++ b/cpp/wedpr-crypto/ppc-homo/fahe/Fahe.cpp @@ -0,0 +1,125 @@ +/** + * Copyright (C) 2022 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 Fahe.cpp + * @author: yujiechen + * @date 2023-08-30 + */ +// clang-format off +#include +#include +// clang-format on +#include "Fahe.h" +#include "../codec/SignedNumberCodec.h" +using namespace ppc::homo; +using namespace ppc::crypto; +using namespace std; + +FaheKey::UniquePtr Fahe::generateKey(int16_t _lambda, int16_t _mmax, int16_t _alpha) +{ + auto key = std::make_unique(); + key->lambda = _lambda; + key->alpha = _alpha; + key->mmax = _mmax; + srand(bcos::utcTime()); + + key->pos = rand() % _lambda; + double tmp = _lambda + _alpha + _mmax; + auto n = tmp + _alpha; + // p + key->p.generatePrime(n); + // x = 2^r/p + BigNum base(2); + // r = p/lgp *((n-tmp)^2) + // divider = (log10(_lambda + _alpha + _mmax)); + int16_t r = (int16_t)((double)tmp / (log10((double)tmp)) * _alpha * _alpha); + BigNum exponent(r); + auto ctx = createBNContext(); + key->x = base.exp(exponent.bn().get(), ctx.get()); + key->x.div(key->x.bn().get(), NULL, key->p.bn().get(), ctx.get()); + return key; +} + +BigNum Fahe::encrypt(BIGNUM const* _m, FaheKey const* _key) +{ + // convert _m to signed + SignedNumberCodec codec(_key->mmax); + auto m = codec.encode(_m); + + auto noise1 = generateRand(_key->pos); + auto noise2 = generateRand(_key->lambda - _key->pos); + // M = (noise2 << (pos + mmax + alpha) + (m << (pos + alpha)) + noise1) + BigNum M1(noise2); + auto shiftStep = _key->pos + _key->mmax + _key->alpha; + if (BN_lshift(M1.bn().get(), M1.bn().get(), shiftStep) != 1) + { + BOOST_THROW_EXCEPTION( + FaheException() << bcos::errinfo_comment( + "encrypt error: " + std::string(ERR_error_string(ERR_get_error(), NULL)))); + } + BigNum M2; + if (BN_lshift(M2.bn().get(), m.bn().get(), (_key->pos + _key->alpha)) != 1) + { + BOOST_THROW_EXCEPTION( + FaheException() << bcos::errinfo_comment( + "encrypt error: " + std::string(ERR_error_string(ERR_get_error(), NULL)))); + } + auto M = M1.add(M2.bn().get()).add(noise1.bn().get()); + // select q from [0, x) + BigNum q; + randRange(q.bn().get(), _key->x.bn().get()); + // n = p * q + BigNum n; + auto ctx = createBNContext(); + q.mul(n.bn().get(), _key->p.bn().get(), ctx.get()); + // c = n + M + return n.add(M.bn().get()); +} + +BigNum Fahe::decrypt(BIGNUM const* _cipher, FaheKey const* _key) +{ + BigNum result; + /// result = (c mod p) >> (pos + alpha) + // cipher mod p + auto ctx = createBNContext(); + if (BN_div(NULL, result.bn().get(), _cipher, _key->p.bn().get(), ctx.get()) != 1) + { + BOOST_THROW_EXCEPTION( + FaheException() << bcos::errinfo_comment( + "decrypt error: " + std::string(ERR_error_string(ERR_get_error(), NULL)))); + } + // result = (cipher mod p) >> (pos + alpha) + if (BN_rshift(result.bn().get(), result.bn().get(), (_key->pos + _key->alpha)) != 1) + { + BOOST_THROW_EXCEPTION( + FaheException() << bcos::errinfo_comment( + "decrypt error: " + std::string(ERR_error_string(ERR_get_error(), NULL)))); + } + BN_mask_bits(result.bn().get(), _key->mmax); + SignedNumberCodec codec(_key->mmax); + return codec.decode(result); +} + +BigNum Fahe::add(BIGNUM const* _cipher1, BIGNUM const* _cipher2) +{ + BigNum result; + if (BN_add(result.bn().get(), _cipher1, _cipher2) != 1) + { + BOOST_THROW_EXCEPTION( + FaheException() << bcos::errinfo_comment( + "add error: " + std::string(ERR_error_string(ERR_get_error(), NULL)))); + } + return result; +} diff --git a/cpp/wedpr-crypto/ppc-homo/fahe/Fahe.h b/cpp/wedpr-crypto/ppc-homo/fahe/Fahe.h new file mode 100644 index 00000000..a43372da --- /dev/null +++ b/cpp/wedpr-crypto/ppc-homo/fahe/Fahe.h @@ -0,0 +1,55 @@ +/** + * Copyright (C) 2022 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 Fahe.h + * @author: yujiechen + * @date 2023-08-30 + */ +#pragma once +#include "openssl/bn.h" +#include "ppc-framework/libwrapper/BigNum.h" +#include +#include +#include +namespace ppc::homo +{ +DERIVE_PPC_EXCEPTION(FaheException); +struct FaheKey +{ + int16_t lambda; + int16_t alpha; + int16_t pos; + int16_t mmax; + ppc::crypto::BigNum p; + ppc::crypto::BigNum x; + + using UniquePtr = std::unique_ptr; + FaheKey() = default; +}; +// FAHE2 implementation: +// Fast Additive Partially Homomorphic Encryption from the Approximate Common Divisor problem +class Fahe +{ +public: + using Ptr = std::shared_ptr; + Fahe() = default; + virtual ~Fahe() = default; + + virtual FaheKey::UniquePtr generateKey(int16_t _lambda, int16_t _mmax, int16_t _alpha); + virtual ppc::crypto::BigNum encrypt(BIGNUM const* _plain, FaheKey const* _key); + virtual ppc::crypto::BigNum decrypt(BIGNUM const* _cipher, FaheKey const* _key); + virtual ppc::crypto::BigNum add(BIGNUM const* _cipher1, BIGNUM const* _cipher2); +}; +} // namespace ppc::homo \ No newline at end of file diff --git a/cpp/wedpr-crypto/ppc-homo/ihc/CMakeLists.txt b/cpp/wedpr-crypto/ppc-homo/ihc/CMakeLists.txt new file mode 100644 index 00000000..d0dc57d5 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-homo/ihc/CMakeLists.txt @@ -0,0 +1,6 @@ +file(GLOB_RECURSE SRCS *.cpp) +add_library( ${IHC_TARGET} ${SRCS}) + +find_package(OpenSSL REQUIRED) +# target_link_libraries(${IHC_TARGET} PUBLIC ${CRYPTO_CODEC_TARGET} ${BCOS_UTILITIES_TARGET} OpenSSL::Crypto ${CPU_FEATURES_LIB}) +target_link_libraries(${IHC_TARGET} PUBLIC ${CRYPTO_CODEC_TARGET} ${BCOS_UTILITIES_TARGET} OpenSSL::Crypto ${CPU_FEATURES_LIB}) \ No newline at end of file diff --git a/cpp/wedpr-crypto/ppc-homo/ihc/FloatingPointIhc.cpp b/cpp/wedpr-crypto/ppc-homo/ihc/FloatingPointIhc.cpp new file mode 100644 index 00000000..5d7267f8 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-homo/ihc/FloatingPointIhc.cpp @@ -0,0 +1,71 @@ +/** + * Copyright (C) 2022 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 FloatingPointIhc.h + * @author: asherli + * @date 2023-12-29 + */ +#include "FloatingPointIhc.h" + +using namespace ppc::homo; +using namespace ppc; + +void FloatingPointIhc::encrypt( + OutputBuffer* _result, bcos::bytesConstRef const& sk, FloatingPointNumber const& _value) const +{ + auto cipher = m_ihc->encrypt(sk, _value.value.bn().get()); + FloatingPointCipher cipherObject(std::move(cipher), _value.exponent); + cipherObject.encode(_result); +} + +FloatingPointNumber FloatingPointIhc::decrypt( + bcos::bytesConstRef const& _sk, bcos::bytesConstRef const& _cipher) const +{ + FloatingPointCipher cipherObject(_cipher); + auto resultV = m_ihc->decrypt(_sk, bcos::ref(cipherObject.cipher())); + return FloatingPointNumber(std::move(resultV), cipherObject.exponent()); +} + +void FloatingPointIhc::add( + OutputBuffer* _result, bcos::bytesConstRef const& _c1, bcos::bytesConstRef const& _c2) const +{ + FloatingPointCipher cipher1(_c1); + FloatingPointCipher cipher2(_c2); + align(cipher1, cipher2); + auto cipher = m_ihc->add(bcos::ref(cipher1.cipher()), bcos::ref(cipher2.cipher())); + FloatingPointCipher result(std::move(cipher), cipher1.exponent()); + result.encode(_result); +} + +void FloatingPointIhc::sub( + OutputBuffer* _result, bcos::bytesConstRef const& _c1, bcos::bytesConstRef const& _c2) const +{ + FloatingPointCipher cipher1(_c1); + FloatingPointCipher cipher2(_c2); + align(cipher1, cipher2); + auto cipher = m_ihc->sub(bcos::ref(cipher1.cipher()), bcos::ref(cipher2.cipher())); + FloatingPointCipher result(std::move(cipher), cipher1.exponent()); + result.encode(_result); +} + +void FloatingPointIhc::scalaMul( + OutputBuffer* _result, FloatingPointNumber const& _v, bcos::bytesConstRef const& _c) const +{ + FloatingPointCipher cipher(_c); + auto resultBytes = m_ihc->scalaMul(_v.value.bn().get(), bcos::ref(cipher.cipher())); + auto exponent = _v.exponent + cipher.exponent(); + FloatingPointCipher result(std::move(resultBytes), exponent); + result.encode(_result); +} \ No newline at end of file diff --git a/cpp/wedpr-crypto/ppc-homo/ihc/FloatingPointIhc.h b/cpp/wedpr-crypto/ppc-homo/ihc/FloatingPointIhc.h new file mode 100644 index 00000000..adcaee7d --- /dev/null +++ b/cpp/wedpr-crypto/ppc-homo/ihc/FloatingPointIhc.h @@ -0,0 +1,109 @@ +/** + * Copyright (C) 2022 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 FloatingPointIhc.h + * @author: asherli + * @date 2023-12-29 + */ +#pragma once +#include "../codec/Common.h" +#include "IhcImpl.h" +#include "openssl/bn.h" +#include "ppc-framework/libwrapper/FloatingPointNumber.h" +#include +namespace ppc::homo +{ +class FloatingPointIhc : public std::enable_shared_from_this +{ +public: + using Ptr = std::shared_ptr; + FloatingPointIhc(Ihc::Ptr _ihc) : m_ihc(std::move(_ihc)) {} + virtual ~FloatingPointIhc() = default; + + virtual void encrypt(OutputBuffer* _result, bcos::bytesConstRef const& sk, + ppc::FloatingPointNumber const& _value) const; + + virtual bcos::bytes encrypt( + bcos::bytesConstRef const& sk, ppc::FloatingPointNumber const& _value) const + { + bcos::bytes result(cipherBytes()); + OutputBuffer resultBuffer{result.data(), result.size()}; + encrypt(&resultBuffer, sk, _value); + result.resize(resultBuffer.len); + return result; + } + + virtual ppc::FloatingPointNumber decrypt( + bcos::bytesConstRef const& _sk, bcos::bytesConstRef const& _cipher) const; + + virtual void add(OutputBuffer* _result, bcos::bytesConstRef const& _c1, + bcos::bytesConstRef const& _c2) const; + + virtual bcos::bytes add(bcos::bytesConstRef const& _c1, bcos::bytesConstRef const& _c2) const + { + bcos::bytes result(cipherBytes()); + OutputBuffer resultBuffer{result.data(), result.size()}; + add(&resultBuffer, _c1, _c2); + result.resize(resultBuffer.len); + return result; + } + + virtual void sub(OutputBuffer* _result, bcos::bytesConstRef const& _c1, + bcos::bytesConstRef const& _c2) const; + virtual bcos::bytes sub(bcos::bytesConstRef const& _c1, bcos::bytesConstRef const& _c2) + { + bcos::bytes result(cipherBytes()); + OutputBuffer resultBuffer{result.data(), result.size()}; + sub(&resultBuffer, _c1, _c2); + result.resize(resultBuffer.len); + return result; + } + + virtual void scalaMul(OutputBuffer* _result, ppc::FloatingPointNumber const& _v, + bcos::bytesConstRef const& _c) const; + + virtual bcos::bytes scalaMul(ppc::FloatingPointNumber const& _v, bcos::bytesConstRef const& _c) + { + bcos::bytes result(cipherBytes()); + OutputBuffer resultBuffer{result.data(), result.size()}; + scalaMul(&resultBuffer, _v, _c); + result.resize(resultBuffer.len); + return result; + } + + virtual uint64_t cipherBytes() const + { + return m_ihc->cipherBytes() + sizeof(uint16_t) + sizeof(int16_t); + } + +private: + inline void align(FloatingPointCipher& _c1, FloatingPointCipher& _c2) const + { + auto self = weak_from_this(); + precisionAlign( + _c1, _c2, [self](BIGNUM const* v, bcos::bytesConstRef const& _cipher) -> bcos::bytes { + auto impl = self.lock(); + if (!impl) + { + return bcos::bytes(); + } + return impl->m_ihc->scalaMul(v, _cipher); + }); + } + +private: + Ihc::Ptr m_ihc; +}; +} // namespace ppc::homo \ No newline at end of file diff --git a/cpp/wedpr-crypto/ppc-homo/ihc/IhcImpl.cpp b/cpp/wedpr-crypto/ppc-homo/ihc/IhcImpl.cpp new file mode 100644 index 00000000..b63cc6fd --- /dev/null +++ b/cpp/wedpr-crypto/ppc-homo/ihc/IhcImpl.cpp @@ -0,0 +1,179 @@ +/** + * Copyright (C) 2022 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 IhcImpl.cpp + * @author: asherli + * @date 2023-11-23 + */ +#include "IhcImpl.h" +#include "ppc-tools/src/codec/CodecUtility.h" + +using namespace ppc::homo; +using namespace ppc::crypto; + +// generate key according to given mode +BigNum IhcImpl::generateKeyImpl() const +{ + BigNum key; + do + { + randRange(key.bn().get(), m_codec->n().bn().get()); + } while (BN_is_zero(key.bn().get())); + return key; +} + +void IhcImpl::generateKey(OutputBuffer* _result) const +{ + if (_result->len < keyBytes()) + { + BOOST_THROW_EXCEPTION( + IhcException() << bcos::errinfo_comment( + "IHC error for un-enough key buffer, current len: " + std::to_string(_result->len) + + ", min key len: " + std::to_string(keyBytes()))); + } + auto key = generateKeyImpl(); + key.toOutputBuffer(_result, false); +} + +bcos::bytes IhcImpl::generateKey() const +{ + bcos::bytes result(keyBytes()); + generateKeyImpl().toBytes(result, false); + return result; +} +// encrypt the given value to cipher using given key +void IhcImpl::encrypt( + OutputBuffer* _cipher, bcos::bytesConstRef const& _key, BIGNUM const* _value) const +{ + auto v = m_codec->encode(_value); + + BigNum lastRoundV; + randRange(lastRoundV.bn().get(), m_codec->n().bn().get()); + BigNum key(_key, false); + auto ctx = createBNContext(); + for (int i = 0; i < m_iterRound; ++i) + { + BigNum tmp; + v.modMul(tmp.bn().get(), key.bn().get(), m_codec->n().bn().get(), ctx.get()); + tmp.modSub(tmp.bn().get(), lastRoundV.bn().get(), m_codec->n().bn().get(), ctx.get()); + lastRoundV = v; + v = tmp; + } + // c1: v + auto pEnd = _cipher->data + _cipher->len; + auto pBuffer = encodeBigNum(_cipher->data, pEnd, v); + // c2: lastRoundV + pBuffer = encodeBigNum(pBuffer, pEnd, lastRoundV); + _cipher->len = (pBuffer - _cipher->data); +} + +// decrypt the given cipher to value using given key +ppc::crypto::BigNum IhcImpl::decrypt( + bcos::bytesConstRef const& _key, bcos::bytesConstRef const& _cipher) const +{ + BigNum lastRoundV; + auto offset = decodeBigNum(lastRoundV, _cipher.data(), _cipher.size(), 0); + BigNum v; + decodeBigNum(v, _cipher.data(), _cipher.size(), offset); + BigNum key(_key, false); + auto ctx = createBNContext(); + for (int i = 0; i < m_iterRound - 1; ++i) + { + BigNum tmp; + v.modMul(tmp.bn().get(), key.bn().get(), m_codec->n().bn().get(), ctx.get()); + tmp.modSub(tmp.bn().get(), lastRoundV.bn().get(), m_codec->n().bn().get(), ctx.get()); + lastRoundV = v; + v = tmp; + } + return m_codec->decode(v); +} + +// ihc add +void IhcImpl::arithmeticImpl(OutputBuffer* _addResult, bcos::bytesConstRef const& _c1, + bcos::bytesConstRef const& _c2, ArithmeticType _type) const +{ + // c1 + BigNum leftV; + auto offset = decodeBigNum(leftV, _c1.data(), _c1.size(), 0); + BigNum leftLastRoundV; + decodeBigNum(leftLastRoundV, _c1.data(), _c1.size(), offset); + // c2 + BigNum rightV; + offset = decodeBigNum(rightV, _c2.data(), _c2.size(), 0); + BigNum rightLastRoundV; + decodeBigNum(rightLastRoundV, _c2.data(), _c2.size(), offset); + // c1 + c2 + BigNum resultV; + BigNum resultLastRoundV; + auto ctx = createBNContext(); + switch (_type) + { + case IhcImpl::ArithmeticType::ADD: + { + resultV = leftV.modAdd(rightV.bn().get(), m_codec->n().bn().get()); + resultLastRoundV = + leftLastRoundV.modAdd(rightLastRoundV.bn().get(), m_codec->n().bn().get()); + break; + } + case IhcImpl::ArithmeticType::SUB: + { + leftV.modSub(resultV.bn().get(), rightV.bn().get(), m_codec->n().bn().get(), ctx.get()); + leftLastRoundV.modSub(resultLastRoundV.bn().get(), rightLastRoundV.bn().get(), + m_codec->n().bn().get(), ctx.get()); + break; + } + default: + BOOST_THROW_EXCEPTION(IhcException() << bcos::errinfo_comment( + "Unsupported ArithmeticType: " + std::to_string((int)_type))); + } + auto pEnd = _addResult->data + _addResult->len; + auto pBuffer = encodeBigNum(_addResult->data, pEnd, resultV); + pBuffer = encodeBigNum(pBuffer, pEnd, resultLastRoundV); + _addResult->len = (pBuffer - _addResult->data); +} + +void IhcImpl::add( + OutputBuffer* _addResult, bcos::bytesConstRef const& _c1, bcos::bytesConstRef const& _c2) const +{ + arithmeticImpl(_addResult, _c1, _c2, IhcImpl::ArithmeticType::ADD); +} + +void IhcImpl::sub( + OutputBuffer* _subResult, bcos::bytesConstRef const& _c1, bcos::bytesConstRef const& _c2) const +{ + arithmeticImpl(_subResult, _c1, _c2, IhcImpl::ArithmeticType::SUB); +} + +// ihc scalaMul +void IhcImpl::scalaMul( + OutputBuffer* _mulResult, BIGNUM const* _value, bcos::bytesConstRef const& _cipher) const +{ + // c1 + BigNum leftV; + auto offset = decodeBigNum(leftV, _cipher.data(), _cipher.size(), 0); + BigNum leftLastRoundV; + decodeBigNum(leftLastRoundV, _cipher.data(), _cipher.size(), offset); + BigNum resultV; + BigNum resultLastRoundV; + auto ctx = createBNContext(); + + leftV.modMul(resultV.bn().get(), _value, m_codec->n().bn().get(), ctx.get()); + leftLastRoundV.modMul(resultLastRoundV.bn().get(), _value, m_codec->n().bn().get(), ctx.get()); + + auto pEnd = _mulResult->data + _mulResult->len; + auto pBuffer = encodeBigNum(_mulResult->data, pEnd, resultV); + pBuffer = encodeBigNum(pBuffer, pEnd, resultLastRoundV); + _mulResult->len = (pBuffer - _mulResult->data); +} \ No newline at end of file diff --git a/cpp/wedpr-crypto/ppc-homo/ihc/IhcImpl.h b/cpp/wedpr-crypto/ppc-homo/ihc/IhcImpl.h new file mode 100644 index 00000000..242a80a6 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-homo/ihc/IhcImpl.h @@ -0,0 +1,132 @@ +/** + * Copyright (C) 2022 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 IhcImpl.h + * @author: asherli + * @date 2023-11-23 + */ + +#pragma once +#include "ppc-framework/Common.h" +#include "ppc-framework/crypto/Ihc.h" +#include "ppc-homo/codec/SignedNumberCodec.h" +namespace ppc::homo +{ +DERIVE_PPC_EXCEPTION(IhcException); +// Ihc implementation: +class IhcImpl : public Ihc +{ +public: + using Ptr = std::shared_ptr; + IhcImpl(int _mode, int _iterRound) : m_mode(_mode), m_iterRound(_iterRound) + { + switch (_mode) + { + case (int)Ihc::IhcMode::IHC_128: + m_keyBits = 128; + break; + case (int)Ihc::IhcMode::IHC_256: + m_keyBits = 256; + break; + default: + BOOST_THROW_EXCEPTION(IhcException() << bcos::errinfo_comment( + "Unsupported mode, only support IHC_128/IHC_256 now")); + } + m_iterRound = 16; + m_codec = std::make_shared(m_keyBits); + } + ~IhcImpl() override {} + + // generate key according to given mode + bcos::bytes generateKey() const override; + void generateKey(OutputBuffer* _result) const override; + + // encrypt the given value to cipher using given key + void encrypt(OutputBuffer* _cipher, bcos::bytesConstRef const& _key, + BIGNUM const* _value) const override; + + bcos::bytes encrypt(bcos::bytesConstRef const& _key, BIGNUM const* _value) const override + { + bcos::bytes result(cipherBytes()); + OutputBuffer resultCipher{result.data(), result.size()}; + encrypt(&resultCipher, _key, _value); + result.resize(resultCipher.len); + return result; + } + + // decrypt the given cipher to value using given key + ppc::crypto::BigNum decrypt( + bcos::bytesConstRef const& _key, bcos::bytesConstRef const& _cipher) const override; + + // ihc add + void add(OutputBuffer* _addResult, bcos::bytesConstRef const& _c1, + bcos::bytesConstRef const& _c2) const override; + bcos::bytes add(bcos::bytesConstRef const& _c1, bcos::bytesConstRef const& _c2) const override + { + bcos::bytes result(cipherBytes()); + OutputBuffer buffer{result.data(), result.size()}; + add(&buffer, _c1, _c2); + result.resize(buffer.len); + return result; + } + // ihc sub + void sub(OutputBuffer* _subResult, bcos::bytesConstRef const& _c1, + bcos::bytesConstRef const& _c2) const override; + + bcos::bytes sub(bcos::bytesConstRef const& _c1, bcos::bytesConstRef const& _c2) const override + { + bcos::bytes result(cipherBytes()); + OutputBuffer buffer{result.data(), result.size()}; + sub(&buffer, _c1, _c2); + result.resize(buffer.len); + return result; + } + // ihc scalaMul + void scalaMul(OutputBuffer* _mulResult, BIGNUM const* _value, + bcos::bytesConstRef const& _cipher) const override; + + bcos::bytes scalaMul(BIGNUM const* _value, bcos::bytesConstRef const& _cipher) const override + { + bcos::bytes result(cipherBytes()); + OutputBuffer buffer{result.data(), result.size()}; + scalaMul(&buffer, _value, _cipher); + result.resize(buffer.len); + return result; + } + + unsigned int keyBits() const override { return m_keyBits; } + unsigned int keyBytes() const override { return (m_keyBits + 7) / 8; } + uint64_t cipherBytes() const override { return 6 + (m_keyBits * 2) / 8; } + + int mode() const { return m_mode; } + +private: + enum class ArithmeticType + { + ADD, + SUB, + }; + void arithmeticImpl(OutputBuffer* _addResult, bcos::bytesConstRef const& _c1, + bcos::bytesConstRef const& _c2, ArithmeticType _type) const; + + ppc::crypto::BigNum generateKeyImpl() const; + +private: + int m_mode; + int m_iterRound; + unsigned int m_keyBits; + SignedNumberCodec::Ptr m_codec; +}; +} // namespace ppc::homo diff --git a/cpp/wedpr-crypto/ppc-homo/paillier/CMakeLists.txt b/cpp/wedpr-crypto/ppc-homo/paillier/CMakeLists.txt new file mode 100644 index 00000000..d6856fcb --- /dev/null +++ b/cpp/wedpr-crypto/ppc-homo/paillier/CMakeLists.txt @@ -0,0 +1,5 @@ +file(GLOB_RECURSE SRCS *.cpp) +add_library(${PAILLIER_TARGET} ${SRCS}) + +find_package(OpenSSL REQUIRED) +target_link_libraries(${PAILLIER_TARGET} PUBLIC ${CRYPTO_CODEC_TARGET} ${BCOS_UTILITIES_TARGET} OpenSSL::Crypto ${CPU_FEATURES_LIB}) \ No newline at end of file diff --git a/cpp/wedpr-crypto/ppc-homo/paillier/Common.h b/cpp/wedpr-crypto/ppc-homo/paillier/Common.h new file mode 100644 index 00000000..ba332866 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-homo/paillier/Common.h @@ -0,0 +1,34 @@ +/* + * 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 Common.h + * @author: yujiechen + * @date 2023-8-4 + */ +#pragma once +#include "ppc-framework/Common.h" +#include + +#include + +#define HOMO_LOG(LEVEL) BCOS_LOG(LEVEL) << LOG_BADGE("HOMOCRYPTO") + +namespace ppc::homo +{ +DERIVE_PPC_EXCEPTION(InvalidHomoKeyPair); +DERIVE_PPC_EXCEPTION(InvalidHomoPublicKey); +DERIVE_PPC_EXCEPTION(OpenSSLPaillierException); +DERIVE_PPC_EXCEPTION(FloatingPointPaillierException); +} // namespace ppc::homo diff --git a/cpp/wedpr-crypto/ppc-homo/paillier/FloatingPointPaillier.cpp b/cpp/wedpr-crypto/ppc-homo/paillier/FloatingPointPaillier.cpp new file mode 100644 index 00000000..8c8fba9c --- /dev/null +++ b/cpp/wedpr-crypto/ppc-homo/paillier/FloatingPointPaillier.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 FloatingPointPaillier.cpp + * @author: yujiechen + * @date 2023-08-17 + */ + +#include "FloatingPointPaillier.h" +#include "../codec/Common.h" + +using namespace ppc::homo; +using namespace ppc::crypto; +using namespace ppc; + +void FloatingPointPaillier::encryptFast( + OutputBuffer* _result, FloatingPointNumber const& _value, void* _keyPair) const +{ + auto cipher = m_paillierImpl->encrypt_with_crt(_value.value.bn().get(), _keyPair); + FloatingPointCipher cipherObject(std::move(cipher), _value.exponent); + cipherObject.encode(_result); +} + +void FloatingPointPaillier::encrypt( + OutputBuffer* _result, FloatingPointNumber const& _value, void* _publicKey) const +{ + auto cipher = m_paillierImpl->encrypt(_value.value.bn().get(), _publicKey); + FloatingPointCipher cipherObject(std::move(cipher), _value.exponent); + cipherObject.encode(_result); +} + + +FloatingPointNumber FloatingPointPaillier::decrypt( + bcos::bytesConstRef const& _cipherData, void* _keyPair) const +{ + FloatingPointCipher cipherObject(_cipherData); + // decrypt + auto decodedV = m_paillierImpl->decrypt(bcos::ref(cipherObject.cipher()), _keyPair); + return FloatingPointNumber(std::move(decodedV), cipherObject.exponent()); +} + +void FloatingPointPaillier::align( + FloatingPointCipher& _c1, FloatingPointCipher& _c2, void* _publicKey) const +{ + if (!_publicKey) + { + BOOST_THROW_EXCEPTION(FloatingPointPaillierException() << bcos::errinfo_comment( + "precisionAlign for two-cipher error for invalid public key")); + } + auto self = weak_from_this(); + precisionAlign(_c1, _c2, + [self, _publicKey](BIGNUM const* v, bcos::bytesConstRef const& _cipher) -> bcos::bytes { + auto fpPaillier = self.lock(); + if (!fpPaillier) + { + return bcos::bytes(); + } + return fpPaillier->m_paillierImpl->scalaMul(v, _cipher, _publicKey); + }); +} + +void FloatingPointPaillier::add(OutputBuffer* _result, bcos::bytesConstRef const& _c1, + bcos::bytesConstRef const& _c2, void* _publicKey) const +{ + FloatingPointCipher c1Obj(_c1); + FloatingPointCipher c2Obj(_c2); + // align the precision + align(c1Obj, c2Obj, _publicKey); + auto addResult = + m_paillierImpl->add(bcos::ref(c1Obj.cipher()), bcos::ref(c2Obj.cipher()), _publicKey); + FloatingPointCipher cipherAddResult(std::move(addResult), c1Obj.exponent()); + cipherAddResult.encode(_result); +} + +void FloatingPointPaillier::sub(OutputBuffer* _result, bcos::bytesConstRef const& _c1, + bcos::bytesConstRef const& _c2, void* _publicKey) const +{ + FloatingPointCipher c1Obj(_c1); + FloatingPointCipher c2Obj(_c2); + // align the precision + align(c1Obj, c2Obj, _publicKey); + auto subResult = + m_paillierImpl->sub(bcos::ref(c1Obj.cipher()), bcos::ref(c2Obj.cipher()), _publicKey); + FloatingPointCipher cipherSubResult(std::move(subResult), c1Obj.exponent()); + cipherSubResult.encode(_result); +} + +void FloatingPointPaillier::scalaMul(OutputBuffer* _result, FloatingPointNumber const& _v, + bcos::bytesConstRef const& _c, void* _publicKey) const +{ + if (!_publicKey) + { + BOOST_THROW_EXCEPTION(FloatingPointPaillierException() + << bcos::errinfo_comment("scalaMul error for invalid public key")); + } + FloatingPointCipher cipherObject(_c); + auto mulResult = + m_paillierImpl->scalaMul(_v.value.bn().get(), bcos::ref(cipherObject.cipher()), _publicKey); + FloatingPointCipher cipherMulResult( + std::move(mulResult), cipherObject.exponent() + _v.exponent); + cipherMulResult.encode(_result); +} \ No newline at end of file diff --git a/cpp/wedpr-crypto/ppc-homo/paillier/FloatingPointPaillier.h b/cpp/wedpr-crypto/ppc-homo/paillier/FloatingPointPaillier.h new file mode 100644 index 00000000..a2e164e2 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-homo/paillier/FloatingPointPaillier.h @@ -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 FloatingPointPaillier.h + * @author: yujiechen + * @date 2023-08-17 + */ +#pragma once +#include "../codec/FloatingPointCipher.h" +#include "../codec/SignedNumberCodec.h" +#include "OpenSSLPaillier.h" +#include "ppc-framework/crypto/Paillier.h" +#include "ppc-framework/libwrapper/FloatingPointNumber.h" +#include + +namespace ppc::homo +{ +class FloatingPointPaillier : public std::enable_shared_from_this +{ +public: + using Ptr = std::shared_ptr; + FloatingPointPaillier(Paillier::Ptr const& _paillierImpl) : m_paillierImpl(_paillierImpl) {} + virtual ~FloatingPointPaillier() = default; + + virtual void encryptFast( + OutputBuffer* _result, ppc::FloatingPointNumber const& _value, void* _keyPair) const; + virtual void encrypt( + OutputBuffer* _result, ppc::FloatingPointNumber const& _value, void* _publicKey) const; + virtual ppc::FloatingPointNumber decrypt( + bcos::bytesConstRef const& _cipherData, void* _keyPair) const; + + virtual void add(OutputBuffer* _result, bcos::bytesConstRef const& _c1, + bcos::bytesConstRef const& c2, void* _publicKey) const; + virtual void sub(OutputBuffer* _result, bcos::bytesConstRef const& _c1, + bcos::bytesConstRef const& c2, void* _publicKey) const; + + // Note: the FloatingPointNumber maybe modified when aligning + virtual void scalaMul(OutputBuffer* _result, ppc::FloatingPointNumber const& _v, + bcos::bytesConstRef const& c, void* _publicKey) const; + + Paillier::Ptr const paillierImpl() const { return m_paillierImpl; } + static unsigned int maxCipherBytesLen(unsigned int _keyBits) + { + return sizeof(uint16_t) + sizeof(int16_t) + OpenSSLPaillier::maxCipherBytesLen(_keyBits); + } + +private: + // align the exponent between cipher c1 and c2 + void align(FloatingPointCipher& c1, FloatingPointCipher& c2, void* _publicKey) const; + +private: + Paillier::Ptr m_paillierImpl; + const ppc::crypto::BigNum C_BASE = ppc::crypto::BigNum(10); +}; +} // namespace ppc::homo \ No newline at end of file diff --git a/cpp/wedpr-crypto/ppc-homo/paillier/OpenSSLPaillier.cpp b/cpp/wedpr-crypto/ppc-homo/paillier/OpenSSLPaillier.cpp new file mode 100644 index 00000000..75a32d91 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-homo/paillier/OpenSSLPaillier.cpp @@ -0,0 +1,314 @@ +/** + * Copyright (C) 2022 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 OpenSSLPaillier.cpp + * @author: yujiechen + * @date 2023-08-04 + */ +#include "OpenSSLPaillier.h" +#include "Common.h" +#include "ppc-framework/libwrapper/BigNum.h" +#include + +using namespace ppc::homo; +using namespace ppc::crypto; +using namespace bcos; + +// generate the keypair +KeyPair::UniquePtr OpenSSLPaillier::generateKeyPair(unsigned const _keyBits) const +{ + BigNum gcdResult; + BigNum two; + BigNum pMinus; + BigNum qMinus; + two.setWord(2); + auto ctx = createBNContext(); + auto sk = std::make_shared(); + + do + { + // generate prime p and q, ensure p != q, and p = 3 mod 4, q = 3 mod 4 + do + { + sk->p.generatePrime(_keyBits / 2); + } while (!sk->p.isBitSet(1)); + do + { + sk->q.generatePrime(_keyBits / 2); + } while (!sk->q.isBitSet(1) || (sk->q.cmp(sk->p.bn().get()) == 0)); + // calculate p-1 and q-1 + pMinus = sk->p.sub(BN_value_one()); + qMinus = sk->q.sub(BN_value_one()); + + // calculate gcd(p-1, q-1), break when gcd(p-1, q-1) == 2 + pMinus.gcd(gcdResult.bn().get(), qMinus.bn().get(), ctx.get()); + } while (gcdResult.cmp(two.bn().get())); + + auto pk = std::make_shared(); + pk->keyBits = _keyBits; + sk->keyBits = _keyBits; + + // calculate n = p * q + sk->p.mul(pk->n.bn().get(), sk->q.bn().get(), ctx.get()); + + // generate random x + BigNum x; + randRange(x.bn().get(), pk->n.bn().get()); + // calculate h = -x^2 + x.mul(pk->h.bn().get(), x.bn().get(), ctx.get()); + BN_set_negative(pk->h.bn().get(), 1); + //// precompute + pk->precompute(); + + /// calculate secret key + // lambda = (p - 1) * (q-1)/2 + pMinus.mul(sk->lambda.bn().get(), qMinus.bn().get(), ctx.get()); + sk->lambda.divConst(2); + // precompute + sk->precompute(); + // return the paillier keypair + return std::make_unique(std::move(sk), std::move(pk)); +} + + +/// optimize (_base^_exp)mod(n^2) using CRT +/// refer to: https://zhuanlan.zhihu.com/p/420503254 +BigNum OpenSSLPaillier::powerModSqrtCrt( + BigNum const& _base, BigNum const& _exp, OpenSSLPaillierKeyPair* _keyPair) const +{ + auto sk = (PaillierPrivateKey*)(_keyPair->sk()); + auto pk = (PaillierPublicKey*)(_keyPair->pk()); + + auto ctx = createBNContext(); + // expp = _exp mod (p^2 - p) + BigNum expp; + _exp.div(NULL, expp.bn().get(), sk->pOrderSqrt.bn().get(), ctx.get()); + // baseP = _base mod p^2 + BigNum baseP; + _base.div(NULL, baseP.bn().get(), sk->pSqrt.bn().get(), ctx.get()); + // xp = baseP ^ expp mod p^2 + auto xp = baseP.modExp(expp.bn().get(), sk->pSqrt.bn().get(), ctx.get()); + + // expq = _exp mod (q^2 - q) + BigNum expq; + _exp.div(NULL, expq.bn().get(), sk->qOrderSqrt.bn().get(), ctx.get()); + // baseQ = _base mod q^2 + BigNum baseQ; + _base.div(NULL, baseQ.bn().get(), sk->qSqrt.bn().get(), ctx.get()); + // xq = baseQ ^ expq mod q^2 + auto xq = baseQ.modExp(expq.bn().get(), sk->qSqrt.bn().get(), ctx.get()); + + // crt to calculate (_base^_exp)mod(n^2) + // h = ((xp - xq)*(qSqrtInv)) mod p^2 + // _base^exp = xq + h * q^2 + auto result = xp.sub(xq.bn().get()); + BigNum tmp; + result.modMul(tmp.bn().get(), sk->qSqrtInverse.bn().get(), sk->pSqrt.bn().get(), ctx.get()); + tmp.mul(tmp.bn().get(), sk->qSqrt.bn().get(), ctx.get()); + + return tmp.modAdd(xq.bn().get(), pk->nSqrt.bn().get()); +} + +void OpenSSLPaillier::encryptImpl(OutputBuffer* _resultBuffer, OutputBuffer* _rBuffer, + BIGNUM const* _m, OpenSSLPaillierKeyPair* _keyPair, void* _pk) const +{ + auto pk = (PaillierPublicKey*)_pk; + // encode _m to support negative case + SignedNumberCodec codec(pk->n); + auto m = codec.encode(_m); + // calculate: g^m + // Note: since g=(n+1) when generate keypair, g^m can be speed up to [(mn + 1) mod n^2] + BigNum tmp; + auto ctx = createBNContext(); + m.mul(tmp.bn().get(), pk->n.bn().get(), ctx.get()); + auto g_power_m = tmp.modAdd(BN_value_one(), pk->nSqrt.bn().get()); + + // generate random r with ceil(|n|/2) bits + // rBits is ceil(keyBits) + auto rBits = pk->keyBits % 2 ? ((pk->keyBits / 2) + 1) : (pk->keyBits / 2); + auto r = generateRand(rBits); + // convert r to buffer + if (_rBuffer) + { + r.toOutputBuffer(_rBuffer, false); + } + // calculate r^n mod n^2, namely (h_s^r mod n^2) + BigNum r_power_n; + // with crt optimization + if (_keyPair && _keyPair->sk()) + { + r_power_n = powerModSqrtCrt(pk->h_s, r, _keyPair); + } + else + { + // without crt optmization + r_power_n = pk->h_s.modExp(r.bn().get(), pk->nSqrt.bn().get(), ctx.get()); + } + // (g^m) * (r^n) mod n^2 + BigNum result; + g_power_m.modMul(result.bn().get(), r_power_n.bn().get(), pk->nSqrt.bn().get(), ctx.get()); + result.toOutputBuffer(_resultBuffer, true); +} + +// encrypt the plain data +void OpenSSLPaillier::encrypt_with_crt( + OutputBuffer* _cipherBytes, OutputBuffer* _rBuffer, BIGNUM const* _v, void* _keyPair) const +{ + if (!_cipherBytes) + { + BOOST_THROW_EXCEPTION(OpenSSLPaillierException() << bcos::errinfo_comment( + "encrypt_with_crt error for Invalid OutputBuffer")); + } + if (!_v) + { + BOOST_THROW_EXCEPTION(OpenSSLPaillierException() + << bcos::errinfo_comment("encrypt_with_crt error for invalid _v")); + } + if (!_keyPair) + { + BOOST_THROW_EXCEPTION(OpenSSLPaillierException() << bcos::errinfo_comment( + "encrypt_with_crt error for invalid _keyPair")); + } + auto keyPair = (OpenSSLPaillierKeyPair*)_keyPair; + if (!keyPair->pk()) + { + BOOST_THROW_EXCEPTION(OpenSSLPaillierException() << bcos::errinfo_comment( + "encrypt_with_crt error for invalid publicKey")); + } + encryptImpl(_cipherBytes, _rBuffer, _v, keyPair, keyPair->pk()); +} + +// decrypt the cipher data +BigNum OpenSSLPaillier::decrypt(bcos::bytesConstRef const& _cipherData, void* _keyPair) const +{ + if (!_keyPair) + { + BOOST_THROW_EXCEPTION( + InvalidHomoKeyPair() << bcos::errinfo_comment("decrypt error for empty keypair")); + } + BigNum cipher(_cipherData); + auto keyPair = (OpenSSLPaillierKeyPair*)_keyPair; + auto sk = (PaillierPrivateKey*)(keyPair->sk()); + if (!sk) + { + BOOST_THROW_EXCEPTION( + InvalidHomoKeyPair() << bcos::errinfo_comment("decrypt error for empty sk")); + } + auto pk = (PaillierPublicKey*)(keyPair->pk()); + if (!pk) + { + BOOST_THROW_EXCEPTION( + InvalidHomoKeyPair() << bcos::errinfo_comment("decrypt error for empty pk")); + } + auto ctx = createBNContext(); + // calculate x = (cipher^lambda mod n^2) + auto x = powerModSqrtCrt(cipher, sk->lambda, keyPair); + // calculate (x-1)/n + BigNum result; + result = x.sub(BN_value_one()); + result.div(result.bn().get(), NULL, pk->n.bn().get(), ctx.get()); + + // result * lambdaInverse mod n + auto lambdaInverse = sk->lambda.Invert(pk->n); + result.modMul(result.bn().get(), lambdaInverse.bn().get(), pk->n.bn().get(), ctx.get()); + // decode result to support negative case + SignedNumberCodec codec(pk->n); + return codec.decode(result); +} + +void OpenSSLPaillier::addImpl(OutputBuffer* _resultBytes, ppc::crypto::BigNum const& _cipher1, + ppc::crypto::BigNum const& _cipher2, void* _publicKey) const +{ + // Note: the keypair contain only the public key + auto pk = (PaillierPublicKey*)(_publicKey); + // c1 * c2 mod n*n + auto ctx = createBNContext(); + BigNum result; + _cipher1.modMul(result.bn().get(), _cipher2.bn().get(), pk->nSqrt.bn().get(), ctx.get()); + bcos::bytes cipherResult; + result.toOutputBuffer(_resultBytes, true); +} + +void OpenSSLPaillier::add(OutputBuffer* _result, bcos::bytesConstRef const& _cipherData1, + bcos::bytesConstRef const& _cipherData2, void* _publicKey) const +{ + if (!_result) + { + BOOST_THROW_EXCEPTION(OpenSSLPaillierException() << bcos::errinfo_comment( + "paillier add error for Invalid OutputBuffer")); + } + if (!_publicKey) + { + BOOST_THROW_EXCEPTION(OpenSSLPaillierException() << bcos::errinfo_comment( + "paillier add error for invalid public key")); + } + BigNum cipher1(_cipherData1); + BigNum cipher2(_cipherData2); + addImpl(_result, cipher1, cipher2, _publicKey); +} + +void OpenSSLPaillier::sub(OutputBuffer* _resultBytes, bcos::bytesConstRef const& _cipherData1, + bcos::bytesConstRef const& _cipherData2, void* _publicKey) const +{ + if (!_resultBytes) + { + BOOST_THROW_EXCEPTION(OpenSSLPaillierException() << bcos::errinfo_comment( + "paillier sub error for Invalid OutputBuffer")); + } + if (!_publicKey) + { + BOOST_THROW_EXCEPTION(OpenSSLPaillierException() << bcos::errinfo_comment( + "paillier sub error for invalid public key")); + } + // Note: the keypair contain only the public key + auto pk = (PaillierPublicKey*)(_publicKey); + BigNum cipher1(_cipherData1); + BigNum cipher2(_cipherData2); + // ((c1 * (c2^-1)) mod n*n + auto cipher2Invert = cipher2.Invert(pk->nSqrt); + return addImpl(_resultBytes, cipher1, cipher2Invert, _publicKey); +} + +void OpenSSLPaillier::scalaMul(OutputBuffer* _resultBytes, BIGNUM const* _value, + bcos::bytesConstRef const& _cipherData, void* _publicKey) const +{ + if (!_resultBytes) + { + BOOST_THROW_EXCEPTION(OpenSSLPaillierException() << bcos::errinfo_comment( + "paillier scalaMul error for invalid OutputBuffer")); + } + if (!_value) + { + BOOST_THROW_EXCEPTION(OpenSSLPaillierException() << bcos::errinfo_comment( + "paillier scalaMul error for invalid input v")); + } + if (!_publicKey) + { + BOOST_THROW_EXCEPTION(OpenSSLPaillierException() << bcos::errinfo_comment( + "paillier scalaMul error for invalid public key")); + } + // Note: the keypair contain only the public key + auto pk = (PaillierPublicKey*)(_publicKey); + // encode to support negative v + SignedNumberCodec codec(pk->n); + auto v = codec.encode(_value); + + BigNum cipher(_cipherData); + + // cipher^v mod (n^2) + auto ctx = createBNContext(); + auto result = cipher.modExp(v.bn().get(), pk->nSqrt.bn().get(), ctx.get()); + result.toOutputBuffer(_resultBytes, true); +} \ No newline at end of file diff --git a/cpp/wedpr-crypto/ppc-homo/paillier/OpenSSLPaillier.h b/cpp/wedpr-crypto/ppc-homo/paillier/OpenSSLPaillier.h new file mode 100644 index 00000000..ef8810e1 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-homo/paillier/OpenSSLPaillier.h @@ -0,0 +1,170 @@ +/** + * Copyright (C) 2022 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 OpenSSLPaillier.h + * @author: yujiechen + * @date 2023-08-04 + */ +#pragma once +#include "../codec/SignedNumberCodec.h" +#include "Common.h" +#include "OpenSSLPaillierKeyPair.h" +#include + +namespace ppc::homo +{ +class OpenSSLPaillier : public Paillier +{ +public: + using Ptr = std::shared_ptr; + OpenSSLPaillier() = default; + virtual ~OpenSSLPaillier() = default; + + // generate the keypair + ppc::crypto::KeyPair::UniquePtr generateKeyPair(unsigned const _keyLength) const override; + + // encrypt the plain data + void encrypt_with_crt(OutputBuffer* _resultBuffer, OutputBuffer* _rBuffer, BIGNUM const* v, + void* _keyPair) const override; + + bcos::bytes encrypt_with_crt(BIGNUM const* _value, void* _keyPair) const override + { + auto keyPair = (OpenSSLPaillierKeyPair*)_keyPair; + if (!keyPair || !keyPair->sk() || !keyPair->pk()) + { + BOOST_THROW_EXCEPTION(InvalidHomoKeyPair()); + } + auto pk = (PaillierPublicKey*)keyPair->pk(); + bcos::bytes result(maxCipherBytesLen(pk->keyBits), 0); + OutputBuffer buffer{result.data(), result.size()}; + encrypt_with_crt(&buffer, nullptr, _value, keyPair); + result.resize(buffer.len); + return result; + } + + void encrypt(OutputBuffer* _result, OutputBuffer* _rBuffer, BIGNUM const* _value, + void* _pk) const override + { + encryptImpl(_result, _rBuffer, _value, nullptr, _pk); + } + bcos::bytes encrypt(BIGNUM const* _value, void* _pk) const override + { + if (!_value) + { + BOOST_THROW_EXCEPTION(OpenSSLPaillierException() + << bcos::errinfo_comment("encrypt error for invalid input v")); + } + if (!_pk) + { + BOOST_THROW_EXCEPTION(OpenSSLPaillierException() + << bcos::errinfo_comment("encrypt error for invalid public key")); + } + auto pk = (PaillierPublicKey*)_pk; + bcos::bytes result(maxCipherBytesLen(pk->keyBits), 0); + OutputBuffer buffer{result.data(), result.size()}; + encrypt(&buffer, nullptr, _value, _pk); + result.resize(buffer.len); + return result; + } + + // decrypt the cipher data + ppc::crypto::BigNum decrypt( + bcos::bytesConstRef const& _cipherData, void* _keyPair) const override; + + // _result = _cipher1 + _cipher2 + void add(OutputBuffer* _result, bcos::bytesConstRef const& _cipher1, + bcos::bytesConstRef const& _cipher2, void* _publicKey) const override; + + bcos::bytes add(bcos::bytesConstRef const& _cipher1, bcos::bytesConstRef const& _cipher2, + void* _publicKey) const override + { + if (!_publicKey) + { + BOOST_THROW_EXCEPTION(InvalidHomoPublicKey()); + } + auto pk = (PaillierPublicKey*)_publicKey; + bcos::bytes result(maxCipherBytesLen(pk->keyBits), 0); + OutputBuffer buffer{result.data(), result.size()}; + add(&buffer, _cipher1, _cipher2, _publicKey); + result.resize(buffer.len); + return result; + } + + // _result = _cipher1 - _cipher2 + void sub(OutputBuffer* _result, bcos::bytesConstRef const& _cipher1, + bcos::bytesConstRef const& _cipher2, void* _publicKey) const override; + + bcos::bytes sub(bcos::bytesConstRef const& _cipher1, bcos::bytesConstRef const& _cipher2, + void* _publicKey) const override + { + if (!_publicKey) + { + BOOST_THROW_EXCEPTION(InvalidHomoPublicKey()); + } + auto pk = (PaillierPublicKey*)_publicKey; + bcos::bytes result(maxCipherBytesLen(pk->keyBits), 0); + + OutputBuffer buffer{result.data(), result.size()}; + sub(&buffer, _cipher1, _cipher2, _publicKey); + result.resize(buffer.len); + return result; + } + + // _result = _v * _cipher + void scalaMul(OutputBuffer* _result, BIGNUM const* _v, bcos::bytesConstRef const& _cipher, + void* _publicKey) const override; + + bcos::bytes scalaMul( + BIGNUM const* v, bcos::bytesConstRef const& _cipher, void* _publicKey) const override + { + if (!_publicKey) + { + BOOST_THROW_EXCEPTION(InvalidHomoPublicKey()); + } + auto pk = (PaillierPublicKey*)_publicKey; + bcos::bytes result(maxCipherBytesLen(pk->keyBits), 0); + + OutputBuffer buffer{result.data(), result.size()}; + scalaMul(&buffer, v, _cipher, _publicKey); + result.resize(buffer.len); + + return result; + } + + // calculate the cipherBytesLen + static unsigned int maxCipherBytesLen(unsigned int _keyBits) + { + // 1(the signed/unsigned flag) + _keyBits * 2/ 8 + return ((_keyBits) >> 2) + 1; + } + + static unsigned int rBytesLen(unsigned int _keyBits) + { + auto rBits = _keyBits % 2 ? ((_keyBits / 2) + 1) : (_keyBits / 2); + return (rBits + 7) >> 3; + } + +protected: + virtual void encryptImpl(OutputBuffer* _resultBuffer, OutputBuffer* _rBuffer, BIGNUM const* m, + OpenSSLPaillierKeyPair* _keyPair, void* _pk) const; + + void addImpl(OutputBuffer* _result, ppc::crypto::BigNum const& _cipher1, + ppc::crypto::BigNum const& _cipher2, void* _publicKey) const; + +private: + ppc::crypto::BigNum powerModSqrtCrt(ppc::crypto::BigNum const& _base, + ppc::crypto::BigNum const& _exp, OpenSSLPaillierKeyPair* _keyPair) const; +}; +} // namespace ppc::homo \ No newline at end of file diff --git a/cpp/wedpr-crypto/ppc-homo/paillier/OpenSSLPaillierKeyPair.cpp b/cpp/wedpr-crypto/ppc-homo/paillier/OpenSSLPaillierKeyPair.cpp new file mode 100644 index 00000000..40b04d23 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-homo/paillier/OpenSSLPaillierKeyPair.cpp @@ -0,0 +1,76 @@ +/** + * Copyright (C) 2022 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 OpenSSLPaillierKeyPair.cpp + * @author: yujiechen + * @date 2023-08-07 + */ +#include "OpenSSLPaillierKeyPair.h" + +using namespace ppc::homo; +using namespace ppc; +using namespace ppc::crypto; + +// serialize the sk +int PaillierPrivateKey::serialize(bcos::byte* _encodedData, unsigned int _dataLen) const +{ + auto pEnd = _encodedData + _dataLen; + // keyBits + auto pBuffer = encodeInteger(_encodedData, pEnd, keyBits); + // lambda + pBuffer = encodeBigNum(pBuffer, pEnd, lambda); + // p + pBuffer = encodeBigNum(pBuffer, pEnd, p); + // q + pBuffer = encodeBigNum(pBuffer, pEnd, q); + return (pBuffer - _encodedData); +} + +// serialize the pk +int PaillierPublicKey::serialize(bcos::byte* _encodedData, unsigned int _dataLen) const +{ + auto pEnd = _encodedData + _dataLen; + // encode the keyBits + auto pBuffer = encodeInteger(_encodedData, pEnd, keyBits); + // n + pBuffer = encodeBigNum(pBuffer, pEnd, n); + // h + pBuffer = encodeBigNum(pBuffer, pEnd, h); + return (pBuffer - _encodedData); +} + +// deserialize the sk +void PaillierPrivateKey::deserialize(bcos::byte const* _sk, unsigned int _len) +{ + // keyBits + auto offset = decodeInteger(keyBits, _sk, _len, 0); + // lambda + offset = decodeBigNum(lambda, _sk, _len, offset); + // p + offset = decodeBigNum(p, _sk, _len, offset); + // q + offset = decodeBigNum(q, _sk, _len, offset); +} + +// deserialize the pk +void PaillierPublicKey::deserialize(bcos::byte const* _pk, unsigned int _len) +{ + // keyBits + auto offset = decodeInteger(keyBits, _pk, _len, 0); + // n + offset = decodeBigNum(n, _pk, _len, offset); + // h + offset = decodeBigNum(h, _pk, _len, offset); +} \ No newline at end of file diff --git a/cpp/wedpr-crypto/ppc-homo/paillier/OpenSSLPaillierKeyPair.h b/cpp/wedpr-crypto/ppc-homo/paillier/OpenSSLPaillierKeyPair.h new file mode 100644 index 00000000..75d13cf7 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-homo/paillier/OpenSSLPaillierKeyPair.h @@ -0,0 +1,190 @@ +/** + * Copyright (C) 2022 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 OpenSSLPaillierKeyPair.h + * @author: yujiechen + * @date 2023-08-07 + */ +#pragma once + +#include "ppc-framework/crypto/KeyPair.h" +#include "ppc-framework/libwrapper/BigNum.h" +#include "ppc-tools/src/codec/CodecUtility.h" + +namespace ppc::homo +{ +///////////// Paillier-DJN ///////////// +/// the paillier public key +class PaillierPublicKey +{ +public: + using Ptr = std::shared_ptr; + using UniquePtr = std::unique_ptr; + PaillierPublicKey() = default; + PaillierPublicKey(bcos::byte const* _pk, unsigned int _len) + { + deserialize(_pk, _len); + precompute(); + } + virtual ~PaillierPublicKey() = default; + + /////// the stored-elements + unsigned int keyBits; // the length of the public key + ppc::crypto::BigNum n; // the public key + ppc::crypto::BigNum h; // -x^2 + + ////// the precomputed-fields + ppc::crypto::BigNum nSqrt; // cached for avoid recomputing, precalculation to improve + // performance, size is keyBits*2 + ppc::crypto::BigNum h_s; // h^n mod n^2, precalculation to improve performance, size is + // keyBits*2 + + // serialize the pk into _encodedData, return the serialized size + virtual int serialize(bcos::byte* _encodedData, unsigned int _dataLen) const; + // deserialize the pk + virtual void deserialize(bcos::byte const* _pk, unsigned int _len); + + void precompute() + { + // calculate nSqrt = n^2 + auto ctx = ppc::crypto::createBNContext(); + n.mul(nSqrt.bn().get(), n.bn().get(), ctx.get()); + // calculate h_s = (h^n) mod (n^2) + h_s = h.modExp(n.bn().get(), nSqrt.bn().get(), ctx.get()); + } + + static unsigned int maxBytes(unsigned int _keyBits) + { + // sizeof(keyBits) + keyBits/8(n Bytes) + 2 * keyBits/8(h Bytes) + sizeof(uint16_t) * + // BigNumFieldNum + BigNumFieldNum + // = sizeof(keyBits) + (3*KeyBits + 7)/8 + sizeof(uint16_t) * 2 + 2; + return sizeof(_keyBits) + (3 * _keyBits + 7) / 8 + 6; + } +}; + +/// the paillier private key +class PaillierPrivateKey +{ +public: + using Ptr = std::shared_ptr; + using UniquePtr = std::unique_ptr; + PaillierPrivateKey() = default; + PaillierPrivateKey(bcos::byte const* _pk, unsigned int _len) + { + deserialize(_pk, _len); + precompute(); + } + virtual ~PaillierPrivateKey() = default; + + ////// the stored-fields + unsigned int keyBits; // the length of the public key + ppc::crypto::BigNum lambda; // the private key, keyBits size + ppc::crypto::BigNum p; // p, keyBits/2 + ppc::crypto::BigNum q; // q, keyBits/2 + + ////// the precompute fields + ppc::crypto::BigNum pSqrt; // p^2, precalculation to improve performance, keyBits size + ppc::crypto::BigNum qSqrt; // q^2, precalculation to improve performance, keyBits size + ppc::crypto::BigNum qSqrtInverse; // (q^2)^(-1) mod(p^2), precalculation to improve + // performance, keyBits size + ppc::crypto::BigNum pOrderSqrt; // (p*(p-1)), keyBits size + ppc::crypto::BigNum qOrderSqrt; // (q*(q - 1)), keyBits size + + + // serialize the sk into _encodedData, return the serialized size + virtual int serialize(bcos::byte* _encodedData, unsigned int _dataLen) const; + // deserialize the sk + virtual void deserialize(bcos::byte const* _pk, unsigned int _len); + + virtual void precompute() + { + auto ctx = ppc::crypto::createBNContext(); + /// calculate pSqrt and qSqrt + p.mul(pSqrt.bn().get(), p.bn().get(), ctx.get()); + q.mul(qSqrt.bn().get(), q.bn().get(), ctx.get()); + // (q^2)^(-1) mod(p^2) + qSqrtInverse = qSqrt.Invert(pSqrt); + // calculate pOrderSqrt(p*(p-1)) and qOrderSqrt(q*(q - 1)) + pOrderSqrt = pSqrt.sub(p.bn().get()); + qOrderSqrt = qSqrt.sub(q.bn().get()); + } + + static unsigned int maxBytes(unsigned int _keyBits) + { + // sizeof(keyBits) + (lambda_length + p_length + q_length) + (lambda_signed_flag + + // p_signed_flag + q_signed_flag) + (lambda_buffer_len + p_buffer_len + q_buffer_len) + // = sizeof(keyBits) + (2*_keyBits + 7)/8 + BigNumFieldNum + BigNumFieldNum * + // = sizeof(keyBits) + (2*_keyBits + 7)/8 + 3 + 3 * sizeof(int16_t) + // = sizeof(uint16_t) + (2 * _keyBits + 7)/8 + 9 + return sizeof(_keyBits) + (2 * _keyBits + 7) / 8 + 9; + } +}; + +class OpenSSLPaillierKeyPair : public ppc::crypto::KeyPair +{ +public: + using Ptr = std::shared_ptr; + using UniquePtr = std::unique_ptr; + OpenSSLPaillierKeyPair(PaillierPrivateKey::Ptr&& _sk, PaillierPublicKey::Ptr&& _pk) + : m_sk(std::move(_sk)), m_pk(std::move(_pk)) + {} + + OpenSSLPaillierKeyPair( + bcos::byte const* _sk, unsigned int _skLen, bcos::byte const* _pk, unsigned int _pkLen) + : m_sk(std::make_shared(_sk, _skLen)), + m_pk(std::make_shared(_pk, _pkLen)) + {} + + OpenSSLPaillierKeyPair(bcos::bytes const& _sk, bcos::bytes const& _pk) + : OpenSSLPaillierKeyPair(_sk.data(), _sk.size(), _pk.data(), _pk.size()) + {} + + void* sk() const override { return (void*)m_sk.get(); } + void* pk() const override { return (void*)m_pk.get(); } + + // serialize the sk + bcos::bytes serializeSK() const override + { + bcos::bytes skData; + skData.resize(PaillierPrivateKey::maxBytes(m_sk->keyBits)); + if (m_sk) + { + auto dataSize = m_sk->serialize(skData.data(), skData.size()); + skData.resize(dataSize); + } + return skData; + } + + // serialize the pk + bcos::bytes serializePK() const override + { + bcos::bytes pkData; + pkData.resize(PaillierPublicKey::maxBytes(m_pk->keyBits)); + if (m_pk) + { + auto dataSize = m_pk->serialize(pkData.data(), pkData.size()); + pkData.resize(dataSize); + } + return pkData; + } + +private: + // the private key + PaillierPrivateKey::Ptr m_sk; + + // the public key + PaillierPublicKey::Ptr m_pk; +}; +} // namespace ppc::homo \ No newline at end of file diff --git a/cpp/wedpr-crypto/ppc-homo/tests/CMakeLists.txt b/cpp/wedpr-crypto/ppc-homo/tests/CMakeLists.txt new file mode 100644 index 00000000..de4051c9 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-homo/tests/CMakeLists.txt @@ -0,0 +1,10 @@ +file(GLOB_RECURSE SOURCES "*.cpp" "*.h") + +# cmake settings +set(TEST_BINARY_NAME test-ppc-homo) + +add_executable(${TEST_BINARY_NAME} ${SOURCES}) +target_include_directories(${TEST_BINARY_NAME} PRIVATE .) + +target_link_libraries(${TEST_BINARY_NAME} ${FAHE_TARGET} ${PAILLIER_TARGET} ${IHC_TARGET} ${BOOST_UNIT_TEST}) +add_test(NAME test-ppc-homo WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} COMMAND ${TEST_BINARY_NAME}) \ No newline at end of file diff --git a/cpp/wedpr-crypto/ppc-homo/tests/TestFahe.cpp b/cpp/wedpr-crypto/ppc-homo/tests/TestFahe.cpp new file mode 100644 index 00000000..2f31b731 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-homo/tests/TestFahe.cpp @@ -0,0 +1,108 @@ +/* + * 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 applicabl 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 TestFahe.cpp + * @author: yujiechen + * @date 2023-08-30 + */ +#include "ppc-homo/fahe/Fahe.h" +#include +#include +#include + +using namespace ppc::crypto; +using namespace ppc::homo; +using namespace bcos; +using namespace bcos::test; +namespace ppc::test +{ +BOOST_FIXTURE_TEST_SUITE(faheTest, TestPromptFixture) +void testFaheImpl(BigNum const& m1, BigNum const& m2, int lambda, int mmax, int alpha) +{ + auto faheImpl = std::make_shared(); + auto key = faheImpl->generateKey(lambda, mmax, alpha); + + // test encrypt/decrypt + auto c1 = faheImpl->encrypt(m1.bn().get(), key.get()); + bcos::bytes cipherBytes; + c1.toBytes(cipherBytes); + std::cout << "### cipherLen: " << cipherBytes.size() << std::endl; + auto decryptedM1 = faheImpl->decrypt(c1.bn().get(), key.get()); + std::cout << "### m1: "; + BN_print_fp(stdout, m1.bn().get()); + std::cout << std::endl; + std::cout << "### decryptedM1: "; + BN_print_fp(stdout, decryptedM1.bn().get()); + std::cout << std::endl; + + BOOST_CHECK(decryptedM1.cmp(m1.bn().get()) == 0); + + auto c2 = faheImpl->encrypt(m2.bn().get(), key.get()); + auto decryptedM2 = faheImpl->decrypt(c2.bn().get(), key.get()); + + std::cout << "### m2: "; + BN_print_fp(stdout, m2.bn().get()); + std::cout << std::endl; + std::cout << "### decryptedM2: "; + BN_print_fp(stdout, decryptedM2.bn().get()); + std::cout << std::endl; + + BOOST_CHECK(decryptedM2.cmp(m2.bn().get()) == 0); + + // add + auto addResult = faheImpl->add(c1.bn().get(), c2.bn().get()); + auto decryptAddResult = faheImpl->decrypt(addResult.bn().get(), key.get()); + auto expectedAddResult = m1.add(m2.bn().get()); + + std::cout << "### decryptAddResult: "; + BN_print_fp(stdout, decryptAddResult.bn().get()); + std::cout << std::endl; + std::cout << "### expectedAddResult: "; + BN_print_fp(stdout, expectedAddResult.bn().get()); + std::cout << std::endl; + BOOST_CHECK(decryptAddResult.cmp(expectedAddResult.bn().get()) == 0); +} + +BOOST_AUTO_TEST_CASE(testFahe) +{ + int lambda = 128; + int alpha = 32; + int mmax = 64; + + // positive case + int64_t m1 = 123213231; + int64_t m2 = 234343430; + std::cout << "==== testFahe positive =====" << std::endl; + testFaheImpl(BigNum(m1), BigNum(m2), lambda, mmax, alpha); + std::cout << "==== testFahe positive finished=====" << std::endl; + + // zero case + std::cout << "==== testFahe zero case =====" << std::endl; + m2 = 0; + testFaheImpl(BigNum(m1), BigNum(m2), lambda, mmax, alpha); + m1 = 0; + testFaheImpl(BigNum(m1), BigNum(m2), lambda, mmax, alpha); + std::cout << "==== testFahe zero case finished =====" << std::endl; + + // negative case + std::cout << "==== testFahe negative case =====" << std::endl; + m1 = 123213231 + bcos::utcSteadyTime(); + srand(bcos::utcSteadyTime()); + m2 = -(123213231 + bcos::utcSteadyTime() + rand()); + testFaheImpl(BigNum(m1), BigNum(m2), lambda, mmax, alpha); + std::cout << "==== testFahe negative case finished =====" << std::endl; +} +BOOST_AUTO_TEST_SUITE_END() +} // namespace ppc::test \ No newline at end of file diff --git a/cpp/wedpr-crypto/ppc-homo/tests/TestFloatingPointCodec.cpp b/cpp/wedpr-crypto/ppc-homo/tests/TestFloatingPointCodec.cpp new file mode 100644 index 00000000..857bb686 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-homo/tests/TestFloatingPointCodec.cpp @@ -0,0 +1,258 @@ +/* + * 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 applicabl 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 TestFloatingPointCodec.cpp + * @author: yujiechen + * @date 2023-08-29 + */ +#include "ppc-homo/codec/FloatingPointCodec.h" +#include +#include +#include +#include + +using namespace ppc::crypto; +using namespace ppc::homo; +using namespace bcos; +using namespace bcos::test; +namespace ppc::test +{ +BOOST_FIXTURE_TEST_SUITE(floatingPointCodecTest, TestPromptFixture) +void testDoubleCase(FloatingPointNumber const& _number, std::string const& _expectedVStr) +{ + float50 _expectedV(_expectedVStr); + auto codec = std::make_shared(); + auto float50V = codec->toFloat50(_number); + std::cout << std::fixed << std::setprecision(8); + std::cout << "float50V: " << float50V << ", expected:" << _expectedV << std::endl; + std::cout << "epsilon: " << std::numeric_limits::epsilon() << std::endl; + BOOST_CHECK(fabs(float50V - _expectedV) < std::numeric_limits::epsilon()); + + // convert float50V to FloatingPointNumber + auto convertedNumber = codec->toFloatingPoint(_expectedVStr); + std::cout << "exp: " << convertedNumber.exponent << std::endl; + std::cout << "value: " << convertedNumber.value.getWord() << std::endl; + + // encode the convertedNumber again + auto convertedV = codec->toFloat50(convertedNumber); + BOOST_CHECK(fabs(convertedV - _expectedV) < std::numeric_limits::epsilon()); +} + +void testIntCase(FloatingPointNumber const& _number, s1024 const& _expectedV) +{ + // encode + auto codec = std::make_shared(); + auto v = codec->toInt(_number); + std::cout << "v: " << v << ", _expectedV: " << _expectedV << std::endl; + BOOST_CHECK(v == _expectedV); + + // decode + auto convertedNumber = codec->toFloatingPoint(_expectedV); + + // encode again and check + auto convertedV = codec->toInt(convertedNumber); + BOOST_CHECK(_expectedV == convertedV); +} + +void testBigNumCovert(s1024 _expectedV) +{ + BigNum bn(_expectedV); + BigNum expectedBn(_expectedV); + BOOST_CHECK(bn.cmp(expectedBn.bn().get()) == 0); + + // test to S1024 + auto expectedS1024 = bn.toS1024(); + BOOST_CHECK(expectedS1024 == _expectedV); +} + +BOOST_AUTO_TEST_CASE(testBigNumConvert) +{ + s1024 value("123243432444440000234234323423424"); + testBigNumCovert(value); + + for (int i = 0; i < 5; i++) + { + int64_t expectedV = 123123342343 + utcSteadyTime(); + s1024 value(expectedV); + testBigNumCovert(value); + + expectedV = -(123123342343 + utcSteadyTime()); + value = s1024(expectedV); + testBigNumCovert(value); + } +} + +BOOST_AUTO_TEST_CASE(testDouble) +{ + std::cout << "==== test decimal case ===== " << std::endl; + std::string expectedV("2.23434"); + FloatingPointNumber fpNumber; + fpNumber.exponent = -5; + s1024 significant = s1024(223434); + BigNum significantBn(significant); + fpNumber.value = significantBn; + testDoubleCase(fpNumber, expectedV); + + expectedV = "2.2343432423423431"; + fpNumber.exponent = -16; + significant = s1024(22343432423423431); + BigNum significantBn2(significant); + fpNumber.value = significantBn2; + testDoubleCase(fpNumber, expectedV); + + + expectedV = "2234.3432423423431"; + fpNumber.exponent = -13; + significant = s1024(22343432423423431); + BigNum significantBn3(significant); + fpNumber.value = significantBn3; + testDoubleCase(fpNumber, expectedV); + + + expectedV = "2234343242342.3431"; + fpNumber.exponent = -4; + significant = s1024(22343432423423431); + BigNum significantBn4(significant); + fpNumber.value = significantBn4; + testDoubleCase(fpNumber, expectedV); + + expectedV = "2234343242342343.1"; + fpNumber.exponent = -1; + significant = s1024(22343432423423431); + BigNum significantBn5(significant); + fpNumber.value = significantBn5; + testDoubleCase(fpNumber, expectedV); + + expectedV = "22343432423423431"; + fpNumber.exponent = 0; + significant = s1024(22343432423423431); + BigNum significantBn6(significant); + fpNumber.value = significantBn6; + testDoubleCase(fpNumber, expectedV); + std::cout << "==== test decimal case finished ===== " << std::endl; + + // the positive case + std::cout << "==== test positive case ===== " << std::endl; + expectedV = "22343432423100"; + fpNumber.exponent = 2; + BigNum significantBn7(223434324231); + fpNumber.value = significantBn7; + testDoubleCase(fpNumber, expectedV); + std::cout << "==== test positive case finish ===== " << std::endl; + + std::cout << "==== test zero case ===== " << std::endl; + // zero + expectedV = "0"; + fpNumber.exponent = 10; + BigNum zero(0); + fpNumber.value = zero; + testDoubleCase(fpNumber, expectedV); + std::cout << "==== test zero case finish===== " << std::endl; + + std::cout << "==== test negative case =====" << std::endl; + expectedV = "-22343432423423431"; + fpNumber.exponent = 0; + significant = s1024(-22343432423423431); + BigNum significantBn8(significant); + fpNumber.value = significantBn8; + testDoubleCase(fpNumber, expectedV); + + expectedV = "-22343432423423.431"; + fpNumber.exponent = -3; + significant = s1024(-22343432423423431); + BigNum significantBn9(significant); + fpNumber.value = significantBn9; + testDoubleCase(fpNumber, expectedV); + + expectedV = "-22.343432423423431"; + fpNumber.exponent = -15; + significant = s1024(-22343432423423431); + BigNum significantBn10(significant); + fpNumber.value = significantBn10; + testDoubleCase(fpNumber, expectedV); + std::cout << "==== test negative case finish===== " << std::endl; +} +BOOST_AUTO_TEST_CASE(testInt) +{ + std::cout << "==== test int case =====" << std::endl; + s1024 expectedV = s1024("223434323222342343242342343234300000"); + FloatingPointNumber fpNumber; + fpNumber.exponent = 5; + s1024 significant = s1024("2234343232223423432423423432343"); + BigNum tmp(significant); + fpNumber.value = tmp; + testIntCase(fpNumber, expectedV); + + expectedV = 200; + fpNumber.exponent = 2; + BigNum tmp1(2); + fpNumber.value = tmp1; + testIntCase(fpNumber, expectedV); + + expectedV = 2000000000000; + fpNumber.exponent = -2; + BigNum tmp2(200000000000000); + fpNumber.value = tmp2; + testIntCase(fpNumber, expectedV); + + expectedV = 2000000000001; + fpNumber.exponent = -2; + BigNum tmp3(200000000000100); + fpNumber.value = tmp3; + testIntCase(fpNumber, expectedV); + + expectedV = 200000000000; + fpNumber.exponent = -3; + BigNum tmp4(200000000000100); + fpNumber.value = tmp4; + testIntCase(fpNumber, expectedV); + + // Note: not support floor + expectedV = 200000000000; + fpNumber.exponent = -3; + BigNum tmp5(200000000000900); + fpNumber.value = tmp5; + testIntCase(fpNumber, expectedV); + std::cout << "==== test int case finish=====" << std::endl; + + std::cout << "==== test zero case =====" << std::endl; + expectedV = 0; + BigNum tmp6(0); + fpNumber.value = tmp6; + testIntCase(fpNumber, expectedV); + std::cout << "==== test zero case finish=====" << std::endl; + + std::cout << "==== test negative case =====" << std::endl; + expectedV = -200; + fpNumber.exponent = 2; + BigNum tmp7(-2); + fpNumber.value = tmp7; + testIntCase(fpNumber, expectedV); + + expectedV = -2000000000000; + fpNumber.exponent = -2; + BigNum tmp8(-200000000000000); + fpNumber.value = tmp8; + testIntCase(fpNumber, expectedV); + + expectedV = -200000000000; + fpNumber.exponent = -3; + BigNum tmp9(-200000000000900); + fpNumber.value = tmp9; + testIntCase(fpNumber, expectedV); + std::cout << "==== test negative case finish=====" << std::endl; +} +BOOST_AUTO_TEST_SUITE_END() +} // namespace ppc::test \ No newline at end of file diff --git a/cpp/wedpr-crypto/ppc-homo/tests/TestFloatingPointPaillier.cpp b/cpp/wedpr-crypto/ppc-homo/tests/TestFloatingPointPaillier.cpp new file mode 100644 index 00000000..f04c8a88 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-homo/tests/TestFloatingPointPaillier.cpp @@ -0,0 +1,160 @@ +/** + * Copyright (C) 2022 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 TestFloatingPointPaillier.cpp + * @author: yujiechen + * @date 2023-08-29 + */ +#include "ppc-homo/codec/FloatingPointCodec.h" +#include "ppc-homo/paillier/FloatingPointPaillier.h" +#include "ppc-homo/paillier/OpenSSLPaillier.h" +#include +#include +#include + +using namespace ppc::crypto; +using namespace ppc::homo; +using namespace bcos; +using namespace bcos::test; + +namespace ppc::test +{ +BOOST_FIXTURE_TEST_SUITE(floatingPointPaillierTest, TestPromptFixture) + +void testPaillierHomoProperty(int _keyBits, std::string const& s1, std::string const& s2, + std::string const& s3, double epsilon) +{ + float50 m1(s1); + float50 m2(s2); + float50 v(s3); + auto codec = std::make_shared(); + auto m1Fp = codec->toFloatingPoint(s1); + auto m2Fp = codec->toFloatingPoint(s2); + auto vFp = codec->toFloatingPoint(s3); + std::cout << "* exp for m1: " << m1Fp.exponent << ", value: " << m1Fp.value.getWord() + << std::endl; + std::cout << "* exp for m2: " << m2Fp.exponent << ", value: " << m2Fp.value.getWord() + << std::endl; + + auto paillierImpl = std::make_shared(); + auto fpPaillier = std::make_shared(paillierImpl); + // generate keypair + auto keyPair = paillierImpl->generateKeyPair(_keyBits); + std::cout << "===== encrypt/decrypt check ======" << std::endl; + // encrypt m1 + bcos::bytes c1(FloatingPointPaillier::maxCipherBytesLen(_keyBits), 0); + OutputBuffer c1Buffer{c1.data(), c1.size()}; + fpPaillier->encryptFast(&c1Buffer, m1Fp, (void*)keyPair.get()); + // decrypt c1 + auto decrypted_m1 = fpPaillier->decrypt(ref(c1), (void*)keyPair.get()); + // check m1 + BOOST_CHECK(fabs(codec->toFloat50(decrypted_m1) - m1) <= epsilon); + + // encrypt m2 + bcos::bytes c2(FloatingPointPaillier::maxCipherBytesLen(_keyBits), 0); + OutputBuffer c2Buffer{c2.data(), c2.size()}; + fpPaillier->encryptFast(&c2Buffer, m2Fp, (void*)keyPair.get()); + // decrypt c2 + auto decrypted_m2 = fpPaillier->decrypt(ref(c2), (void*)keyPair.get()); + // check m2 + std::cout << std::fixed << std::setprecision(11); + std::cout << "#### decrypted_m2: " << codec->toFloat50(decrypted_m2) << std::endl; + std::cout << "#### m2: " << m2 << std::endl; + BOOST_CHECK(fabs(codec->toFloat50(decrypted_m2) - m2) <= epsilon); + std::cout << "===== encrypt/decrypt check done======" << std::endl; + + std::cout << "===== paillier add check ======" << std::endl; + bcos::bytes addResult(FloatingPointPaillier::maxCipherBytesLen(_keyBits), 0); + OutputBuffer addResultBuffer{addResult.data(), addResult.size()}; + auto pk = keyPair->pk(); + fpPaillier->add(&addResultBuffer, ref(c1), ref(c2), pk); + // decrypt and check + auto decryptAddResult = fpPaillier->decrypt(ref(addResult), (void*)keyPair.get()); + auto expectedAddResult = m1 + m2; + + std::cout << std::fixed << std::setprecision(15); + std::cout << "#### expectedAddResult: " << expectedAddResult << std::endl; + std::cout << "#### decryptAddResult: " << codec->toFloat50(decryptAddResult) << std::endl; + std::cout << "### fabs: " << fabs(codec->toFloat50(decryptAddResult) - expectedAddResult) + << std::endl; + BOOST_CHECK(fabs(codec->toFloat50(decryptAddResult) - expectedAddResult) <= epsilon); + std::cout << "===== paillier add check done======" << std::endl; + + std::cout << "===== paillier sub check ======" << std::endl; + bcos::bytes subResult(FloatingPointPaillier::maxCipherBytesLen(_keyBits), 0); + OutputBuffer subResultBuffer{subResult.data(), subResult.size()}; + fpPaillier->sub(&subResultBuffer, ref(c1), ref(c2), pk); + // decrypt and check + auto decryptSubResult = fpPaillier->decrypt(ref(subResult), (void*)keyPair.get()); + auto expectedSubResult = m1 - m2; + + std::cout << std::fixed << std::setprecision(15); + std::cout << "#### expectedSubResult: " << expectedSubResult << std::endl; + std::cout << "#### decryptSubResult: " << codec->toFloat50(decryptSubResult) << std::endl; + std::cout << "### fabs: " << fabs(codec->toFloat50(decryptSubResult) - expectedSubResult) + << std::endl; + BOOST_CHECK(fabs(codec->toFloat50(decryptSubResult) - expectedSubResult) <= epsilon); + std::cout << "===== paillier sub check done======" << std::endl; + + + std::cout << "===== paillier scalaMul check ======" << std::endl; + bcos::bytes mulResult(FloatingPointPaillier::maxCipherBytesLen(_keyBits), 0); + OutputBuffer mulResultBuffer{mulResult.data(), mulResult.size()}; + fpPaillier->scalaMul(&mulResultBuffer, vFp, ref(c1), pk); + // decrypt and check + auto decryptMulResult = fpPaillier->decrypt(ref(mulResult), (void*)keyPair.get()); + auto expectedMulResult = v * m1; + + std::cout << std::fixed << std::setprecision(15); + std::cout << "#### expectedMulResult: " << expectedMulResult << std::endl; + std::cout << "#### decryptMulResult: " << codec->toFloat50(decryptMulResult) << std::endl; + std::cout << "### fabs: " << fabs(codec->toFloat50(decryptMulResult) - expectedMulResult) + << std::endl; + BOOST_CHECK(fabs(codec->toFloat50(decryptMulResult) - expectedMulResult) <= epsilon); + std::cout << "===== paillier scalaMul check done======" << std::endl; + + // test the overflow case + std::cout << "====== test the overflow case ======" << std::endl; + FloatingPointNumber fpN; + fpN.value = ((PaillierPublicKey*)pk)->n; + fpN.exponent = 0; + bcos::bytes resultBytes(FloatingPointPaillier::maxCipherBytesLen(_keyBits)); + OutputBuffer result{resultBytes.data(), resultBytes.size()}; + BOOST_CHECK_THROW(fpPaillier->encrypt(&result, fpN, (void*)pk), SignedNumberCodecException); + std::cout << "====== test the overflow case done======" << std::endl; +} + +BOOST_AUTO_TEST_CASE(testFloatingPointPaillier) +{ + int keyBits = 2048; + std::string m1("2.323"); + std::string m2("4.5"); + std::string v("123.23"); + // set precison to 10 + double epsilon = 0.0000000001; + std::cout << "===== testFloatingPointPaillier: positive case =========" << std::endl; + testPaillierHomoProperty(keyBits, m1, m2, v, epsilon); + std::cout << "===== testFloatingPointPaillier: positive case done =========" << std::endl; + + // the negative case + std::cout << "===== testFloatingPointPaillier: negative case =========" << std::endl; + m1 = "-23.2344234"; + m2 = "4.234"; + v = "-2343.23434324324"; + testPaillierHomoProperty(keyBits, m1, m2, v, epsilon); + std::cout << "===== testFloatingPointPaillier: negative case done=========" << std::endl; +} +BOOST_AUTO_TEST_SUITE_END() +} // namespace ppc::test \ No newline at end of file diff --git a/cpp/wedpr-crypto/ppc-homo/tests/TestIhc.cpp b/cpp/wedpr-crypto/ppc-homo/tests/TestIhc.cpp new file mode 100644 index 00000000..c5c0109d --- /dev/null +++ b/cpp/wedpr-crypto/ppc-homo/tests/TestIhc.cpp @@ -0,0 +1,121 @@ +/* + * 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 applicabl 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 TestIhc.cpp + * @author: asherli + * @date 2023-11-27 + */ +#include "ppc-homo/ihc/IhcImpl.h" +#include +#include +#include + +using namespace ppc::crypto; +using namespace ppc::homo; +using namespace bcos; +using namespace bcos::test; +namespace ppc::test +{ +BOOST_FIXTURE_TEST_SUITE(ihcTest, TestPromptFixture) + +bcos::bytes testIhcEncryptionDecryption( + Ihc::Ptr const& _ihc, bcos::bytesConstRef const& key, BigNum const& m) +{ + std::cout << "#### ihc encrypt" << std::endl; + // encrypt + auto cipher = _ihc->encrypt(key, m.bn().get()); + std::cout << "#### ihc decrypt" << std::endl; + // decrypt + auto decodedM = _ihc->decrypt(key, bcos::ref(cipher)); + std::cout << "#### ihc decrypt success" << std::endl; + BOOST_CHECK(decodedM.cmp(m.bn().get()) == 0); + return cipher; +} +void testIhcImpl(BigNum const& m1, BigNum const& m2, BigNum const& m3, Ihc::IhcMode _mode, + unsigned int _iterRound) +{ + auto ihc = std::make_shared((int)_mode, _iterRound); + auto key = ihc->generateKey(); + // encryption + auto c1 = testIhcEncryptionDecryption(ihc, bcos::ref(key), m1); + auto c2 = testIhcEncryptionDecryption(ihc, bcos::ref(key), m2); + auto c3 = testIhcEncryptionDecryption(ihc, bcos::ref(key), m3); + // add test + std::cout << "#### ihc add test" << std::endl; + auto addResult = ihc->add(bcos::ref(c1), bcos::ref(c2)); + std::cout << "##### addResult: " << bcos::toHex(addResult) << ", size: " << addResult.size() + << std::endl; + auto addM = ihc->decrypt(bcos::ref(key), bcos::ref(addResult)); + auto expectedAddM = m1.add(m2.bn().get()); + BOOST_CHECK(addM.cmp(expectedAddM.bn().get()) == 0); + std::cout << "#### ihc add test success!" << std::endl; + // sub test + std::cout << "#### ihc sub test" << std::endl; + auto subResult = ihc->sub(bcos::ref(c1), bcos::ref(c2)); + auto subM = ihc->decrypt(bcos::ref(key), bcos::ref(subResult)); + auto expectedSubM = m1.sub(m2.bn().get()); + std::cout << "##### subM: " << std::endl; + BN_print_fp(stdout, subM.bn().get()); + std::cout << "#### expectedSubM: " << std::endl; + BN_print_fp(stdout, expectedSubM.bn().get()); + BOOST_CHECK(subM.cmp(expectedSubM.bn().get()) == 0); + std::cout << "#### ihc sub test success" << std::endl; + + // scalaMul test + std::cout << "#### ihc sub scalaMul" << std::endl; + auto mulCipher = ihc->scalaMul(m3.bn().get(), bcos::ref(c2)); + auto mulM = ihc->decrypt(bcos::ref(key), bcos::ref(mulCipher)); + auto ctx = createBNContext(); + BigNum expectedMulResult; + m3.mul(expectedMulResult.bn().get(), m2.bn().get(), ctx.get()); + BOOST_CHECK(mulM.cmp(expectedMulResult.bn().get()) == 0); + std::cout << "#### ihc sub scalaMul success" << std::endl; +} + +BOOST_AUTO_TEST_CASE(testIhc) +{ + int iterRound = 16; + + // positive case + BigNum m1(123213231); + BigNum m2(234343430); + BigNum m3(123456); + std::cout << "==== testIhc positive =====" << std::endl; + testIhcImpl(m1, m2, m3, Ihc::IhcMode::IHC_128, 16); + testIhcImpl(m1, m2, m3, Ihc::IhcMode::IHC_256, 16); + std::cout << "==== testIhc positive finished=====" << std::endl; + + // zero case + std::cout << "==== testIhc zero case =====" << std::endl; + m2 = BigNum((int64_t)0); + testIhcImpl(m1, m2, m3, Ihc::IhcMode::IHC_128, 16); + testIhcImpl(m1, m2, m3, Ihc::IhcMode::IHC_256, 16); + m1 = BigNum((int64_t)0); + m3 = BigNum((int64_t)1); + testIhcImpl(m1, m2, m3, Ihc::IhcMode::IHC_128, 16); + testIhcImpl(m1, m2, m3, Ihc::IhcMode::IHC_256, 16); + std::cout << "==== testIhc zero case finished =====" << std::endl; + + // negative case + std::cout << "==== testIhc negative case =====" << std::endl; + m1 = BigNum(123213231 + bcos::utcSteadyTime()); + srand(bcos::utcSteadyTime()); + m2 = BigNum(-(123213231 + bcos::utcSteadyTime() + rand())); + m3 = BigNum(122); + testIhcImpl(m1, m2, m3, Ihc::IhcMode::IHC_256, 16); + std::cout << "==== testIhc negative case finished =====" << std::endl; +} +BOOST_AUTO_TEST_SUITE_END() +} // namespace ppc::test \ No newline at end of file diff --git a/cpp/wedpr-crypto/ppc-homo/tests/TestIhcFloating.cpp b/cpp/wedpr-crypto/ppc-homo/tests/TestIhcFloating.cpp new file mode 100644 index 00000000..216cf7b5 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-homo/tests/TestIhcFloating.cpp @@ -0,0 +1,127 @@ +/* + * 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 applicabl 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 TestIhcFloating.cpp + * @author: asherli + * @date 2023-11-27 + */ +#include "ppc-framework/libwrapper/FloatingPointNumber.h" +#include "ppc-homo/codec/FloatingPointCodec.h" +#include "ppc-homo/ihc/FloatingPointIhc.h" +#include +#include +#include + +using namespace ppc::crypto; +using namespace ppc::homo; +using namespace bcos; +using namespace bcos::test; +namespace ppc::test +{ +BOOST_FIXTURE_TEST_SUITE(ihcFloatingTest, TestPromptFixture) + +bcos::bytes testEncryptDecrypt(FloatingPointIhc::Ptr const& fpIhc, + FloatingPointCodec::Ptr const& codec, bcos::bytes const& _key, std::string const& s) +{ + float50 m(s); + auto ffpNumber = codec->toFloatingPoint(s); + auto cipher = fpIhc->encrypt(bcos::ref(_key), ffpNumber); + // decrypt + auto decryptffp = fpIhc->decrypt(bcos::ref(_key), bcos::ref(cipher)); + auto decryptValue = codec->toFloat50(decryptffp); + // check + std::cout << "#### m: " << m.str(32) << std::endl; + std::cout << "#### decryptValue: " << decryptValue.str(32) << std::endl; + BOOST_CHECK(m == decryptValue); + return cipher; +} + +void testIhcFloatingImpl( + std::string s1, std::string s2, std::string s3, Ihc::IhcMode _mode, int iterRound) +{ + auto ihc = std::make_shared((int)_mode, iterRound); + auto key = ihc->generateKey(); + + float50 m1(s1); + float50 m2(s2); + float50 m3(s3); + auto fpIhc = std::make_shared(ihc); + auto codec = std::make_shared(); + // c1 + auto c1 = testEncryptDecrypt(fpIhc, codec, key, s1); + // c2 + auto c2 = testEncryptDecrypt(fpIhc, codec, key, s2); + // c3 + auto c3 = testEncryptDecrypt(fpIhc, codec, key, s3); + // add + std::cout << "### testIhcFloatingImpl: add case" << std::endl; + auto addResult = fpIhc->add(bcos::ref(c1), bcos::ref(c2)); + auto addFfpResult = fpIhc->decrypt(bcos::ref(key), bcos::ref(addResult)); + auto expectedAddResult = m1 + m2; + BOOST_CHECK(codec->toFloat50(addFfpResult) == expectedAddResult); + std::cout << "### testIhcFloatingImpl: add case end" << std::endl; + // sub case + std::cout << "### testIhcFloatingImpl: sub case" << std::endl; + auto subResult = fpIhc->sub(bcos::ref(c1), bcos::ref(c2)); + auto subFfpResult = fpIhc->decrypt(bcos::ref(key), bcos::ref(subResult)); + auto expectedSubResult = m1 - m2; + BOOST_CHECK(codec->toFloat50(subFfpResult) == expectedSubResult); + std::cout << "### testIhcFloatingImpl: sub case end" << std::endl; + // scalaMul case + std::cout << "### testIhcFloatingImpl: scalaMul case" << std::endl; + auto v = codec->toFloatingPoint(s3); + auto mulResult = fpIhc->scalaMul(v, bcos::ref(c1)); + auto mulFfpResult = fpIhc->decrypt(bcos::ref(key), bcos::ref(mulResult)); + auto expectedMulResult = m1 * m3; + std::cout << "#### expectedMulResult: " << expectedMulResult << std::endl; + std::cout << "#### mulFfpResult: " << codec->toFloat50(mulFfpResult) << std::endl; + BOOST_CHECK(codec->toFloat50(mulFfpResult) == expectedMulResult); + std::cout << "### testIhcFloatingImpl: mul case end" << std::endl; +} + + +BOOST_AUTO_TEST_CASE(testIhcFloating) +{ + int iterRound = 16; + + // positive case + std::cout << "==== testIhcFloatingImpl positive =====" << std::endl; + std::string m1("234324.345435345345"); + std::string m2("534252.45670234"); + std::string m3("234.456452"); + testIhcFloatingImpl(m1, m2, m3, Ihc::IhcMode::IHC_128, iterRound); + testIhcFloatingImpl(m1, m2, m3, Ihc::IhcMode::IHC_256, iterRound); + std::cout << "==== testIhcFloatingImpl positive finished=====" << std::endl; + + // zero case + std::cout << "==== testIhcFloatingImpl zero case =====" << std::endl; + m1 = "0.0"; + m2 = "0.1"; + m3 = "0.000"; + testIhcFloatingImpl(m1, m2, m3, Ihc::IhcMode::IHC_128, iterRound); + testIhcFloatingImpl(m1, m2, m3, Ihc::IhcMode::IHC_256, iterRound); + std::cout << "==== testIhc zero case finished =====" << std::endl; + + // negative case + std::cout << "==== testIhcFloatingImpl negative case =====" << std::endl; + m1 = "-234234.00234324"; + m2 = "-234.543645"; + m3 = "-23432435234"; + testIhcFloatingImpl(m1, m2, m3, Ihc::IhcMode::IHC_128, iterRound); + testIhcFloatingImpl(m1, m2, m3, Ihc::IhcMode::IHC_256, iterRound); + std::cout << "==== testIhcFloatingImpl negative case finished =====" << std::endl; +} +BOOST_AUTO_TEST_SUITE_END() +} // namespace ppc::test \ No newline at end of file diff --git a/cpp/wedpr-crypto/ppc-homo/tests/TestPaillier.cpp b/cpp/wedpr-crypto/ppc-homo/tests/TestPaillier.cpp new file mode 100644 index 00000000..a7b04bbb --- /dev/null +++ b/cpp/wedpr-crypto/ppc-homo/tests/TestPaillier.cpp @@ -0,0 +1,267 @@ +/* + * 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 applicabl 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 TestPaillier.cpp + * @author: yujiechen + * @date 2023-08-08 + */ +#include "ppc-homo/codec/SignedNumberCodec.h" +#include "ppc-homo/paillier/OpenSSLPaillier.h" +#include +#include +#include + +using namespace ppc::crypto; +using namespace ppc::homo; +using namespace bcos; +using namespace bcos::test; + +namespace ppc::test +{ +BOOST_FIXTURE_TEST_SUITE(paillierTest, TestPromptFixture) + +void testPaillierEncryptDecrypt(bcos::bytes& _cipherData, OpenSSLPaillier::Ptr const& _impl, + SignedNumberCodec::Ptr const& _codec, KeyPair::UniquePtr const& _keyPair, int64_t const _m, + uint64_t const _perfCount) +{ + (void)_codec; + ////// test encrypt and decrypt, return the cipher data + // encrypt + BigNum m(_m); + + auto startT = bcos::utcSteadyTimeUs(); + for (uint64_t i = 0; i < _perfCount; i++) + { + _cipherData = _impl->encrypt_with_crt(m.bn().get(), (void*)_keyPair.get()); + } + std::cout << "#### paillier encrypt perf:" << ((bcos::utcSteadyTimeUs() - startT) / _perfCount) + << " us" << std::endl; + + /// case not enough resultBuffer; + bcos::bytes resultBytes(2); + OutputBuffer resultBuffer{resultBytes.data(), resultBytes.size()}; + BOOST_CHECK_THROW( + _impl->encrypt_with_crt(&resultBuffer, nullptr, m.bn().get(), (void*)_keyPair.get()), + std::exception); + + // decrypt + startT = utcSteadyTimeUs(); + BigNum decryptedV; + for (uint64_t i = 0; i < _perfCount; i++) + { + decryptedV = _impl->decrypt(bcos::ref(_cipherData), (void*)_keyPair.get()); + } + std::cout << "#### paillier decrypt perf:" << ((bcos::utcSteadyTimeUs() - startT) / _perfCount) + << " us" << std::endl; + std::cout << std::endl; + + BN_print_fp(stdout, decryptedV.bn().get()); + BigNum mBN(_m); + BOOST_CHECK(mBN.cmp(decryptedV.bn().get()) == 0); +} + +void testPaillierHomoProperty(OpenSSLPaillier::Ptr const& _impl, + SignedNumberCodec::Ptr const& _codec, KeyPair::UniquePtr const& _keyPair, int64_t _value, + bcos::bytes& _c1, bcos::bytes& _c2, int64_t const _m1, int64_t _m2, uint64_t _perfCount) +{ + std::cout << "### c1 size:" << _c1.size() << std::endl; + std::cout << "### c2 size:" << _c2.size() << std::endl; + BigNum m1(_m1); + BigNum m2(_m2); + // ==== test add ===== + // _c1 + _c2 + bcos::bytes sumCipher; + auto startT = bcos::utcSteadyTimeUs(); + for (uint64_t i = 0; i < _perfCount; i++) + { + sumCipher = _impl->add(bcos::ref(_c1), bcos::ref(_c2), _keyPair->pk()); + } + std::cout << "#### paillier add perf:" << ((bcos::utcSteadyTimeUs() - startT) / _perfCount) + << " us" << std::endl; + + /// case not enough resultBuffer; + bcos::bytes resultBytes(10); + OutputBuffer resultBuffer{resultBytes.data(), resultBytes.size()}; + BOOST_CHECK_THROW( + _impl->add(&resultBuffer, bcos::ref(_c1), bcos::ref(_c2), _keyPair->pk()), std::exception); + + // decrypt and check the result + auto result = _impl->decrypt(bcos::ref(sumCipher), (void*)_keyPair.get()); + auto expectedBN = m1.add(m2.bn().get()); + BOOST_CHECK(expectedBN.cmp(result.bn().get()) == 0); + + // ==== test sub ===== + // _c1 - _c2 + startT = bcos::utcSteadyTimeUs(); + bcos::bytes subCipher; + for (uint64_t i = 0; i < _perfCount; i++) + { + subCipher = _impl->sub(bcos::ref(_c1), bcos::ref(_c2), _keyPair->pk()); + } + std::cout << "#### paillier sub perf:" << ((bcos::utcSteadyTimeUs() - startT) / _perfCount) + << " us" << std::endl; + /// case not enough resultBuffer; + BOOST_CHECK_THROW( + _impl->sub(&resultBuffer, bcos::ref(_c1), bcos::ref(_c2), _keyPair->pk()), std::exception); + + result = _impl->decrypt(bcos::ref(subCipher), (void*)_keyPair.get()); + auto expectedSubBN = m1.sub(m2.bn().get()); + BOOST_CHECK(expectedSubBN.cmp(result.bn().get()) == 0); + + // ==== test mul ===== + // _value * _c1 + bcos::bytes mulCipher; + startT = bcos::utcSteadyTimeUs(); + ppc::crypto::BigNum v(_value); + for (uint64_t i = 0; i < _perfCount; i++) + { + mulCipher = _impl->scalaMul(v.bn().get(), bcos::ref(_c1), _keyPair->pk()); + } + std::cout << "#### paillier scalMul perf:" << ((bcos::utcSteadyTimeUs() - startT) / _perfCount) + << " us" << std::endl; + /// case not enough resultBuffer; + BOOST_CHECK_THROW(_impl->scalaMul(&resultBuffer, v.bn().get(), bcos::ref(_c1), _keyPair->pk()), + std::exception); + + // decrypt and check the result + auto resultBn = _codec->decode(_impl->decrypt(bcos::ref(mulCipher), (void*)_keyPair.get())); + BigNum valueBn(_value); + BigNum valueM1(_m1); + BigNum expectedBn; + auto ctx = createBNContext(); + valueBn.mul(expectedBn.bn().get(), valueM1.bn().get(), ctx.get()); + std::cout << "## scalaMul resultBn: "; + BN_print_fp(stdout, resultBn.bn().get()); + std::cout << std::endl; + std::cout << "## scalaMul expectedResult: "; + BN_print_fp(stdout, expectedBn.bn().get()); + std::cout << std::endl; + BOOST_CHECK(expectedBn.cmp(resultBn.bn().get()) == 0); +} + +void checkKeyPair(KeyPair::UniquePtr&& _keyPair1, OpenSSLPaillierKeyPair::UniquePtr&& _keyPair2) +{ + auto pk1 = (PaillierPublicKey*)_keyPair1->pk(); + auto pk2 = (PaillierPublicKey*)_keyPair2->pk(); + BOOST_CHECK(pk1->keyBits == pk2->keyBits); + BOOST_CHECK(pk1->n.cmp(pk2->n.bn().get()) == 0); + BOOST_CHECK(pk1->nSqrt.cmp(pk2->nSqrt.bn().get()) == 0); + BOOST_CHECK(pk1->h.cmp(pk2->h.bn().get()) == 0); + + BOOST_CHECK(pk1->h_s.cmp(pk2->h_s.bn().get()) == 0); + + auto sk1 = (PaillierPrivateKey*)_keyPair1->sk(); + auto sk2 = (PaillierPrivateKey*)_keyPair2->sk(); + BOOST_CHECK(sk1->keyBits == sk2->keyBits); + BOOST_CHECK(sk1->lambda.cmp(sk2->lambda.bn().get()) == 0); + BOOST_CHECK(sk1->p.cmp(sk2->p.bn().get()) == 0); + BOOST_CHECK(sk1->q.cmp(sk2->q.bn().get()) == 0); + BOOST_CHECK(sk1->pSqrt.cmp(sk2->pSqrt.bn().get()) == 0); + BOOST_CHECK(sk1->qSqrt.cmp(sk2->qSqrt.bn().get()) == 0); + BOOST_CHECK(sk1->qSqrtInverse.cmp(sk2->qSqrtInverse.bn().get()) == 0); + BOOST_CHECK(sk1->pOrderSqrt.cmp(sk2->pOrderSqrt.bn().get()) == 0); + BOOST_CHECK(sk1->qOrderSqrt.cmp(sk2->qOrderSqrt.bn().get()) == 0); +} + +void testOverflow(SignedNumberCodec::Ptr codec, OpenSSLPaillier::Ptr paillierImpl, + ppc::crypto::KeyPair::UniquePtr&& keyPair) +{ + // overflow case + auto v = codec->maxPositive(); + BigNum tmp(1); + tmp.add(tmp.bn().get(), v.bn().get()); + BOOST_CHECK_THROW(paillierImpl->encrypt_with_crt(tmp.bn().get(), (void*)keyPair.get()), + SignedNumberCodecException); + + // add overflow + BigNum two(2); + auto m1 = tmp.sub(two.bn().get()); + auto c1 = paillierImpl->encrypt_with_crt(m1.bn().get(), (void*)keyPair.get()); + BigNum m2(1000); + auto c2 = paillierImpl->encrypt_with_crt(m2.bn().get(), (void*)keyPair.get()); + auto pk = (PaillierPublicKey*)(keyPair->pk()); + auto cipher = paillierImpl->add(bcos::ref(c1), bcos::ref(c2), (void*)pk); + // decrypt failed for overflow + BOOST_CHECK_THROW( + paillierImpl->decrypt(bcos::ref(cipher), (void*)keyPair.get()), SignedNumberCodecException); +} + +BOOST_AUTO_TEST_CASE(testPaillier) +{ + auto paillierImpl = std::make_shared(); + // generate keyPair with keyLength bits + unsigned keyLength = 3072; + auto startT = bcos::utcSteadyTime(); + auto keyPair = paillierImpl->generateKeyPair(keyLength); + std::cout << "### generate keypair timecost:" << (bcos::utcSteadyTime() - startT) << " ms" + << std::endl; + auto pk = (PaillierPublicKey*)(keyPair->pk()); + + auto codec = std::make_shared(pk->n); + + /// === normal test case + // check encrypt/decrypt + int64_t perfCount = 2; + bcos::bytes cipherData1; + srand(bcos::utcSteadyTime()); + int64_t m1 = 12323423434 + rand(); + testPaillierEncryptDecrypt(cipherData1, paillierImpl, codec, keyPair, m1, perfCount); + + bcos::bytes cipherData2; + int64_t m2 = 2342342344 + rand(); + testPaillierEncryptDecrypt(cipherData2, paillierImpl, codec, keyPair, m2, perfCount); + + // check homo-property + int value = rand(); + testPaillierHomoProperty( + paillierImpl, codec, keyPair, value, cipherData1, cipherData2, m1, m2, perfCount); + + ////// negative case + m1 = -1234324 - rand(); + testPaillierEncryptDecrypt(cipherData1, paillierImpl, codec, keyPair, m1, 1); + m2 = 23434 + rand(); + testPaillierEncryptDecrypt(cipherData2, paillierImpl, codec, keyPair, m2, 1); + testPaillierHomoProperty( + paillierImpl, codec, keyPair, value, cipherData1, cipherData2, m1, m2, perfCount); + + value = -34534 - rand(); + testPaillierHomoProperty( + paillierImpl, codec, keyPair, value, cipherData1, cipherData2, m1, m2, perfCount); + + testOverflow(codec, paillierImpl, std::move(keyPair)); +} + +// test paillier keyPair +BOOST_AUTO_TEST_CASE(testPaillierKeyPair) +{ + int keyLength = 2048; + auto paillierImpl = std::make_shared(); + auto keyPair = paillierImpl->generateKeyPair(keyLength); + + auto skData = keyPair->serializeSK(); + auto pkData = keyPair->serializePK(); + + // create new keyPair according to skData and pkData + auto keyPair2 = std::make_unique( + skData.data(), skData.size(), pkData.data(), pkData.size()); + // check serialize again + auto skData2 = keyPair2->serializeSK(); + auto pkData2 = keyPair2->serializePK(); + BOOST_CHECK(skData == skData2); + BOOST_CHECK(pkData == pkData2); + checkKeyPair(std::move(keyPair), std::move(keyPair2)); +} +BOOST_AUTO_TEST_SUITE_END() +} // namespace ppc::test \ No newline at end of file diff --git a/cpp/wedpr-crypto/ppc-homo/tests/main.cpp b/cpp/wedpr-crypto/ppc-homo/tests/main.cpp new file mode 100644 index 00000000..2c06f9b5 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-homo/tests/main.cpp @@ -0,0 +1,2 @@ +#define BOOST_TEST_MAIN +#include \ No newline at end of file diff --git a/cpp/wedpr-crypto/ppc-udf/CMakeLists.txt b/cpp/wedpr-crypto/ppc-udf/CMakeLists.txt new file mode 100644 index 00000000..71e339b1 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-udf/CMakeLists.txt @@ -0,0 +1,33 @@ +# export windows dll symbol +if(WIN32) + message(STATUS "Compile on Windows") + set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS "ON") +endif() + +file(GLOB_RECURSE SRCS mysql/*.cpp mysql/*.c) + +if(EXISTS ${MYSQL_INCLUDE_PATH}) + include_directories(${MYSQL_INCLUDE_PATH}) +else() + find_package(MySQL REQUIRED) + if(MYSQL_FOUND) + include_directories(${MYSQL_INCLUDE_DIRS}) + else() + message(FATAL "MySQL not found! Must install the mysql or specify the include path using -DMYSQL_INCLUDE_PATH") + endif() +endif() + +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC") +# generate the shared lib +add_definitions("-DHAVE_DLOPEN") +add_library(${PPC_UDF_TARGET} MODULE ${SRCS}) +target_link_libraries(${PPC_UDF_TARGET} PUBLIC ${PPC_CRYPTO_C_SDK_STATIC_TARGET}) + +add_library(${PPC_UDF_STATIC_TARGET} ${SRCS}) +target_link_libraries(${PPC_UDF_STATIC_TARGET} PUBLIC ${PPC_CRYPTO_C_SDK_STATIC_TARGET}) + +if (TESTS) + enable_testing() + set(CTEST_OUTPUT_ON_FAILURE TRUE) + add_subdirectory(tests) +endif() diff --git a/cpp/wedpr-crypto/ppc-udf/hive/build.gradle b/cpp/wedpr-crypto/ppc-udf/hive/build.gradle new file mode 100644 index 00000000..b866064c --- /dev/null +++ b/cpp/wedpr-crypto/ppc-udf/hive/build.gradle @@ -0,0 +1,159 @@ +plugins { + id 'java' + id 'idea' + id 'org.ajoberstar.grgit' version '4.1.1' + id 'java-library' + id 'maven-publish' + id "de.undercouch.download" version "4.1.2" + id 'com.github.sherter.google-java-format' version '0.9' +} + +println("Notice: current gradle version is " + gradle.gradleVersion) +sourceCompatibility = 1.8 +targetCompatibility = 1.8 + +[compileJava, compileTestJava, javadoc]*.options*.encoding = 'UTF-8' + +ext { + if (!project.hasProperty("ossrhUsername")) { + ossrhUsername = "xxx" + } + + if (!project.hasProperty("ossrhPassword")) { + ossrhPassword = "xxx" + } + toml4jVersion = "0.7.2" + hiveExecVersion="2.3.9" +} + +repositories { + maven { url "https://maven.aliyun.com/nexus/content/groups/public/" } + maven { url "https://oss.sonatype.org/service/local/staging/deploy/maven2"} + maven { url "https://oss.sonatype.org/content/repositories/snapshots" } + maven {url "https://plugins.gradle.org/m2/"} + mavenCentral() + mavenLocal() +} +googleJavaFormat { + toolVersion = '1.7' + options style: 'AOSP' + source = sourceSets*.allJava + include '**/*.java' + exclude '**/*Test.java' + exclude '**/Test*.java' + exclude '**/Mock*.java' +} + +sourceSets { + main { + java { + srcDir 'src/main/java' + } + resources { + srcDir 'src/main/resources' + } + } +} +dependencies { + api("org.apache.hive:hive-exec:${hiveExecVersion}") + api("com.moandjiezana.toml:toml4j:${toml4jVersion}") + implementation fileTree(dir:'libs',include:['*.jar']) + testImplementation ('junit:junit:4.13.2') +} + +archivesBaseName = 'ppc-hive-udf' +group = 'com.webank.wedpr' +version = '1.0.0' + +test { + dependsOn cleanTest + testLogging.showStandardStreams = true +} + +jar { + exclude '**/*.xml' + exclude '**/*.properties' + doLast { + copy { + from destinationDirectory + into 'dist/app' + } + + copy { + from configurations.runtimeClasspath + into 'dist/lib' + } + } +} + +javadoc { + options.addStringOption('Xdoclint:none', '-quiet') + options.addStringOption('encoding', 'UTF-8') + options.addStringOption('charSet', 'UTF-8') +} + +task sourcesJar(type: Jar) { + from sourceSets.main.allJava + archiveClassifier = 'sources' + duplicatesStrategy 'exclude' +} +tasks.withType(Copy).all { + duplicatesStrategy 'exclude' +} + + +task javadocJar(type: Jar) { + from javadoc + archiveClassifier = 'javadoc' +} +publishing { + publications { + mavenJava(MavenPublication) { + artifactId project.name + groupId project.group + version project.version + + from components.java + artifact sourcesJar + artifact javadocJar + + pom { + name = 'wedpr' + description = 'wedpr ppc-hive-udf' + url = 'http://www.fisco-bcos.org' + + licenses { + license { + name = 'The Apache License, Version 2.0' + url = 'http://www.apache.org/licenses/LICENSE-2.0.txt' + } + } + scm { + connection = 'http://github.com/WeBankBlockchain/wedpr-components.git' + url = 'http://github.com/WeBankBlockchain/wedpr-components.git' + } + + developers { + developer { + id = 'zhangsan' + name = 'zhangsan' + email = 'zhangsan@example.com' + } + } + } + } + } + repositories { + maven { + def releasesRepoURL = "https://oss.sonatype.org/service/local/staging/deploy/maven2" + def snapshotsRepoURL = "https://oss.sonatype.org/content/repositories/snapshots" + allowInsecureProtocol = true + url = !version.endsWith("SNAPSHOT") ? releasesRepoURL : snapshotsRepoURL + + credentials { + username 'deployment' + password 'deployment123' + } + } + } +} diff --git a/cpp/wedpr-crypto/ppc-udf/hive/gradle/wrapper/gradle-wrapper.jar b/cpp/wedpr-crypto/ppc-udf/hive/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 00000000..e708b1c0 Binary files /dev/null and b/cpp/wedpr-crypto/ppc-udf/hive/gradle/wrapper/gradle-wrapper.jar differ diff --git a/cpp/wedpr-crypto/ppc-udf/hive/gradle/wrapper/gradle-wrapper.properties b/cpp/wedpr-crypto/ppc-udf/hive/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 00000000..be792139 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-udf/hive/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +#distributionUrl=https\://services.gradle.org/distributions/gradle-7.3-bin.zip +distributionUrl=https\://mirrors.cloud.tencent.com/gradle/gradle-7.3-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/cpp/wedpr-crypto/ppc-udf/hive/gradlew b/cpp/wedpr-crypto/ppc-udf/hive/gradlew new file mode 100644 index 00000000..4f906e0c --- /dev/null +++ b/cpp/wedpr-crypto/ppc-udf/hive/gradlew @@ -0,0 +1,185 @@ +#!/usr/bin/env sh + +# +# Copyright 2015 the original author or authors. +# +# 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 +# +# https://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. +# + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$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 "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# 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 + ;; + 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" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin or MSYS, switch paths to Windows format before running java +if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=`expr $i + 1` + done + case $i in + 0) set -- ;; + 1) set -- "$args0" ;; + 2) set -- "$args0" "$args1" ;; + 3) set -- "$args0" "$args1" "$args2" ;; + 4) set -- "$args0" "$args1" "$args2" "$args3" ;; + 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=`save "$@"` + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +exec "$JAVACMD" "$@" diff --git a/cpp/wedpr-crypto/ppc-udf/hive/gradlew.bat b/cpp/wedpr-crypto/ppc-udf/hive/gradlew.bat new file mode 100644 index 00000000..ac1b06f9 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-udf/hive/gradlew.bat @@ -0,0 +1,89 @@ +@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%" == "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%"=="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! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/cpp/wedpr-crypto/ppc-udf/hive/settings.gradle b/cpp/wedpr-crypto/ppc-udf/hive/settings.gradle new file mode 100644 index 00000000..f8eea762 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-udf/hive/settings.gradle @@ -0,0 +1,2 @@ +rootProject.name = 'ppc-hive-udf' + diff --git a/cpp/wedpr-crypto/ppc-udf/hive/src/main/java/com/webank/wedpr/hive/udf/config/Config.java b/cpp/wedpr-crypto/ppc-udf/hive/src/main/java/com/webank/wedpr/hive/udf/config/Config.java new file mode 100644 index 00000000..52d6cdae --- /dev/null +++ b/cpp/wedpr-crypto/ppc-udf/hive/src/main/java/com/webank/wedpr/hive/udf/config/Config.java @@ -0,0 +1,55 @@ +/** + * Copyright 2023 [wedpr] + * + *

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. + */ +package com.webank.wedpr.hive.udf.config; + +import com.webank.wedpr.hive.udf.config.model.ConfigProperty; +import com.webank.wedpr.hive.udf.config.model.KeyConfig; +import java.util.Objects; +import org.apache.log4j.Logger; + +public class Config { + private static final Logger logger = Logger.getLogger(Config.class.getName()); + + private KeyConfig keyConfig; + + public Config(ConfigProperty configProperty) { + this.keyConfig = new KeyConfig(configProperty); + } + + public KeyConfig getKeyConfig() { + return keyConfig; + } + + public void setKeyConfig(KeyConfig keyConfig) { + this.keyConfig = keyConfig; + } + + @Override + public String toString() { + return "Config{" + "keyConfig=" + keyConfig + '}'; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Config that = (Config) o; + return Objects.equals(keyConfig, that.keyConfig); + } + + @Override + public int hashCode() { + return Objects.hash(keyConfig); + } +} diff --git a/cpp/wedpr-crypto/ppc-udf/hive/src/main/java/com/webank/wedpr/hive/udf/config/ConfigLoader.java b/cpp/wedpr-crypto/ppc-udf/hive/src/main/java/com/webank/wedpr/hive/udf/config/ConfigLoader.java new file mode 100644 index 00000000..d212e5c2 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-udf/hive/src/main/java/com/webank/wedpr/hive/udf/config/ConfigLoader.java @@ -0,0 +1,46 @@ +/** + * Copyright 2023 [wedpr] + * + *

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. + */ +package com.webank.wedpr.hive.udf.config; + +import com.moandjiezana.toml.Toml; +import com.webank.wedpr.hive.udf.config.model.ConfigProperty; +import com.webank.wedpr.hive.udf.exceptions.ConfigException; +import java.io.InputStream; +import org.apache.log4j.Logger; + +public class ConfigLoader { + private static final Logger logger = Logger.getLogger(ConfigLoader.class.getName()); + private static final String DEFAULT_CONFIG_FILE = "config.toml"; + public static Config config; + + static { + InputStream configStream = + ConfigLoader.class.getClassLoader().getResourceAsStream(DEFAULT_CONFIG_FILE); + if (configStream == null) { + throw new ConfigException( + "The config file " + DEFAULT_CONFIG_FILE + " doesn't exists!"); + } + config = load(configStream); + } + + private static Config load(InputStream configStream) throws ConfigException { + try { + ConfigProperty property = new Toml().read(configStream).to(ConfigProperty.class); + return new Config(property); + } catch (Exception e) { + logger.error("load config error, e: " + e.getMessage()); + throw new ConfigException("load config error!", e); + } + } +} diff --git a/cpp/wedpr-crypto/ppc-udf/hive/src/main/java/com/webank/wedpr/hive/udf/config/model/ConfigProperty.java b/cpp/wedpr-crypto/ppc-udf/hive/src/main/java/com/webank/wedpr/hive/udf/config/model/ConfigProperty.java new file mode 100644 index 00000000..8345abcf --- /dev/null +++ b/cpp/wedpr-crypto/ppc-udf/hive/src/main/java/com/webank/wedpr/hive/udf/config/model/ConfigProperty.java @@ -0,0 +1,59 @@ +/** + * Copyright 2023 [wedpr] + * + *

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. + */ +package com.webank.wedpr.hive.udf.config.model; + +import java.util.Map; +import java.util.Objects; +import org.apache.log4j.Logger; +import org.codehaus.jackson.annotate.JsonIgnoreProperties; + +@JsonIgnoreProperties(ignoreUnknown = true) +public class ConfigProperty { + private static final Logger logger = Logger.getLogger(ConfigProperty.class.getName()); + + private Map keys; + + public Map getKeys() { + return keys; + } + + public void setKeys(Map keys) { + this.keys = keys; + } + + public static String getValue(Map config, String key, String defaultValue) { + if (config == null || config.get(key) == null) { + return defaultValue; + } + return (String) config.get(key); + } + + @Override + public String toString() { + return "ConfigProperty{" + "keys=" + keys + '}'; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + ConfigProperty that = (ConfigProperty) o; + return Objects.equals(keys, that.keys); + } + + @Override + public int hashCode() { + return Objects.hash(keys); + } +} diff --git a/cpp/wedpr-crypto/ppc-udf/hive/src/main/java/com/webank/wedpr/hive/udf/config/model/KeyConfig.java b/cpp/wedpr-crypto/ppc-udf/hive/src/main/java/com/webank/wedpr/hive/udf/config/model/KeyConfig.java new file mode 100644 index 00000000..550fb158 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-udf/hive/src/main/java/com/webank/wedpr/hive/udf/config/model/KeyConfig.java @@ -0,0 +1,130 @@ +/** + * Copyright 2023 [wedpr] + * + *

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. + */ +package com.webank.wedpr.hive.udf.config.model; + +import com.webank.wedpr.hive.udf.exceptions.ConfigException; +import com.webank.wedpr.sdk.jni.homo.NativeFloatingIhc; +import java.util.Map; +import org.apache.log4j.Logger; + +public class KeyConfig { + private static final Logger logger = Logger.getLogger(KeyConfig.class.getName()); + + // AES key + private static final String AES_PRIVATE_KEY_PROPERTY = "aes_sk"; + private String aesPrivateKey; + // AES IV + private static final String AES_IV_PROPERTY = "aes_iv"; + private String aesIv; + // ore key + private static final String ORE_PRIVATE_KEY_PROPERTY = "ore_sk"; + private String orePrivateKey; + + // ihc key + private static final String IHC_PRIVATE_KEY_PROPERTY = "ihc_sk"; + private String ihcPrivateKey; + + // paillier key + private static final String PAILLIER_PRIVATE_KEY_PROPERTY = "paillier_sk"; + private static final String PAILLIER_PUBLIC_KEY_PROPERTY = "paillier_pk"; + private String paillierSk; + private String paillierPk; + + private final int ihcMode = NativeFloatingIhc.mode.IHC_128.ordinal(); + + public KeyConfig(ConfigProperty configProperty) throws ConfigException { + Map keyConfig = configProperty.getKeys(); + /// load the aes private key + aesPrivateKey = ConfigProperty.getValue(keyConfig, AES_PRIVATE_KEY_PROPERTY, null); + if (aesPrivateKey == null) { + throw new ConfigException("Must set the aes private key!"); + } + /// load the aesIv + aesIv = ConfigProperty.getValue(keyConfig, AES_IV_PROPERTY, null); + if (aesIv == null) { + throw new ConfigException("Must set the aes iv!"); + } + /// load the orePrivateKey + orePrivateKey = ConfigProperty.getValue(keyConfig, ORE_PRIVATE_KEY_PROPERTY, null); + if (orePrivateKey == null) { + throw new ConfigException("Must set the ore private key!"); + } + /// load the ihcPrivateKey + ihcPrivateKey = ConfigProperty.getValue(keyConfig, IHC_PRIVATE_KEY_PROPERTY, null); + if (ihcPrivateKey == null) { + throw new ConfigException("Must set the ihc private key"); + } + /// load the paillier keys + paillierPk = ConfigProperty.getValue(keyConfig, PAILLIER_PUBLIC_KEY_PROPERTY, null); + if (paillierPk == null) { + throw new ConfigException("Must set the paillier public key!"); + } + paillierSk = ConfigProperty.getValue(keyConfig, PAILLIER_PRIVATE_KEY_PROPERTY, null); + if (paillierSk == null) { + throw new ConfigException("Must set the paillier private key"); + } + } + + public String getAesPrivateKey() { + return aesPrivateKey; + } + + public void setAesPrivateKey(String aesPrivateKey) { + this.aesPrivateKey = aesPrivateKey; + } + + public String getOrePrivateKey() { + return orePrivateKey; + } + + public void setOrePrivateKey(String orePrivateKey) { + this.orePrivateKey = orePrivateKey; + } + + public String getIhcPrivateKey() { + return ihcPrivateKey; + } + + public void setIhcPrivateKey(String ihcPrivateKey) { + this.ihcPrivateKey = ihcPrivateKey; + } + + public String getAesIv() { + return aesIv; + } + + public void setAesIv(String aesIv) { + this.aesIv = aesIv; + } + + public String getPaillierSk() { + return paillierSk; + } + + public void setPaillierSk(String paillierSk) { + this.paillierSk = paillierSk; + } + + public String getPaillierPk() { + return paillierPk; + } + + public void setPaillierPk(String paillierPk) { + this.paillierPk = paillierPk; + } + + public int getIhcMode() { + return this.ihcMode; + } +} diff --git a/cpp/wedpr-crypto/ppc-udf/hive/src/main/java/com/webank/wedpr/hive/udf/demo/GeneratePaillierMain.java b/cpp/wedpr-crypto/ppc-udf/hive/src/main/java/com/webank/wedpr/hive/udf/demo/GeneratePaillierMain.java new file mode 100644 index 00000000..f804b518 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-udf/hive/src/main/java/com/webank/wedpr/hive/udf/demo/GeneratePaillierMain.java @@ -0,0 +1,61 @@ +package com.webank.wedpr.hive.udf.demo; + +import com.webank.wedpr.sdk.jni.codec.FloatingPointNumber; +import com.webank.wedpr.sdk.jni.codec.NumberCodec; +import com.webank.wedpr.sdk.jni.codec.NumberCodecImpl; +import com.webank.wedpr.sdk.jni.homo.NativeFloatingPointPaillier; +import com.webank.wedpr.sdk.jni.homo.NativePaillier; +import java.io.File; +import java.io.FileWriter; +import java.math.BigDecimal; +import java.util.Random; +import javax.xml.bind.DatatypeConverter; + +public class GeneratePaillierMain { + + public static void main(String[] args) throws Exception { + String hexPublicKey = + "00000800010100E74CF4A6DD95032412678A2702C6B1C158F0DC94F72191311DC8FA3A2608AAC2F287D3BE7D2583EE7F042B1DBC42C8FE149669D4A36A77A49956D9DFC83DCBD38AB03F7324CB5071EEED8C7FAE108BA4C79639CAFEB4FF96A87EFAAB4580F8CDFCD9FC55BAD63AF2B27BF84B568348228ED7CE8A16A1220CB323301D7F4475A7BAB747477D9056CF9D1FDDE6EBDF4D94814B4A530FB84CC34E36AD0E8DCA220F7E354B4C471B699B155A3463C8A74DE5E824897F519A4BBF01E11FD3F62A349B0604003FB6BC00C1C25173AF4FA610B760114CC55BB92A4173B90A52DE2009C5B18F86725A27B6DA19ED60BD208C5F1875E151CD8DA8D689543C50347A23ED5D0201FF0D6877B3378C46D2839EEF71C78042F99218C2C3E6A3EEB741BAD372E2B5B7FFA222BEBA5C3C18A1B3E4AC890F5AFBAE460607A558743738D11E53EDFA00A54D209A0F52410576ACDD2F28D448B3E48F054A066BEEFA61207E29BB0BDC1EA1EA1B674A94D63D72CC57C55F8250E3EB01F1A4AD42FA14F9EAF92D880CF279DFF50A2AD6FD062B026886FF23BBE310EA1E324BF83B6860A864BD9E28B5DBE5D01173E090827262A65FA7EB0729860808DE9DEB9B2D17B0EABCB3699635EB5B4676AA7E7C533F361FDBE578DA114C6771EEE97894291796A03F1519C77ADBF8697741E48E1DC8E0B15667B617631155E88D9D6781B0FC2D26BD9A121620B2A65ACD099FE494BD887021759E7A16AAA570C881964DF67152E7D578A1751E09B11461A1ACF5FDAEFEAC5410BC5970BE924E56551F7763FD293669F24FAE322931DACDB27A6A865E0F5875A5C26082A329CEDEA47A5F2776DFD2144389AB5EC5358CFAB44B481851ED03292AB79B3E59EF0B0CB8DCE7CEE102E5E0A7597150B297FFEFFF80ED684C1CC5A0DE369EC2B636F1F9B41F4372B4AF662C71F89F0AD456595423CE4B3A38E5998CBB5EA096C9AFAABD9B48DE8BC5819F95C47E7576CAC92CADC4E00175252D6BFD1C5D585442AD5C4285A6878DE9A65D425AF3B61359D9B39C1427923CEB5B82B1CFBF4941DA0454746CD79E30912998A6407F34C29713C210"; + + long startTime1 = System.currentTimeMillis(); + long publicKeyPointer = + NativePaillier.loadPublicKey(DatatypeConverter.parseHexBinary(hexPublicKey)); + long endTime = System.currentTimeMillis(); + System.out.println( + "TestPaillierDemo loadPublicKey cost: " + (endTime - startTime1) + " ms"); + + final NumberCodec codec = new NumberCodecImpl(); + // 创建一个文件 + File file = new File("paillier.csv"); + // 创建一个文件写入器 + FileWriter writer = new FileWriter(file); + // 创建一个随机数生成器 + Random random = new Random(); + int count = Integer.parseInt(args[0]); + // 循环生成100万个随机数 + for (int i = 1; i <= count; i++) { + // 生成一个随机数 + double number = random.nextDouble() * 1000.99999 + 1.99999; + // System.out.println("TestPaillierDemo double number: " + number); + BigDecimal originalValue = new BigDecimal(number); + FloatingPointNumber plainValueFp = codec.encode(originalValue); + byte[] cipher = + NativeFloatingPointPaillier.encrypt( + plainValueFp.getSignificantBytes(), + plainValueFp.getExponent(), + publicKeyPointer); + String hexCipher = DatatypeConverter.printHexBinary(cipher); + // System.out.println("TestPaillierDemo BigDecimal encryptedValue: " + + // hexCipher); + // 将自增id和密文字符串写入文件 + writer.write(i + "," + hexCipher + "\n"); + } + // 关闭文件写入器 + writer.close(); + long startTime2 = System.nanoTime(); + NativePaillier.freePublicKey(publicKeyPointer); + long endTime2 = System.nanoTime(); + System.out.println( + "TestPaillierDemo freePublicKey cost: " + (endTime2 - startTime2) + " ns"); + } +} diff --git a/cpp/wedpr-crypto/ppc-udf/hive/src/main/java/com/webank/wedpr/hive/udf/exceptions/ConfigException.java b/cpp/wedpr-crypto/ppc-udf/hive/src/main/java/com/webank/wedpr/hive/udf/exceptions/ConfigException.java new file mode 100644 index 00000000..8c7f9cb5 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-udf/hive/src/main/java/com/webank/wedpr/hive/udf/exceptions/ConfigException.java @@ -0,0 +1,11 @@ +package com.webank.wedpr.hive.udf.exceptions; + +public class ConfigException extends RuntimeException { + public ConfigException(String message) { + super(message); + } + + public ConfigException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/cpp/wedpr-crypto/ppc-udf/hive/src/main/java/com/webank/wedpr/hive/udf/exceptions/DecryptionException.java b/cpp/wedpr-crypto/ppc-udf/hive/src/main/java/com/webank/wedpr/hive/udf/exceptions/DecryptionException.java new file mode 100644 index 00000000..0a6ca5e7 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-udf/hive/src/main/java/com/webank/wedpr/hive/udf/exceptions/DecryptionException.java @@ -0,0 +1,11 @@ +package com.webank.wedpr.hive.udf.exceptions; + +public class DecryptionException extends RuntimeException { + public DecryptionException(String message) { + super(message); + } + + public DecryptionException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/cpp/wedpr-crypto/ppc-udf/hive/src/main/java/com/webank/wedpr/hive/udf/exceptions/EncryptionException.java b/cpp/wedpr-crypto/ppc-udf/hive/src/main/java/com/webank/wedpr/hive/udf/exceptions/EncryptionException.java new file mode 100644 index 00000000..b79484a9 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-udf/hive/src/main/java/com/webank/wedpr/hive/udf/exceptions/EncryptionException.java @@ -0,0 +1,24 @@ +/** + * Copyright 2023 [wedpr] + * + *

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. + */ +package com.webank.wedpr.hive.udf.exceptions; + +public class EncryptionException extends RuntimeException { + public EncryptionException(String message) { + super(message); + } + + public EncryptionException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/cpp/wedpr-crypto/ppc-udf/hive/src/main/java/com/webank/wedpr/hive/udf/exceptions/KeyException.java b/cpp/wedpr-crypto/ppc-udf/hive/src/main/java/com/webank/wedpr/hive/udf/exceptions/KeyException.java new file mode 100644 index 00000000..aa43c71e --- /dev/null +++ b/cpp/wedpr-crypto/ppc-udf/hive/src/main/java/com/webank/wedpr/hive/udf/exceptions/KeyException.java @@ -0,0 +1,11 @@ +package com.webank.wedpr.hive.udf.exceptions; + +public class KeyException extends RuntimeException { + public KeyException(String message) { + super(message); + } + + public KeyException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/cpp/wedpr-crypto/ppc-udf/hive/src/main/java/com/webank/wedpr/hive/udf/impl/ihc/IhcDecryptionUDF.java b/cpp/wedpr-crypto/ppc-udf/hive/src/main/java/com/webank/wedpr/hive/udf/impl/ihc/IhcDecryptionUDF.java new file mode 100644 index 00000000..e9d0522e --- /dev/null +++ b/cpp/wedpr-crypto/ppc-udf/hive/src/main/java/com/webank/wedpr/hive/udf/impl/ihc/IhcDecryptionUDF.java @@ -0,0 +1,74 @@ +/** + * Copyright 2023 [wedpr] + * + *

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. + */ +package com.webank.wedpr.hive.udf.impl.ihc; + +import com.webank.wedpr.hive.udf.config.ConfigLoader; +import com.webank.wedpr.hive.udf.config.model.KeyConfig; +import com.webank.wedpr.hive.udf.exceptions.DecryptionException; +import com.webank.wedpr.sdk.jni.codec.FloatingPointNumber; +import com.webank.wedpr.sdk.jni.codec.NumberCodec; +import com.webank.wedpr.sdk.jni.codec.NumberCodecImpl; +import com.webank.wedpr.sdk.jni.homo.NativeFloatingIhc; +import java.math.BigDecimal; +import javax.xml.bind.DatatypeConverter; +import org.apache.hadoop.hive.ql.exec.Description; +import org.apache.hadoop.hive.ql.exec.UDF; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author caryliao + * @date 2023/11/28 + */ +@Description( + name = "ihc_dec", + value = "迭代希尔密码解密", + extended = + "用法:ihc_dec(columnName, hexSk, iterRound, keyBits) \n" + + "示例:select ihc_dec(salary, '303132...', 10, 64) from t_user") +public class IhcDecryptionUDF extends UDF { + private static final Logger logger = LoggerFactory.getLogger(IhcDecryptionUDF.class); + private final NumberCodec codec = new NumberCodecImpl(); + + public String evaluate(final String cipherValue) { + KeyConfig config = ConfigLoader.config.getKeyConfig(); + return evaluate(config.getIhcMode(), config.getIhcPrivateKey(), cipherValue); + } + /** + * ihc_enc(columnName, hexSk, iterRound, keyBits) + * + * @param cipherValue + * @param hexSk + * @return + */ + public String evaluate(int mode, final String hexSk, final String cipherValue) { + try { + if (cipherValue == null) { + return null; + } + FloatingPointNumber cipherValueFp = + NativeFloatingIhc.decrypt( + mode, + DatatypeConverter.parseHexBinary(hexSk), + DatatypeConverter.parseHexBinary(cipherValue)); + int scale = (cipherValueFp.getExponent() <= 0 ? -cipherValueFp.getExponent() : 0); + return codec.decodeBigDecimal(cipherValueFp) + .setScale(scale, BigDecimal.ROUND_HALF_UP) + .toString(); + } catch (Exception e) { + logger.error("ihc解密失败 ", e); + throw new DecryptionException("ihc解密失败", e); + } + } +} diff --git a/cpp/wedpr-crypto/ppc-udf/hive/src/main/java/com/webank/wedpr/hive/udf/impl/ihc/IhcEncryptionUDF.java b/cpp/wedpr-crypto/ppc-udf/hive/src/main/java/com/webank/wedpr/hive/udf/impl/ihc/IhcEncryptionUDF.java new file mode 100644 index 00000000..90ef0e7f --- /dev/null +++ b/cpp/wedpr-crypto/ppc-udf/hive/src/main/java/com/webank/wedpr/hive/udf/impl/ihc/IhcEncryptionUDF.java @@ -0,0 +1,74 @@ +/** + * Copyright 2023 [wedpr] + * + *

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. + */ +package com.webank.wedpr.hive.udf.impl.ihc; + +import com.webank.wedpr.hive.udf.config.ConfigLoader; +import com.webank.wedpr.hive.udf.config.model.KeyConfig; +import com.webank.wedpr.hive.udf.exceptions.DecryptionException; +import com.webank.wedpr.sdk.jni.codec.FloatingPointNumber; +import com.webank.wedpr.sdk.jni.codec.NumberCodec; +import com.webank.wedpr.sdk.jni.codec.NumberCodecImpl; +import com.webank.wedpr.sdk.jni.homo.NativeFloatingIhc; +import java.math.BigDecimal; +import javax.xml.bind.DatatypeConverter; +import org.apache.hadoop.hive.ql.exec.Description; +import org.apache.hadoop.hive.ql.exec.UDF; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author caryliao + * @date 2023/11/28 + */ +@Description( + name = "ihc_enc", + value = "迭代希尔密码加密", + extended = + "用法:ihc_enc(columnName, hexSk, iterRound, keyBits) \n" + + "示例:select ihc_enc(salary, '303132...', 10, 64) from t_user") +public class IhcEncryptionUDF extends UDF { + private static final Logger logger = LoggerFactory.getLogger(IhcEncryptionUDF.class); + + private final NumberCodec codec = new NumberCodecImpl(); + + public String evaluate(final String plainValue) { + KeyConfig config = ConfigLoader.config.getKeyConfig(); + return evaluate(config.getIhcMode(), config.getIhcPrivateKey(), plainValue); + } + /** + * ihc_enc(columnName, hexSk, iterRound, keyBits) + * + * @param plainValue + * @param hexSk + * @return + */ + public String evaluate(int mode, final String hexSk, final String plainValue) { + try { + if (plainValue == null) { + return null; + } + FloatingPointNumber plainValueFp = codec.encode(new BigDecimal(plainValue)); + byte[] cipher = + NativeFloatingIhc.encrypt( + mode, + DatatypeConverter.parseHexBinary(hexSk), + plainValueFp.getSignificantBytes(), + plainValueFp.getExponent()); + return DatatypeConverter.printHexBinary(cipher); + } catch (Exception e) { + logger.error("ihc加密失败 ", e); + throw new DecryptionException("ihc加密失败", e); + } + } +} diff --git a/cpp/wedpr-crypto/ppc-udf/hive/src/main/java/com/webank/wedpr/hive/udf/impl/ihc/IhcSumUDAF.java b/cpp/wedpr-crypto/ppc-udf/hive/src/main/java/com/webank/wedpr/hive/udf/impl/ihc/IhcSumUDAF.java new file mode 100644 index 00000000..aad83e31 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-udf/hive/src/main/java/com/webank/wedpr/hive/udf/impl/ihc/IhcSumUDAF.java @@ -0,0 +1,211 @@ +package com.webank.wedpr.hive.udf.impl.ihc; + +import com.webank.wedpr.hive.udf.config.ConfigLoader; +import com.webank.wedpr.hive.udf.config.model.KeyConfig; +import com.webank.wedpr.sdk.jni.common.JniException; +import com.webank.wedpr.sdk.jni.homo.NativeFloatingIhc; +import java.util.ArrayList; +import javax.xml.bind.DatatypeConverter; +import org.apache.hadoop.hive.ql.exec.Description; +import org.apache.hadoop.hive.ql.exec.UDFArgumentTypeException; +import org.apache.hadoop.hive.ql.metadata.HiveException; +import org.apache.hadoop.hive.ql.parse.SemanticException; +import org.apache.hadoop.hive.ql.udf.generic.AbstractGenericUDAFResolver; +import org.apache.hadoop.hive.ql.udf.generic.GenericUDAFEvaluator; +import org.apache.hadoop.hive.ql.udf.generic.GenericUDAFParameterInfo; +import org.apache.hadoop.hive.serde2.objectinspector.*; +import org.apache.hadoop.hive.serde2.objectinspector.primitive.BinaryObjectInspector; +import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorFactory; +import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorUtils; +import org.apache.hadoop.hive.serde2.typeinfo.PrimitiveTypeInfo; +import org.apache.hadoop.hive.serde2.typeinfo.TypeInfo; +import org.apache.hadoop.io.BytesWritable; +import org.apache.hadoop.io.Text; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author caryliao + * @date 2023/11/9 + */ +@Description( + name = "ihc_sum", + value = "Returns the sum of a set of ihc ciphertexts", + extended = + "Usage:ihc_sum(columnName) \n" + + "Example:select ihc_sum(encrypted_salary, 64) from t_user\n") +public class IhcSumUDAF extends AbstractGenericUDAFResolver { + static final Logger logger = LoggerFactory.getLogger(IhcSumUDAF.class); + + @Override + public GenericUDAFEvaluator getEvaluator(GenericUDAFParameterInfo info) + throws SemanticException { + return getEvaluator(info.getParameters()); + } + + @Override + public GenericUDAFEvaluator getEvaluator(TypeInfo[] parameters) throws SemanticException { + int paramsCount = 1; + if (parameters.length != paramsCount) { + throw new UDFArgumentTypeException( + parameters.length - 1, "Exactly one arguments are expected."); + } + + if (((PrimitiveTypeInfo) parameters[0]).getPrimitiveCategory() + != PrimitiveObjectInspector.PrimitiveCategory.STRING) { + throw new UDFArgumentTypeException(0, "Only (string, int) type arguments are accepted"); + } + return new IhcSumUDAFEvaluator(); + } + + /** IhcSumUDAFEvaluator. */ + public static class IhcSumUDAFEvaluator extends GenericUDAFEvaluator { + + // Iterate 输入 + private PrimitiveObjectInspector inputOICipherText; + // Merge 输入 + private StructObjectInspector structOI; + + private BinaryObjectInspector sumFieldOI; + + private StructField sumField; + + // TerminatePartial 输出 + private Object[] partialResult; + + // Terminate 输出 + private Text result; + + // the keyConfig + private KeyConfig keyConfig; + + // 中间结果 + static class IhcSumBuffer implements AggregationBuffer { + byte[] sum; + } + + @Override + public ObjectInspector init(Mode mode, ObjectInspector[] parameters) throws HiveException { + super.init(mode, parameters); + // load keys + keyConfig = ConfigLoader.config.getKeyConfig(); + // 初始化输入参数类型 + if (mode == Mode.PARTIAL1 || mode == Mode.COMPLETE) { + inputOICipherText = (PrimitiveObjectInspector) parameters[0]; + } else { + // Struct + structOI = (StructObjectInspector) parameters[0]; + sumField = structOI.getStructFieldRef("sum"); + sumFieldOI = (BinaryObjectInspector) sumField.getFieldObjectInspector(); + } + // 初始化输出类型 + if (mode == Mode.PARTIAL1 || mode == Mode.PARTIAL2) { + // 输出类型 + if (partialResult == null) { + partialResult = new Object[1]; + partialResult[0] = new BytesWritable(); + } + // 输出OI + // 字段类型 + ArrayList objectInspectors = new ArrayList(); + objectInspectors.add(PrimitiveObjectInspectorFactory.writableBinaryObjectInspector); + // 字段名称 + ArrayList fieldNames = new ArrayList(); + fieldNames.add("sum"); + return ObjectInspectorFactory.getStandardStructObjectInspector( + fieldNames, objectInspectors); + + } else { + result = new Text(); + return PrimitiveObjectInspectorFactory.writableStringObjectInspector; + } + } + + @Override + public AggregationBuffer getNewAggregationBuffer() throws HiveException { + IhcSumBuffer buffer = new IhcSumBuffer(); + reset(buffer); + return buffer; + } + + @Override + public void reset(AggregationBuffer agg) throws HiveException { + IhcSumBuffer buffer = (IhcSumBuffer) agg; + buffer.sum = null; + } + + @Override + public void iterate(AggregationBuffer agg, Object[] parameters) throws HiveException { + try { + if (parameters[0] != null) { + IhcSumBuffer buffer = (IhcSumBuffer) agg; + String cipherText = + PrimitiveObjectInspectorUtils.getString( + parameters[0], inputOICipherText); + byte[] cipherTextBytes = DatatypeConverter.parseHexBinary(cipherText); + if (buffer.sum == null) { + buffer.sum = cipherTextBytes; + } else { + buffer.sum = + NativeFloatingIhc.add( + keyConfig.getIhcMode(), buffer.sum, cipherTextBytes); + } + } + } catch (JniException e) { + logger.error("ihc迭代过程失败", e); + throw new HiveException(e); + } catch (Exception e) { + logger.error("ihc迭代过程失败", e); + throw new HiveException(e); + } + } + + // 输出部分聚合结果 + @Override + public Object terminatePartial(AggregationBuffer agg) throws HiveException { + IhcSumBuffer buffer = (IhcSumBuffer) agg; + if (buffer.sum == null) { + return null; + } + ((BytesWritable) partialResult[0]).set(new BytesWritable(buffer.sum)); + return partialResult; + } + + // 合并 + @Override + public void merge(AggregationBuffer agg, Object partialResult) throws HiveException { + IhcSumBuffer buffer = (IhcSumBuffer) agg; + if (partialResult == null) { + return; + } + // 通过StandardStructObjectInspector实例,分解出 partialResult 数组元素值 + Object partialSum = structOI.getStructFieldData(partialResult, sumField); + try { + // 通过基本数据类型的OI 实例解析 Object 的值 + byte[] sum = sumFieldOI.getPrimitiveJavaObject(partialSum); + if (buffer.sum == null) { + buffer.sum = sum; + } else { + buffer.sum = NativeFloatingIhc.add(keyConfig.getIhcMode(), buffer.sum, sum); + } + } catch (JniException e) { + logger.error("ihc聚合过程失败", e); + throw new HiveException(e); + } + } + + // 输出最终聚合结果 + @Override + public Object terminate(AggregationBuffer agg) throws HiveException { + IhcSumBuffer buffer = (IhcSumBuffer) agg; + if (buffer.sum == null) { + return null; + } + if (result == null) { + result = new Text(); + } + result.set(DatatypeConverter.printHexBinary(buffer.sum)); + return result; + } + } +} diff --git a/cpp/wedpr-crypto/ppc-udf/hive/src/main/java/com/webank/wedpr/hive/udf/impl/ore/OreDecryptionUDF.java b/cpp/wedpr-crypto/ppc-udf/hive/src/main/java/com/webank/wedpr/hive/udf/impl/ore/OreDecryptionUDF.java new file mode 100644 index 00000000..a4d81ae6 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-udf/hive/src/main/java/com/webank/wedpr/hive/udf/impl/ore/OreDecryptionUDF.java @@ -0,0 +1,61 @@ +/** + * Copyright 2023 [wedpr] + * + *

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. + */ +package com.webank.wedpr.hive.udf.impl.ore; + +import com.webank.wedpr.hive.udf.config.ConfigLoader; +import com.webank.wedpr.hive.udf.config.model.KeyConfig; +import com.webank.wedpr.hive.udf.exceptions.DecryptionException; +import com.webank.wedpr.sdk.jni.crypto.FastOre; +import javax.xml.bind.DatatypeConverter; +import org.apache.commons.codec.Charsets; +import org.apache.hadoop.hive.ql.exec.Description; +import org.apache.hadoop.hive.ql.exec.UDF; +import org.apache.log4j.Logger; + +/** @author caryliao 2023/11/2 */ +@Description( + name = "ore_dec", + value = "decrypt ore cipher to plain value", + extended = + "Usage:ore_dec(columnName, hexSk) \n" + + "Example:select ore_dec(encrypted_name, '303132...') as user_name from t_user") +public class OreDecryptionUDF extends UDF { + private static final Logger logger = Logger.getLogger(OreDecryptionUDF.class.getName()); + + public String evaluate(final String hexCipher) { + if (hexCipher == null) { + return null; + } + KeyConfig keyConfig = ConfigLoader.config.getKeyConfig(); + return evaluate(hexCipher, keyConfig.getOrePrivateKey()); + } + + public String evaluate(final String hexCipher, String hexSk) { + try { + if (hexCipher == null) { + return null; + } + return new String( + FastOre.decrypt4String( + DatatypeConverter.parseHexBinary(hexSk), + hexCipher.getBytes(Charsets.UTF_8), + true), + Charsets.UTF_8) + .trim(); + } catch (Exception e) { + logger.error("OreDecryptionUDF jni fail ", e); + throw new DecryptionException("ore Decrypt jni fail ", e); + } + } +} diff --git a/cpp/wedpr-crypto/ppc-udf/hive/src/main/java/com/webank/wedpr/hive/udf/impl/ore/OreEncryptionUDF.java b/cpp/wedpr-crypto/ppc-udf/hive/src/main/java/com/webank/wedpr/hive/udf/impl/ore/OreEncryptionUDF.java new file mode 100644 index 00000000..6e4bd854 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-udf/hive/src/main/java/com/webank/wedpr/hive/udf/impl/ore/OreEncryptionUDF.java @@ -0,0 +1,57 @@ +/** + * Copyright 2023 [wedpr] + * + *

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. + */ +package com.webank.wedpr.hive.udf.impl.ore; + +import com.webank.wedpr.hive.udf.config.ConfigLoader; +import com.webank.wedpr.hive.udf.config.model.KeyConfig; +import com.webank.wedpr.hive.udf.exceptions.EncryptionException; +import com.webank.wedpr.sdk.jni.crypto.FastOre; +import javax.xml.bind.DatatypeConverter; +import org.apache.commons.codec.Charsets; +import org.apache.hadoop.hive.ql.exec.Description; +import org.apache.hadoop.hive.ql.exec.UDF; +import org.apache.log4j.Logger; + +@Description( + name = "ore_enc", + value = "encrypt ore plain-text to cipher", + extended = + "Usage:ore_enc(columnName, hexSk) \n" + + "Example:select ore_enc(encrypted_name, '303132...') as user_name from t_user") +public class OreEncryptionUDF extends UDF { + private static final Logger logger = Logger.getLogger(OreEncryptionUDF.class.getName()); + + public String evaluate(final String plainData) { + KeyConfig keyConfig = ConfigLoader.config.getKeyConfig(); + return evaluate(plainData, keyConfig.getOrePrivateKey()); + } + + public String evaluate(final String plainData, String hexSk) { + try { + if (plainData == null) { + return null; + } + return new String( + FastOre.encrypt4String( + DatatypeConverter.parseHexBinary(hexSk), + plainData.getBytes(Charsets.UTF_8), + true), + Charsets.UTF_8) + .trim(); + } catch (Exception e) { + logger.warn("ORE Encryption exception", e); + throw new EncryptionException("ORE Encryption exception", e); + } + } +} diff --git a/cpp/wedpr-crypto/ppc-udf/hive/src/main/java/com/webank/wedpr/hive/udf/impl/ore/OreNumberDecryptionUDF.java b/cpp/wedpr-crypto/ppc-udf/hive/src/main/java/com/webank/wedpr/hive/udf/impl/ore/OreNumberDecryptionUDF.java new file mode 100644 index 00000000..e5509f47 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-udf/hive/src/main/java/com/webank/wedpr/hive/udf/impl/ore/OreNumberDecryptionUDF.java @@ -0,0 +1,48 @@ +/** + * Copyright 2024 [wedpr] + * + *

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. + */ +package com.webank.wedpr.hive.udf.impl.ore; + +import com.webank.wedpr.hive.udf.config.ConfigLoader; +import com.webank.wedpr.hive.udf.config.model.KeyConfig; +import com.webank.wedpr.hive.udf.exceptions.DecryptionException; +import com.webank.wedpr.sdk.jni.codec.NumberCodec; +import com.webank.wedpr.sdk.jni.codec.NumberCodecImpl; +import com.webank.wedpr.sdk.jni.crypto.FastOre; +import javax.xml.bind.DatatypeConverter; +import org.apache.commons.codec.Charsets; +import org.apache.hadoop.hive.ql.exec.UDF; +import org.apache.log4j.Logger; + +public class OreNumberDecryptionUDF extends UDF { + private static final Logger logger = Logger.getLogger(OreNumberDecryptionUDF.class.getName()); + private static final NumberCodec codec = new NumberCodecImpl(); + + public String evaluate(String cipher) { + KeyConfig keyConfig = ConfigLoader.config.getKeyConfig(); + try { + if (cipher == null) { + return null; + } + return codec.toBigDecimal( + FastOre.decrypt4Float( + DatatypeConverter.parseHexBinary(keyConfig.getOrePrivateKey()), + cipher.getBytes(Charsets.UTF_8), + true)) + .toPlainString(); + } catch (Exception e) { + logger.error("OreNumberDecryptionUDF jni fail ", e); + throw new DecryptionException("ore Decrypt jni fail ", e); + } + } +} diff --git a/cpp/wedpr-crypto/ppc-udf/hive/src/main/java/com/webank/wedpr/hive/udf/impl/ore/OreNumberEncryptionUDF.java b/cpp/wedpr-crypto/ppc-udf/hive/src/main/java/com/webank/wedpr/hive/udf/impl/ore/OreNumberEncryptionUDF.java new file mode 100644 index 00000000..b6f8a6a4 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-udf/hive/src/main/java/com/webank/wedpr/hive/udf/impl/ore/OreNumberEncryptionUDF.java @@ -0,0 +1,72 @@ +/** + * Copyright 2024 [wedpr] + * + *

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. + */ +package com.webank.wedpr.hive.udf.impl.ore; + +import com.webank.wedpr.hive.udf.config.ConfigLoader; +import com.webank.wedpr.hive.udf.config.model.KeyConfig; +import com.webank.wedpr.hive.udf.exceptions.DecryptionException; +import com.webank.wedpr.sdk.jni.codec.NumberCodec; +import com.webank.wedpr.sdk.jni.codec.NumberCodecImpl; +import com.webank.wedpr.sdk.jni.crypto.FastOre; +import java.math.BigDecimal; +import javax.xml.bind.DatatypeConverter; +import org.apache.commons.codec.Charsets; +import org.apache.hadoop.hive.ql.exec.UDF; +import org.apache.log4j.Logger; + +public class OreNumberEncryptionUDF extends UDF { + private static final Logger logger = Logger.getLogger(OreNumberEncryptionUDF.class.getName()); + private static final NumberCodec codec = new NumberCodecImpl(); + + public String evaluate(final BigDecimal value) { + if (value == null) { + return null; + } + return evaluate(codec.toBytes(value)); + } + + public String evaluate(final Double value) { + if (value == null) { + return null; + } + return evaluate(codec.toBytes(value)); + } + + public String evaluate(final String value) { + if (value == null) { + return null; + } + return evaluate(value.getBytes(Charsets.UTF_8)); + } + + public String evaluate(final byte[] plainBytes) { + + KeyConfig keyConfig = ConfigLoader.config.getKeyConfig(); + try { + if (plainBytes == null) { + return null; + } + return new String( + FastOre.encrypt4Float( + DatatypeConverter.parseHexBinary(keyConfig.getOrePrivateKey()), + plainBytes, + true), + Charsets.UTF_8) + .trim(); + } catch (Exception e) { + logger.error("OreNumberEncryptionUDFNumnerNumner jni fail ", e); + throw new DecryptionException("ore Decrypt jni fail ", e); + } + } +} diff --git a/cpp/wedpr-crypto/ppc-udf/hive/src/main/java/com/webank/wedpr/hive/udf/impl/paillier/PaillierDecryptionUDF.java b/cpp/wedpr-crypto/ppc-udf/hive/src/main/java/com/webank/wedpr/hive/udf/impl/paillier/PaillierDecryptionUDF.java new file mode 100644 index 00000000..798fb21f --- /dev/null +++ b/cpp/wedpr-crypto/ppc-udf/hive/src/main/java/com/webank/wedpr/hive/udf/impl/paillier/PaillierDecryptionUDF.java @@ -0,0 +1,83 @@ +/** + * Copyright 2023 [wedpr] + * + *

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. + */ +package com.webank.wedpr.hive.udf.impl.paillier; + +import com.webank.wedpr.hive.udf.config.ConfigLoader; +import com.webank.wedpr.hive.udf.config.model.KeyConfig; +import com.webank.wedpr.hive.udf.exceptions.DecryptionException; +import com.webank.wedpr.hive.udf.exceptions.KeyException; +import com.webank.wedpr.sdk.jni.codec.FloatingPointNumber; +import com.webank.wedpr.sdk.jni.codec.NumberCodec; +import com.webank.wedpr.sdk.jni.codec.NumberCodecImpl; +import com.webank.wedpr.sdk.jni.homo.NativeFloatingPointPaillier; +import com.webank.wedpr.sdk.jni.homo.NativePaillier; +import java.math.BigDecimal; +import javax.xml.bind.DatatypeConverter; +import org.apache.hadoop.hive.ql.exec.Description; +import org.apache.hadoop.hive.ql.exec.UDF; +import org.apache.hadoop.io.Text; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author caryliao + * @date 2023/10/31 + */ +@Description( + name = "paillier_dec", + value = "decrypt paillier cipher to plain value", + extended = + "Usage:paillier_dec(columnName) \n" + + "Example:select paillier_dec(encrypted_salary)") +public class PaillierDecryptionUDF extends UDF { + private static final Logger logger = LoggerFactory.getLogger(PaillierDecryptionUDF.class); + + private static long keyPairPointer = 0L; + private static final NumberCodec codec = new NumberCodecImpl(); + + static { + try { + KeyConfig keyConfig = ConfigLoader.config.getKeyConfig(); + keyPairPointer = + NativePaillier.loadKeyPair( + DatatypeConverter.parseHexBinary(keyConfig.getPaillierSk()), + DatatypeConverter.parseHexBinary(keyConfig.getPaillierPk())); + } catch (Exception e) { + throw new KeyException("Load key pair for paillier error", e); + } + } + /** + * paillier_dec(columnName) + * + * @param hexCipher + * @return + */ + public String evaluate(final Text hexCipher) { + if (hexCipher == null) { + return null; + } + try { + FloatingPointNumber cipherValueFp = + NativeFloatingPointPaillier.decrypt( + DatatypeConverter.parseHexBinary(hexCipher.toString()), keyPairPointer); + int scale = (cipherValueFp.getExponent() <= 0 ? -cipherValueFp.getExponent() : 0); + return codec.decodeBigDecimal(cipherValueFp) + .setScale(scale, BigDecimal.ROUND_HALF_UP) + .toString(); + } catch (Exception e) { + logger.error("Paillier Decrypt jni fail ", e); + throw new DecryptionException("Paillier Decrypt jni fail ", e); + } + } +} diff --git a/cpp/wedpr-crypto/ppc-udf/hive/src/main/java/com/webank/wedpr/hive/udf/impl/paillier/PaillierEncryptionUDF.java b/cpp/wedpr-crypto/ppc-udf/hive/src/main/java/com/webank/wedpr/hive/udf/impl/paillier/PaillierEncryptionUDF.java new file mode 100644 index 00000000..259a205b --- /dev/null +++ b/cpp/wedpr-crypto/ppc-udf/hive/src/main/java/com/webank/wedpr/hive/udf/impl/paillier/PaillierEncryptionUDF.java @@ -0,0 +1,86 @@ +/** + * Copyright 2023 [wedpr] + * + *

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. + */ +package com.webank.wedpr.hive.udf.impl.paillier; + +import com.webank.wedpr.hive.udf.config.ConfigLoader; +import com.webank.wedpr.hive.udf.config.model.KeyConfig; +import com.webank.wedpr.hive.udf.exceptions.EncryptionException; +import com.webank.wedpr.hive.udf.exceptions.KeyException; +import com.webank.wedpr.sdk.jni.codec.FloatingPointNumber; +import com.webank.wedpr.sdk.jni.codec.NumberCodec; +import com.webank.wedpr.sdk.jni.codec.NumberCodecException; +import com.webank.wedpr.sdk.jni.codec.NumberCodecImpl; +import com.webank.wedpr.sdk.jni.common.JniException; +import com.webank.wedpr.sdk.jni.homo.NativeFloatingPointPaillier; +import com.webank.wedpr.sdk.jni.homo.NativePaillier; +import java.math.BigDecimal; +import javax.xml.bind.DatatypeConverter; +import org.apache.hadoop.hive.ql.exec.Description; +import org.apache.hadoop.hive.ql.exec.UDF; +import org.apache.hadoop.io.Text; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author caryliao + * @date 2023/12/2 + */ +@Description( + name = "paillier_enc", + value = "encrypt plain value to paillier cipher", + extended = + "Usage:paillier_enc(columnName, hexPk) \n" + + "Example:select paillier_enc(encrypted_salary,'0000080001...')") +public class PaillierEncryptionUDF extends UDF { + private static final Logger logger = LoggerFactory.getLogger(PaillierEncryptionUDF.class); + private static long publicKeyPointer = 0L; + private static final NumberCodec codec = new NumberCodecImpl(); + + static { + try { + KeyConfig keyConfig = ConfigLoader.config.getKeyConfig(); + publicKeyPointer = + NativePaillier.loadPublicKey( + DatatypeConverter.parseHexBinary(keyConfig.getPaillierPk())); + } catch (Exception e) { + throw new KeyException( + "Load public key for paillier exception, error: " + e.getMessage(), e); + } + } + + /** + * paillier_enc(columnName, hexPk) + * + * @param plainValue + * @return + */ + public Text evaluate(final Text plainValue) { + if (plainValue == null) { + return null; + } + try { + BigDecimal value = new BigDecimal(plainValue.toString()); + FloatingPointNumber plainValueFp = codec.encode(value); + byte[] cipherValue = + NativeFloatingPointPaillier.encrypt( + plainValueFp.getSignificantBytes(), + plainValueFp.getExponent(), + publicKeyPointer); + return new Text(DatatypeConverter.printHexBinary(cipherValue)); + } catch (NumberCodecException | JniException e) { + logger.error("Paillier Encrypt BigDecimal jni fail ", e); + throw new EncryptionException("WeFec Paillier Encrypt BigDecimal jni fail ", e); + } + } +} diff --git a/cpp/wedpr-crypto/ppc-udf/hive/src/main/java/com/webank/wedpr/hive/udf/impl/paillier/PaillierSumUDAF.java b/cpp/wedpr-crypto/ppc-udf/hive/src/main/java/com/webank/wedpr/hive/udf/impl/paillier/PaillierSumUDAF.java new file mode 100644 index 00000000..f1c15846 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-udf/hive/src/main/java/com/webank/wedpr/hive/udf/impl/paillier/PaillierSumUDAF.java @@ -0,0 +1,219 @@ +package com.webank.wedpr.hive.udf.impl.paillier; + +import com.webank.wedpr.hive.udf.config.ConfigLoader; +import com.webank.wedpr.hive.udf.config.model.KeyConfig; +import com.webank.wedpr.hive.udf.exceptions.KeyException; +import com.webank.wedpr.sdk.jni.common.JniException; +import com.webank.wedpr.sdk.jni.homo.NativeFloatingPointPaillier; +import com.webank.wedpr.sdk.jni.homo.NativePaillier; +import java.util.ArrayList; +import javax.xml.bind.DatatypeConverter; +import org.apache.hadoop.hive.ql.exec.Description; +import org.apache.hadoop.hive.ql.exec.UDFArgumentTypeException; +import org.apache.hadoop.hive.ql.metadata.HiveException; +import org.apache.hadoop.hive.ql.parse.SemanticException; +import org.apache.hadoop.hive.ql.udf.generic.AbstractGenericUDAFResolver; +import org.apache.hadoop.hive.ql.udf.generic.GenericUDAFEvaluator; +import org.apache.hadoop.hive.ql.udf.generic.GenericUDAFParameterInfo; +import org.apache.hadoop.hive.serde2.objectinspector.*; +import org.apache.hadoop.hive.serde2.objectinspector.primitive.BinaryObjectInspector; +import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorFactory; +import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorUtils; +import org.apache.hadoop.hive.serde2.typeinfo.PrimitiveTypeInfo; +import org.apache.hadoop.hive.serde2.typeinfo.TypeInfo; +import org.apache.hadoop.io.BytesWritable; +import org.apache.hadoop.io.Text; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** @author caryliao 2023/11/9 */ +@Description( + name = "paillier_sum", + value = "Returns the sum of a set of paillier ciphertexts", + extended = + "Usage:paillier_sum(columnName, hexPk) \n" + + "Example:select paillier_sum(encrypted_salary,'0000080001...')") +public class PaillierSumUDAF extends AbstractGenericUDAFResolver { + static final Logger logger = LoggerFactory.getLogger(PaillierSumUDAF.class); + + private static long publicKeyPointer = 0L; + + static { + try { + KeyConfig keyConfig = ConfigLoader.config.getKeyConfig(); + publicKeyPointer = + NativePaillier.loadPublicKey( + DatatypeConverter.parseHexBinary(keyConfig.getPaillierPk())); + } catch (Exception e) { + throw new KeyException( + "Load public key for paillier exception, error: " + e.getMessage(), e); + } + } + + @Override + public GenericUDAFEvaluator getEvaluator(GenericUDAFParameterInfo info) + throws SemanticException { + return getEvaluator(info.getParameters()); + } + + @Override + public GenericUDAFEvaluator getEvaluator(TypeInfo[] parameters) throws SemanticException { + int paramsCount = 1; + if (parameters.length != paramsCount) { + throw new UDFArgumentTypeException( + parameters.length - 1, "Exactly one arguments are expected."); + } + + if (((PrimitiveTypeInfo) parameters[0]).getPrimitiveCategory() + != PrimitiveObjectInspector.PrimitiveCategory.STRING) { + throw new UDFArgumentTypeException(0, "Only string type arguments are accepted"); + } + return new PaillierSumUDAFEvaluator(); + } + + /** PaillierSumUDAFEvaluator. */ + public static class PaillierSumUDAFEvaluator extends GenericUDAFEvaluator { + + // Iterate 输入 + private PrimitiveObjectInspector inputOICipherText; + // Merge 输入 + private StructObjectInspector structOI; + + private BinaryObjectInspector sumFieldOI; + + private StructField sumField; + + // TerminatePartial 输出 + private Object[] partialResult; + + // Terminate 输出 + private Text result; + + // 中间结果 + static class PaillierSumBuffer implements AggregationBuffer { + byte[] sum; + } + + @Override + public ObjectInspector init(Mode mode, ObjectInspector[] parameters) throws HiveException { + super.init(mode, parameters); + // 初始化输入参数类型 + if (mode == Mode.PARTIAL1 || mode == Mode.COMPLETE) { + inputOICipherText = (PrimitiveObjectInspector) parameters[0]; + } else { + // Struct + structOI = (StructObjectInspector) parameters[0]; + sumField = structOI.getStructFieldRef("sum"); + sumFieldOI = (BinaryObjectInspector) sumField.getFieldObjectInspector(); + } + // 初始化输出类型 + if (mode == Mode.PARTIAL1 || mode == Mode.PARTIAL2) { + // 输出类型 + if (partialResult == null) { + partialResult = new Object[1]; + partialResult[0] = new BytesWritable(); + } + // 输出OI + // 字段类型 + ArrayList objectInspectors = new ArrayList(); + objectInspectors.add(PrimitiveObjectInspectorFactory.writableBinaryObjectInspector); + // 字段名称 + ArrayList fieldNames = new ArrayList(); + fieldNames.add("sum"); + return ObjectInspectorFactory.getStandardStructObjectInspector( + fieldNames, objectInspectors); + + } else { + result = new Text(); + return PrimitiveObjectInspectorFactory.writableStringObjectInspector; + } + } + + @Override + public AggregationBuffer getNewAggregationBuffer() throws HiveException { + PaillierSumBuffer buffer = new PaillierSumBuffer(); + reset(buffer); + return buffer; + } + + @Override + public void reset(AggregationBuffer agg) throws HiveException { + PaillierSumBuffer buffer = (PaillierSumBuffer) agg; + buffer.sum = null; + } + + @Override + public void iterate(AggregationBuffer agg, Object[] parameters) throws HiveException { + try { + if (parameters[0] != null) { + PaillierSumBuffer buffer = (PaillierSumBuffer) agg; + String cipherText = + PrimitiveObjectInspectorUtils.getString( + parameters[0], inputOICipherText); + byte[] cipherTextBytes = DatatypeConverter.parseHexBinary(cipherText); + if (buffer.sum == null) { + buffer.sum = cipherTextBytes; + } else { + buffer.sum = + NativeFloatingPointPaillier.add( + buffer.sum, cipherTextBytes, publicKeyPointer); + } + } + } catch (JniException e) { + logger.error("PaillierSumUDAFEvaluator iterate error", e); + throw new HiveException(e); + } catch (Exception e) { + logger.error("PaillierSumUDAFEvaluator iterate error", e); + throw new HiveException(e); + } + } + + // 输出部分聚合结果 + @Override + public Object terminatePartial(AggregationBuffer agg) throws HiveException { + PaillierSumBuffer buffer = (PaillierSumBuffer) agg; + if (buffer.sum == null) { + return null; + } + ((BytesWritable) partialResult[0]).set(new BytesWritable(buffer.sum)); + return partialResult; + } + + // 合并 + @Override + public void merge(AggregationBuffer agg, Object partialResult) throws HiveException { + PaillierSumBuffer buffer = (PaillierSumBuffer) agg; + if (partialResult == null) { + return; + } + // 通过StandardStructObjectInspector实例,分解出 partialResult 数组元素值 + Object partialSum = structOI.getStructFieldData(partialResult, sumField); + try { + // 通过基本数据类型的OI 实例解析 Object 的值 + byte[] sum = sumFieldOI.getPrimitiveJavaObject(partialSum); + if (buffer.sum == null) { + buffer.sum = sum; + } else { + buffer.sum = NativeFloatingPointPaillier.add(buffer.sum, sum, publicKeyPointer); + } + } catch (JniException e) { + logger.error("PaillierSumUDAFEvaluator merge error", e); + throw new HiveException(e); + } + } + + // 输出最终聚合结果 + @Override + public Object terminate(AggregationBuffer agg) throws HiveException { + PaillierSumBuffer buffer = (PaillierSumBuffer) agg; + if (buffer.sum == null) { + return null; + } + if (result == null) { + result = new Text(); + } + result.set(DatatypeConverter.printHexBinary(buffer.sum)); + return result; + } + } +} diff --git a/cpp/wedpr-crypto/ppc-udf/hive/src/main/java/com/webank/wedpr/hive/udf/impl/symmetric/SymDecryptionUDF.java b/cpp/wedpr-crypto/ppc-udf/hive/src/main/java/com/webank/wedpr/hive/udf/impl/symmetric/SymDecryptionUDF.java new file mode 100644 index 00000000..fa08563b --- /dev/null +++ b/cpp/wedpr-crypto/ppc-udf/hive/src/main/java/com/webank/wedpr/hive/udf/impl/symmetric/SymDecryptionUDF.java @@ -0,0 +1,73 @@ +/** + * Copyright 2023 [wedpr] + * + *

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. + */ +package com.webank.wedpr.hive.udf.impl.symmetric; + +import com.webank.wedpr.hive.udf.config.ConfigLoader; +import com.webank.wedpr.hive.udf.config.model.KeyConfig; +import com.webank.wedpr.hive.udf.exceptions.DecryptionException; +import com.webank.wedpr.sdk.jni.crypto.SymmetricEncryption; +import javax.xml.bind.DatatypeConverter; +import org.apache.commons.codec.Charsets; +import org.apache.hadoop.hive.ql.exec.Description; +import org.apache.hadoop.hive.ql.exec.UDF; +import org.apache.log4j.Logger; + +/** @author caryliao 2023/11/1 */ +@Description( + name = "sym_dec", + value = "decrypt symmetric cipher to plain value", + extended = + "Usage:sym_dec(columnName, algorithmType, mode, hexIv, hexSk) \n" + + "algorithmType(0:AES_128, 1:AES_192, 2:AES_256, 3:TrippleDES, 4:SM4), mode(0:ECB, 1:CBC, 2:CFB, 3:OFB, 4:CTR)\n" + + "Example:select sym_dec(encrypted_name, 0, 0,'303132...', 'ce73b0...') as user_name from t_user") +public class SymDecryptionUDF extends UDF { + private static final Logger logger = Logger.getLogger(SymDecryptionUDF.class.getName()); + + public String evaluate(final String hexCipher) { + KeyConfig keyConfig = ConfigLoader.config.getKeyConfig(); + return evaluate( + hexCipher, + SymmetricEncryption.AlgorithmType.AES_256.ordinal(), + SymmetricEncryption.OperationMode.CBC.ordinal(), + keyConfig.getAesIv(), + keyConfig.getAesPrivateKey()); + } + /* @param hexCipher + * @param algorithmType + * @param mode + * @param hexIv + * @param hexSk + * @return + */ + public String evaluate( + final String hexCipher, int algorithmType, int mode, String hexIv, String hexSk) { + try { + if (hexCipher == null) { + return null; + } + return new String( + SymmetricEncryption.decrypt( + algorithmType, + mode, + DatatypeConverter.parseHexBinary(hexSk), + DatatypeConverter.parseHexBinary(hexIv), + DatatypeConverter.parseHexBinary(hexCipher)), + Charsets.UTF_8) + .trim(); + } catch (Exception e) { + logger.error("Sym Decrypt fail ", e); + throw new DecryptionException("Sym Decrypt jni fail ", e); + } + } +} diff --git a/cpp/wedpr-crypto/ppc-udf/hive/src/main/java/com/webank/wedpr/hive/udf/impl/symmetric/SymEncryptionUDF.java b/cpp/wedpr-crypto/ppc-udf/hive/src/main/java/com/webank/wedpr/hive/udf/impl/symmetric/SymEncryptionUDF.java new file mode 100644 index 00000000..a6e67656 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-udf/hive/src/main/java/com/webank/wedpr/hive/udf/impl/symmetric/SymEncryptionUDF.java @@ -0,0 +1,83 @@ +/** + * Copyright 2023 [wedpr] + * + *

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. + */ +package com.webank.wedpr.hive.udf.impl.symmetric; + +import com.webank.wedpr.hive.udf.config.ConfigLoader; +import com.webank.wedpr.hive.udf.config.model.KeyConfig; +import com.webank.wedpr.hive.udf.exceptions.EncryptionException; +import com.webank.wedpr.sdk.jni.common.JniException; +import com.webank.wedpr.sdk.jni.crypto.SymmetricEncryption; +import javax.xml.bind.DatatypeConverter; +import org.apache.commons.codec.Charsets; +import org.apache.commons.codec.binary.Hex; +import org.apache.hadoop.hive.ql.exec.Description; +import org.apache.hadoop.hive.ql.exec.UDF; +import org.apache.log4j.Logger; + +@Description( + name = "sym_enc", + value = "encrypt the plain-text into hex-cipher-data", + extended = + "Usage:sym_enc(columnName, algorithmType, mode, hexIv, hexSk) \n" + + "algorithmType(0:AES_128, 1:AES_192, 2:AES_256, 3:TrippleDES, 4:SM4), mode(0:ECB, 1:CBC, 2:CFB, 3:OFB, 4:CTR)\n" + + "Example: " + + "from t_user1 t1" + + "insert into t_user partition(dt=\"20231011\") select sym_enc(t1.id, 0, 0,'303132...', 'ce73b0...'),... ") +public class SymEncryptionUDF extends UDF { + private static final Logger logger = Logger.getLogger(SymEncryptionUDF.class.getName()); + + public String evaluate(final String plainData) { + KeyConfig keyConfig = ConfigLoader.config.getKeyConfig(); + return evaluate( + plainData, + SymmetricEncryption.AlgorithmType.AES_256.ordinal(), + SymmetricEncryption.OperationMode.CBC.ordinal(), + keyConfig.getAesIv(), + keyConfig.getAesPrivateKey()); + } + + public String evaluate( + final String plainData, + int algorithmType, + int mode, + String hexIv, + String hexPrivateKey) { + if (plainData == null) { + return null; + } + if (hexPrivateKey == null) { + logger.warn("Invalid empty private key"); + return plainData; + } + try { + return Hex.encodeHexString( + SymmetricEncryption.encrypt( + algorithmType, + mode, + DatatypeConverter.parseHexBinary(hexPrivateKey), + DatatypeConverter.parseHexBinary(hexIv), + plainData.getBytes(Charsets.UTF_8))) + .trim(); + } catch (JniException e) { + logger.warn( + "Symmetric Encryption exception, algorithm: " + + algorithmType + + " , mode: " + + mode + + ", exception: " + + e); + throw new EncryptionException("Symmetric Encryption exception", e); + } + } +} diff --git a/cpp/wedpr-crypto/ppc-udf/hive/src/main/resources/config.toml b/cpp/wedpr-crypto/ppc-udf/hive/src/main/resources/config.toml new file mode 100644 index 00000000..39e1b909 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-udf/hive/src/main/resources/config.toml @@ -0,0 +1,7 @@ +[keys] +aes_sk = "AEAC6BCB142F8945E57935D1506E3A9D" +aes_iv = "0123456789" +ore_sk = "A9F524FC2BC9CDCCC6C76EC26238D5E4" +ihc_sk = "436BBF943B43449B16BE19D90ED558F5" +paillier_sk = "000008000101006EFDA25C7DF1F497DBEEA2F08ADFD030066A4BC0ABD9905FA128BDFC81780D2936EAC40299B93F222675C75B0C57107EA034744C352C2B3EC07D2943A974A1F602A0AAA7FC382E6F0AFFFC4B878F007D80FDF03028502416D8FCABBED033EBFDF0A3EE552D41F167E52F1CFEE4990CDD003FF582CF18D095CB71A0212B80DB9D73A8451F5491F7F34CA523222CCBF5CB9FC2753D45C5CE327F3D9DDCC5E79C57BC956B4E84214CC37B048AD631F1DFA9EC0CCFACF16FD5B5EC804CCBBC46449CFFBE7D8DCA9577E643814389EFFEE62D8F4320D9E246CFB3B20464B74014A2FFFBBA0223514CBE479620A0F8D941DECB19B46497EA0B8CBBBDB42C0C0AE75432008100E8219B3E57789D4EC59D133446132F5B1697D5134F0B24967E5C99A63740F6904F159ED8AE4C59421C053E0225EBDB1929CD7A9D2B43FB86D02C8DADEE8F5570AFA2D5A2D0842832A1CB233CF0CE3F699FE8F29CE1326DA91AD02156E7E076A5B6CB2EB6F4B9828F4AA37D23F9D2772FD41634CDCC43DE94EC2401E3D31C5DFF008100F4CE7D67EC0992CAC78169EC32180EFC8E99C0DED88C1332E29B2895EC4F59B0339D335694F93A8262F2A48A9AFC1F8F7E9142F834761E3AA9FAE910C298CAF4B5D4A972BFB44A5CFF66814EE4785231BAE80DDCB65F7FF6B807D31CB12FE3901274019DDBD17BD9E257F5496D81F2B602BDB17FF1055B460B3D2946CD757DCF" +paillier_pk = "00000800010100DDFB44B8FBE3E92FB7DD45E115BFA0600CD4978157B320BF42517BF902F01A526DD5880533727E444CEB8EB618AE20FD4068E8986A58567D80FA528752E943EC0541554FF8705CDE15FFF8970F1E00FB01FBE06050A0482DB1F9577DA067D7FBE147DCAA5A83E2CFCA5E39FDC93219BA007FEB059E31A12B96E340425701B73CC440A2E4ECA620002668C364D1C329EEE4B6806CB322D42E5F72FDF5AF5F88EFFBDDA8CC4B882D4B7500F83924CBB9FC80785CEF4299C52D5328105629B4A99F64F47A312563625C28342B9FB5445DF67957422D5C1F8D0736E0BDE21939A035C0B3349B73247AF8593CB45F19D8277C0A3CAF7D9160535272C98342B66084310201FF0E06E2102360C675C143D2E0543D7A35FE8A9169368ADDE79082AD93E6EB62495A751FB46CAFE23C5990FE1BD8EDF894AB049A1970B6BD6E2B48BA3DD68ADE3FB916BDACB9948CDC03168E30EB9819A8A341AB4B5FFD9276388303F5771271AFFEEC2C3D9BED3354DF51971AC5E0EDB62A5F0796E29FB48C8DDB47B184F183CAD9751A22303D4D1C7415390B9F4E4954C226DAD2935801C64F605E3DE12607469408FEAEA3BC6AA277E2811EFBA39C50931B8D665CC35AF4D2E8A4DC62DE6B5087991AAB5C64ED389C66CF2096C4870F8BF893E73891F0E263F2181DB2B89C5F10A4D8C16FDE25FAFFF744B3517A3F13D3E3E0C9DD96F59775236E4986C19677813FB3914338F51620E8679C7CA64BAFF1C7C6CD0216874FF82EC403AE7A47FBD542724E49F2897A7CCA5F7D2340C946534BD45BB483EE56244BE5E61FBF669DB7024151E33D60AB50E44BBA9DD91584E67409F7240EAC4234D8AD6D2FD2CF41C81E3BEB894D593177B8DC162B77694FEBDDA2248E6603BF11DCF1C963F870F1A35767179E3112DED335E9D187B0A197667C47628B4718A326D754F6415B4A6F1DC4F99EFCFEA9A5F99DF56C9BB911825B7AF7308FF0BF595EB1B6E60FA864B73F3C8E82247567867470737BC1431FF5808B00B52C2A025D741E72A94594285BEBE9986C1A0FB13606C00F7CC6061EE141BEEE3E2DA9E740C4C23EC1FB778440" \ No newline at end of file diff --git a/cpp/wedpr-crypto/ppc-udf/hive/src/test/java/com/webank/wedpr/hive/udf/impl/IhcEncAndDecUDFTest.java b/cpp/wedpr-crypto/ppc-udf/hive/src/test/java/com/webank/wedpr/hive/udf/impl/IhcEncAndDecUDFTest.java new file mode 100644 index 00000000..84df8b3e --- /dev/null +++ b/cpp/wedpr-crypto/ppc-udf/hive/src/test/java/com/webank/wedpr/hive/udf/impl/IhcEncAndDecUDFTest.java @@ -0,0 +1,60 @@ +package com.webank.wedpr.hive.udf.impl; + +import java.math.BigDecimal; +import javax.xml.bind.DatatypeConverter; + +import com.webank.wedpr.hive.udf.impl.ihc.IhcDecryptionUDF; +import com.webank.wedpr.hive.udf.impl.ihc.IhcEncryptionUDF; +import org.apache.hadoop.io.Text; +import org.junit.Assert; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.webank.wedpr.hive.udf.impl.ihc.IhcDecryptionUDF; +import com.webank.wedpr.hive.udf.impl.ihc.IhcEncryptionUDF; +import com.webank.wedpr.sdk.jni.common.JniException; +import com.webank.wedpr.sdk.jni.homo.NativeFloatingIhc; + +/** + * @author caryliao + * @date 2023/11/29 + */ + +public class IhcEncAndDecUDFTest { + private static final Logger logger = LoggerFactory.getLogger(IhcEncAndDecUDFTest.class); + + public void testEncAndDecEvaluateImpl(int mode) throws JniException { + IhcEncryptionUDF ihcEncUDF = new IhcEncryptionUDF();; + int keyBits = 64; + String plainValue = "10000"; + String hexSk = "1F272ECA7DED4105"; + int iterRound = 16; + String cipherValue = ihcEncUDF.evaluate(mode, hexSk, plainValue); + System.out.println("cipherValue:" + cipherValue); + + IhcDecryptionUDF ihcDecUDF = new IhcDecryptionUDF(); + String decryptValueStr = ihcDecUDF.evaluate(mode, hexSk, cipherValue); + System.out.println("decryptValueStr:" + decryptValueStr); + BigDecimal decryptValue = new BigDecimal(decryptValueStr); + System.out.println("decryptValue:" + decryptValue); + byte[] cipherValueBytes = DatatypeConverter.parseHexBinary(cipherValue); + byte[] cipherValueSum = cipherValueBytes; + int addRound = 10; + long startTime = System.currentTimeMillis(); + for (int i = 0; i < addRound - 1; i++) { + cipherValueSum = NativeFloatingIhc.add(mode, cipherValueSum, cipherValueBytes); + } + long endTime = System.currentTimeMillis(); + System.out.println("NativeIhc.add cost time(ms):" + (endTime - startTime)); + String decryptValueSumStr = ihcDecUDF.evaluate(mode, hexSk, DatatypeConverter.printHexBinary(cipherValueSum)); + System.out.println("decryptValueSumStr:" + decryptValueSumStr); + Assert.assertTrue(new BigDecimal(plainValue).compareTo(decryptValue) == 0); + } + + @Test + public void testEncAndDecEvaluate() throws JniException { + testEncAndDecEvaluateImpl(NativeFloatingIhc.mode.IHC_256.ordinal()); + testEncAndDecEvaluateImpl(NativeFloatingIhc.mode.IHC_128.ordinal()); + } +} diff --git a/cpp/wedpr-crypto/ppc-udf/hive/src/test/java/com/webank/wedpr/hive/udf/impl/IhcSumUDAFTest.java b/cpp/wedpr-crypto/ppc-udf/hive/src/test/java/com/webank/wedpr/hive/udf/impl/IhcSumUDAFTest.java new file mode 100644 index 00000000..06dbe2c1 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-udf/hive/src/test/java/com/webank/wedpr/hive/udf/impl/IhcSumUDAFTest.java @@ -0,0 +1,78 @@ +package com.webank.wedpr.hive.udf.impl; + +import java.math.BigDecimal; + +import com.webank.wedpr.hive.udf.impl.ihc.IhcDecryptionUDF; +import com.webank.wedpr.hive.udf.impl.ihc.IhcEncryptionUDF; +import com.webank.wedpr.hive.udf.impl.ihc.IhcSumUDAF; +import com.webank.wedpr.sdk.jni.common.JniException; +import com.webank.wedpr.sdk.jni.homo.NativeFloatingIhc; +import org.apache.hadoop.hive.ql.metadata.HiveException; +import org.apache.hadoop.hive.ql.udf.generic.GenericUDAFEvaluator; +import org.apache.hadoop.hive.ql.udf.generic.GenericUDAFParameterInfo; +import org.apache.hadoop.hive.ql.udf.generic.SimpleGenericUDAFParameterInfo; +import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector; +import org.apache.hadoop.hive.serde2.objectinspector.primitive.JavaConstantStringObjectInspector; +import org.apache.hadoop.io.Text; +import org.junit.Assert; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import com.webank.wedpr.hive.udf.impl.ihc.IhcDecryptionUDF; +import com.webank.wedpr.hive.udf.impl.ihc.IhcEncryptionUDF; +import com.webank.wedpr.hive.udf.impl.ihc.IhcSumUDAF; + +import javax.xml.bind.DatatypeConverter; + +/** + * @author caryliao + * @date 2023/11/30 + */ + +public class IhcSumUDAFTest { + private static final Logger logger = LoggerFactory.getLogger(IhcSumUDAFTest.class); + + @Test + public void testIhcSumUDAFEvaluate() throws HiveException, JniException + { + //testIhcSumUDAFEvaluateImpl(NativeFloatingIhc.mode.IHC_256.ordinal()); + testIhcSumUDAFEvaluateImpl(NativeFloatingIhc.mode.IHC_128.ordinal()); + } + + public void testIhcSumUDAFEvaluateImpl(int mode) throws HiveException, JniException { + IhcEncryptionUDF ihcEncUDF = new IhcEncryptionUDF(); + String plainValue1 = "111.11"; + String plainValue2 = "222.22"; + String hexSk = DatatypeConverter.printHexBinary(NativeFloatingIhc.generateKey(mode)); + String cipherValue1 = ihcEncUDF.evaluate(mode, hexSk, plainValue1); + String cipherValue2 = ihcEncUDF.evaluate(mode, hexSk, plainValue2); + System.out.println("cipherValue1:" + cipherValue1); + System.out.println("cipherValue2:" + cipherValue2); + + IhcSumUDAF ihcSumUDAF = new IhcSumUDAF(); + JavaConstantStringObjectInspector stringObjectInspector = new JavaConstantStringObjectInspector(cipherValue1); + ObjectInspector[] params = {stringObjectInspector}; + GenericUDAFParameterInfo parameterInfo = new SimpleGenericUDAFParameterInfo(params, false, false, false); + GenericUDAFEvaluator evaluator = ihcSumUDAF.getEvaluator(parameterInfo); + evaluator.init(GenericUDAFEvaluator.Mode.PARTIAL1, params); + GenericUDAFEvaluator.AggregationBuffer agg = evaluator.getNewAggregationBuffer(); + Object[] iterateParams1 = {cipherValue1}; + evaluator.iterate(agg, iterateParams1); + evaluator.init(GenericUDAFEvaluator.Mode.PARTIAL1, params); + Object[] iterateParams2 = {cipherValue2}; + evaluator.iterate(agg, iterateParams2); + Text result = (Text) evaluator.terminate(agg); + System.out.println("result:" + result.toString()); + + long startTime = System.nanoTime(); + IhcDecryptionUDF ihcDecUDF = new IhcDecryptionUDF(); + String sumValueStr = ihcDecUDF.evaluate(mode, hexSk, result.toString()); + BigDecimal sumValue = new BigDecimal(sumValueStr); + long endTime = System.nanoTime(); + System.out.println("paillierSumUDF cost time(ns):" + (endTime - startTime)); + System.out.println("sumValue:" + sumValue); + Assert.assertTrue(new BigDecimal("333.33").compareTo(sumValue) == 0);; + } + +} + diff --git a/cpp/wedpr-crypto/ppc-udf/hive/src/test/java/com/webank/wedpr/hive/udf/impl/OreDecUDFTest.java b/cpp/wedpr-crypto/ppc-udf/hive/src/test/java/com/webank/wedpr/hive/udf/impl/OreDecUDFTest.java new file mode 100644 index 00000000..e09d5f1e --- /dev/null +++ b/cpp/wedpr-crypto/ppc-udf/hive/src/test/java/com/webank/wedpr/hive/udf/impl/OreDecUDFTest.java @@ -0,0 +1,138 @@ +package com.webank.wedpr.hive.udf.impl; +import java.nio.charset.StandardCharsets; + +import javax.xml.bind.DatatypeConverter; + +import com.webank.wedpr.hive.udf.exceptions.DecryptionException; +import com.webank.wedpr.hive.udf.impl.ore.OreDecryptionUDF; +import com.webank.wedpr.hive.udf.impl.ore.OreEncryptionUDF; +import com.webank.wedpr.hive.udf.impl.ore.OreNumberDecryptionUDF; +import com.webank.wedpr.hive.udf.impl.ore.OreNumberEncryptionUDF; +import com.webank.wedpr.sdk.jni.codec.NumberCodec; +import com.webank.wedpr.sdk.jni.codec.NumberCodecImpl; +import org.apache.commons.codec.Charsets; +import org.apache.commons.codec.binary.Hex; +import org.junit.Assert; +import org.junit.Test; + +import com.webank.wedpr.sdk.jni.common.JniException; +import com.webank.wedpr.sdk.jni.crypto.FastOre; + +/** + * @author caryliao + */ + +public class OreDecUDFTest { + + @Test + public void testOREDecUDFEvaluate() throws JniException { + String plainValue = "19014527865"; + String hexSk = "267C74CB4AFF39E0D59CB177CA5E495A"; + byte[] bytesSk = DatatypeConverter.parseHexBinary(hexSk); + byte[] bytesCipher = FastOre.encrypt4String(bytesSk, plainValue.getBytes(StandardCharsets.UTF_8), true); + System.out.println("hexCipher: " + new String(bytesCipher)); + + OreDecryptionUDF oreDecUDF = new OreDecryptionUDF(); + long startTime = System.nanoTime(); + String decryptValueStr = oreDecUDF.evaluate(new String(bytesCipher), hexSk); + long endTime = System.nanoTime(); + System.out.println("OREDecUDF cost time(ns):" + (endTime - startTime)); + System.out.println("decryptValueStr:" + decryptValueStr); + Assert.assertEquals(plainValue,decryptValueStr); + } + + public void testOREDecUDFEvaluateImpl2(String plainValue, String hexSk, byte[] cipher){ + OreDecryptionUDF oreDecUDF = new OreDecryptionUDF(); + String decryptValueStr = oreDecUDF.evaluate(new String(cipher), hexSk); + System.out.println("decryptValueStr:" + decryptValueStr); + System.out.println("##### decryptValueStr: " + decryptValueStr); + System.out.println("##### plainValue:" + plainValue); + Assert.assertEquals(plainValue, decryptValueStr); + } + + public void checkInvalidCase( String hexSk, byte[] cipher) + { + OreDecryptionUDF oreDecUDF = new OreDecryptionUDF(); + Assert.assertThrows(DecryptionException.class, ()-> oreDecUDF.evaluate(new String(cipher), hexSk)); + } + + @Test + public void testOREDecUDFEvaluate3() throws JniException{ + String plainValue = "456_world"; + String hexSk = "267C74CB4AFF39E0D59CB177CA5E495A"; + testOreEncDecImpl(plainValue, hexSk); + + plainValue = "202.103.123.99"; + String cipher = "af067bca0937b7420a60e45de9831bd5b70ae0f950b6d748c470da10"; + testOREDecUDFEvaluateImpl2(plainValue, hexSk, cipher.getBytes(Charsets.UTF_8)); + plainValue = "192.168.19.12"; + cipher = "af05856a300f0bee890821b3a560af45b537a7e561b606252eed"; + testOREDecUDFEvaluateImpl2(plainValue, hexSk, cipher.getBytes(Charsets.UTF_8)); + + checkInvalidCase("abc", cipher.getBytes(Charsets.UTF_8)); + cipher = "abcwsd"; + checkInvalidCase(hexSk, cipher.getBytes(Charsets.UTF_8)); + } + + public void testOreEncDecImpl(String plainData, String hexSk) { + OreEncryptionUDF oreEncUDF = new OreEncryptionUDF(); + OreDecryptionUDF oreDecUDF = new OreDecryptionUDF(); + + String tmpCipher = ""; + for (int i = 0; i < 10; i++) + { + String cipher = oreEncUDF.evaluate(plainData, hexSk); + if(i >=1) + { + Assert.assertEquals(cipher, tmpCipher); + } + tmpCipher = cipher; + String plain = oreDecUDF.evaluate(cipher, hexSk); + Assert.assertEquals(plain, plainData); + } + } + + @Test + public void testOreEncDecEvaluate() throws JniException + { + byte[] sk = FastOre.generateKey(); + String hexSk = Hex.encodeHexString(sk); + testOreEncDecImpl("abc", hexSk); + testOreEncDecImpl("中国werw34#$%546!!@3中国中文", hexSk); + testOreEncDecImpl("192.168.19.12", hexSk); + testOreEncDecImpl("202.103.123.99", hexSk); + } + + + public void testOreNumberEncDecImpl(String plainData) { + OreNumberEncryptionUDF oreEncUDF = new OreNumberEncryptionUDF(); + OreNumberDecryptionUDF oreDecUDF = new OreNumberDecryptionUDF(); + + String tmpCipher = ""; + for (int i = 0; i < 10; i++) + { + String cipher = oreEncUDF.evaluate(plainData); + if(i >=1) + { + Assert.assertEquals(cipher, tmpCipher); + } + tmpCipher = cipher; + String plain = oreDecUDF.evaluate(cipher); + System.out.println("#### plain: " + plain); + System.out.println("#### plainData: " + plainData); + Assert.assertEquals(plain, plainData); + } + } + + @Test + public void testOreNumberEncDecEvaluate() throws JniException + { + testOreNumberEncDecImpl("12332432423.23432444444444"); + testOreNumberEncDecImpl("-12332432423.23432444444444"); + testOreNumberEncDecImpl("12332432423"); + testOreNumberEncDecImpl("-12332432423"); + testOreNumberEncDecImpl("0"); + testOreNumberEncDecImpl("0.000000000000000000000000000000001"); + testOreNumberEncDecImpl("-0.000000000000000000000000000000001"); + } +} diff --git a/cpp/wedpr-crypto/ppc-udf/hive/src/test/java/com/webank/wedpr/hive/udf/impl/PaillierDecUDFTest.java b/cpp/wedpr-crypto/ppc-udf/hive/src/test/java/com/webank/wedpr/hive/udf/impl/PaillierDecUDFTest.java new file mode 100644 index 00000000..84773780 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-udf/hive/src/test/java/com/webank/wedpr/hive/udf/impl/PaillierDecUDFTest.java @@ -0,0 +1,41 @@ +package com.webank.wedpr.hive.udf.impl; + +import java.math.BigDecimal; + +import com.webank.wedpr.hive.udf.impl.paillier.PaillierDecryptionUDF; +import com.webank.wedpr.hive.udf.impl.paillier.PaillierEncryptionUDF; +import com.webank.wedpr.sdk.jni.homo.NativeFloatingPointPaillier; +import org.apache.hadoop.io.Text; +import org.junit.Assert; +import org.junit.Test; + +/** + * @author caryliao + */ + +public class PaillierDecUDFTest { + @Test + public void testPaillierDecryptionUDFEvaluate() { + String plain = "1600.7568000000001120497472584247589111328125"; + PaillierEncryptionUDF paillierEncryptionUDF = new PaillierEncryptionUDF(); + Text hexCipher = paillierEncryptionUDF.evaluate(new Text(plain)); + + PaillierDecryptionUDF paillierDecUDF = new PaillierDecryptionUDF(); + long startTime = System.nanoTime(); + String decryptValueStr = + paillierDecUDF.evaluate(hexCipher); + long endTime = System.nanoTime(); + System.out.println("paillierDecUDF cost time(ns):" + (endTime - startTime)); + String decryptValueStr2 = + paillierDecUDF.evaluate(hexCipher); + System.out.println("decryptValueStr:" + decryptValueStr); + System.out.println("decryptValueStr2:" + decryptValueStr2); + BigDecimal decryptValue = new BigDecimal(decryptValueStr); + BigDecimal decryptValue2 = new BigDecimal(decryptValueStr2); + System.out.println("##### decryptValue: " + decryptValueStr); + System.out.println("##### decryptValue2: " + decryptValueStr2); + Assert.assertTrue(new BigDecimal(plain).compareTo(decryptValue) == 0); + Assert.assertTrue(new BigDecimal(plain).compareTo(decryptValue2) == 0); + } + +} diff --git a/cpp/wedpr-crypto/ppc-udf/hive/src/test/java/com/webank/wedpr/hive/udf/impl/PaillierEncUDFTest.java b/cpp/wedpr-crypto/ppc-udf/hive/src/test/java/com/webank/wedpr/hive/udf/impl/PaillierEncUDFTest.java new file mode 100644 index 00000000..a35fa3b4 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-udf/hive/src/test/java/com/webank/wedpr/hive/udf/impl/PaillierEncUDFTest.java @@ -0,0 +1,46 @@ +package com.webank.wedpr.hive.udf; + +import java.math.BigDecimal; + +import com.webank.wedpr.hive.udf.impl.paillier.PaillierDecryptionUDF; +import com.webank.wedpr.hive.udf.impl.paillier.PaillierEncryptionUDF; +import org.apache.hadoop.io.Text; +import org.junit.Assert; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.webank.wedpr.hive.udf.impl.paillier.PaillierDecryptionUDF; +import com.webank.wedpr.hive.udf.impl.paillier.PaillierEncryptionUDF; + +/** + * @author caryliao + * @date 2023/12/02 + */ + +public class PaillierEncUDFTest { + private static final Logger logger = LoggerFactory.getLogger(PaillierEncUDFTest.class); + + @Test + public void testPaillierDecryptionUDFEvaluate() { + String plainValue = "1000.123"; + PaillierEncryptionUDF paillierEncUDF = new PaillierEncryptionUDF(); + PaillierDecryptionUDF paillierDecUDF = new PaillierDecryptionUDF(); + String hexPublicKey = + "00000800010100E74CF4A6DD95032412678A2702C6B1C158F0DC94F72191311DC8FA3A2608AAC2F287D3BE7D2583EE7F042B1DBC42C8FE149669D4A36A77A49956D9DFC83DCBD38AB03F7324CB5071EEED8C7FAE108BA4C79639CAFEB4FF96A87EFAAB4580F8CDFCD9FC55BAD63AF2B27BF84B568348228ED7CE8A16A1220CB323301D7F4475A7BAB747477D9056CF9D1FDDE6EBDF4D94814B4A530FB84CC34E36AD0E8DCA220F7E354B4C471B699B155A3463C8A74DE5E824897F519A4BBF01E11FD3F62A349B0604003FB6BC00C1C25173AF4FA610B760114CC55BB92A4173B90A52DE2009C5B18F86725A27B6DA19ED60BD208C5F1875E151CD8DA8D689543C50347A23ED5D0201FF0D6877B3378C46D2839EEF71C78042F99218C2C3E6A3EEB741BAD372E2B5B7FFA222BEBA5C3C18A1B3E4AC890F5AFBAE460607A558743738D11E53EDFA00A54D209A0F52410576ACDD2F28D448B3E48F054A066BEEFA61207E29BB0BDC1EA1EA1B674A94D63D72CC57C55F8250E3EB01F1A4AD42FA14F9EAF92D880CF279DFF50A2AD6FD062B026886FF23BBE310EA1E324BF83B6860A864BD9E28B5DBE5D01173E090827262A65FA7EB0729860808DE9DEB9B2D17B0EABCB3699635EB5B4676AA7E7C533F361FDBE578DA114C6771EEE97894291796A03F1519C77ADBF8697741E48E1DC8E0B15667B617631155E88D9D6781B0FC2D26BD9A121620B2A65ACD099FE494BD887021759E7A16AAA570C881964DF67152E7D578A1751E09B11461A1ACF5FDAEFEAC5410BC5970BE924E56551F7763FD293669F24FAE322931DACDB27A6A865E0F5875A5C26082A329CEDEA47A5F2776DFD2144389AB5EC5358CFAB44B481851ED03292AB79B3E59EF0B0CB8DCE7CEE102E5E0A7597150B297FFEFFF80ED684C1CC5A0DE369EC2B636F1F9B41F4372B4AF662C71F89F0AD456595423CE4B3A38E5998CBB5EA096C9AFAABD9B48DE8BC5819F95C47E7576CAC92CADC4E00175252D6BFD1C5D585442AD5C4285A6878DE9A65D425AF3B61359D9B39C1427923CEB5B82B1CFBF4941DA0454746CD79E30912998A6407F34C29713C210"; + String hexPrivateKey = + "0000080001010073A67A536ECA81920933C513816358E0AC786E4A7B90C8988EE47D1D130455617943E9DF3E92C1F73F82158EDE21647F0A4B34EA51B53BD24CAB6CEFE41EE5E9C5581FB99265A838F776C63FD70845D263CB1CE57F5A7FCB543F7D55A2C07C66FE6CFE2ADD6B1D79593DFC25AB41A411476BE7450B5091065991980EBFA23AD2E9B9754B13E1E9AE0BC19C51CAEC71C1C9CD71F0232D3FED74C35F3D8A370CF85AED749E4E37E306B9CF5823A1F4257A536AF45983E85B171D2BB8E9A60ECABC53AA9C90D370DC05D348144C44E519FC397465EDA930FC4EA84D942E8B80D5C766E817790C6B1BBDECBEECFA30A966E9013302F8C9E28FE30292857F38951F8E008100FFA5C3FBECCA8C8EE0336C384A7CDFB8996480E432AF757624A8B24509DB56529C86A64B933E79649C54E8AE4059BF7EFE675B3678924497A866CEBAB68AC8331FE95A72FE494D5B99CD5BE8343C187DC00F788DF1D6263FEE4C09D99DA58AF004CBAA2EA523B92AB0C2935D92DB203ABB4BE46389A7CF0A55E8F56B0B0188CB008100E79E98B56901F6E4A569390B0B898A58544BE58E96AE577240073C4E6F80B1CC2BD3BBC4176D2A2905669B6E4465437242E74595D13750F91F22DF45F381D6EF3EC56CAB1190FB5A81F3EF2E919FC4412D19085C17810B6434D1D81C2978D346DEF3AD519C2DC6338FACF36B2C5E710BB82F6778703BE7B8F92E4FCAFDF82577"; + long startTime1 = System.nanoTime(); + Text cipherValue = paillierEncUDF.evaluate(new Text(plainValue)); + System.out.println("cipherValue:" + cipherValue.toString()); + long endTime1 = System.nanoTime(); + System.out.println("paillierEncUDF cost time(ns):" + (endTime1 - startTime1)); + long startTime2 = System.nanoTime(); + String decryptValueStr = paillierDecUDF.evaluate(cipherValue).toString(); + long endTime2 = System.nanoTime(); + System.out.println("paillierDecUDF cost time(ns):" + (endTime2 - startTime2)); + System.out.println("decryptValueStr:" + decryptValueStr); + Assert.assertTrue(new BigDecimal(plainValue).compareTo(new BigDecimal(decryptValueStr)) == 0);; + } + +} diff --git a/cpp/wedpr-crypto/ppc-udf/hive/src/test/java/com/webank/wedpr/hive/udf/impl/PaillierSumUDAFTest.java b/cpp/wedpr-crypto/ppc-udf/hive/src/test/java/com/webank/wedpr/hive/udf/impl/PaillierSumUDAFTest.java new file mode 100644 index 00000000..8f6e6123 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-udf/hive/src/test/java/com/webank/wedpr/hive/udf/impl/PaillierSumUDAFTest.java @@ -0,0 +1,61 @@ +package com.webank.wedpr.hive.udf.impl; + +import java.math.BigDecimal; + +import com.webank.wedpr.hive.udf.impl.paillier.PaillierDecryptionUDF; +import com.webank.wedpr.hive.udf.impl.paillier.PaillierEncryptionUDF; +import com.webank.wedpr.hive.udf.impl.paillier.PaillierSumUDAF; +import org.apache.hadoop.hive.ql.metadata.HiveException; +import org.apache.hadoop.hive.ql.udf.generic.GenericUDAFEvaluator; +import org.apache.hadoop.hive.ql.udf.generic.GenericUDAFParameterInfo; +import org.apache.hadoop.hive.ql.udf.generic.SimpleGenericUDAFParameterInfo; +import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector; +import org.apache.hadoop.hive.serde2.objectinspector.primitive.JavaConstantStringObjectInspector; +import org.apache.hadoop.io.Text; +import org.junit.Assert; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author caryliao + * 2023/11/9 + */ + +public class PaillierSumUDAFTest { + private static final Logger logger = LoggerFactory.getLogger(PaillierSumUDAFTest.class); + + @Test + public void testPaillierSumUDAFEvaluate() throws HiveException { + PaillierDecryptionUDF paillierDecUDF = new PaillierDecryptionUDF(); + PaillierEncryptionUDF encryptionUDF = new PaillierEncryptionUDF(); + String plain = "1232324234.34353543"; + Text cipher = encryptionUDF.evaluate(new Text(plain)); + + PaillierSumUDAF paillierSumUDAF = new PaillierSumUDAF(); + JavaConstantStringObjectInspector stringObjectInspector1 = new JavaConstantStringObjectInspector(cipher.toString()); + ObjectInspector[] params1 = {stringObjectInspector1}; + ObjectInspector[] params2 = {stringObjectInspector1}; + GenericUDAFParameterInfo parameterInfo = new SimpleGenericUDAFParameterInfo(params1, false, false, false); + GenericUDAFEvaluator evaluator = paillierSumUDAF.getEvaluator(parameterInfo); + evaluator.init(GenericUDAFEvaluator.Mode.PARTIAL1, params1); + + GenericUDAFEvaluator.AggregationBuffer agg = evaluator.getNewAggregationBuffer(); + String[] iterateParams1 = {cipher.toString()}; + evaluator.iterate(agg, iterateParams1); + evaluator.init(GenericUDAFEvaluator.Mode.PARTIAL1, params2); + String[] iterateParams2 = {cipher.toString()}; + evaluator.iterate(agg, iterateParams2); + Text result = (Text) evaluator.terminate(agg); + System.out.println("result:" + result.toString()); + + String decryptValueStr = paillierDecUDF.evaluate(new Text(result)).toString(); + System.out.println("###### decryptValueStr: " + decryptValueStr); + BigDecimal decryptValue = new BigDecimal(decryptValueStr); + BigDecimal m = new BigDecimal(plain); + BigDecimal expectedV = m.add(m); + Assert.assertTrue(decryptValue.compareTo(expectedV) == 0); + } + +} + diff --git a/cpp/wedpr-crypto/ppc-udf/hive/src/test/java/com/webank/wedpr/hive/udf/impl/SymDecUDFTest.java b/cpp/wedpr-crypto/ppc-udf/hive/src/test/java/com/webank/wedpr/hive/udf/impl/SymDecUDFTest.java new file mode 100644 index 00000000..7dc8f5a6 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-udf/hive/src/test/java/com/webank/wedpr/hive/udf/impl/SymDecUDFTest.java @@ -0,0 +1,68 @@ +package com.webank.wedpr.hive.udf.impl; + +import java.nio.charset.StandardCharsets; + +import javax.xml.bind.DatatypeConverter; + +import com.webank.wedpr.hive.udf.exceptions.DecryptionException; +import com.webank.wedpr.hive.udf.impl.symmetric.SymDecryptionUDF; +import org.junit.Assert; +import org.junit.Test; + +import com.webank.wedpr.sdk.jni.common.JniException; +import com.webank.wedpr.sdk.jni.crypto.SymmetricEncryption; + +/** + * @author caryliao + * @ 2023/11/1 + */ + +public class SymDecUDFTest { + @Test + public void testSymDecUDFEvaluate() throws JniException { + doTest(SymmetricEncryption.AlgorithmType.AES_128, SymmetricEncryption.OperationMode.ECB); + long startTime = System.nanoTime(); + doTest(SymmetricEncryption.AlgorithmType.AES_128, SymmetricEncryption.OperationMode.CTR); + long endTime = System.nanoTime(); + System.out.println("AES_128 CTR cost time(ns):" + (endTime - startTime)); + doTest(SymmetricEncryption.AlgorithmType.AES_192, SymmetricEncryption.OperationMode.CBC); + doTest(SymmetricEncryption.AlgorithmType.AES_256, SymmetricEncryption.OperationMode.OFB); + doTest(SymmetricEncryption.AlgorithmType.AES_256, SymmetricEncryption.OperationMode.CFB); + doTest(SymmetricEncryption.AlgorithmType.AES_256, SymmetricEncryption.OperationMode.CTR); + + doTest(SymmetricEncryption.AlgorithmType.TrippleDES, SymmetricEncryption.OperationMode.ECB); + doTest(SymmetricEncryption.AlgorithmType.TrippleDES, SymmetricEncryption.OperationMode.CBC); + doTest(SymmetricEncryption.AlgorithmType.TrippleDES, SymmetricEncryption.OperationMode.OFB); + doTest(SymmetricEncryption.AlgorithmType.TrippleDES, SymmetricEncryption.OperationMode.CFB); + + doTest(SymmetricEncryption.AlgorithmType.SM4, SymmetricEncryption.OperationMode.ECB); + doTest(SymmetricEncryption.AlgorithmType.SM4, SymmetricEncryption.OperationMode.CBC); + doTest(SymmetricEncryption.AlgorithmType.SM4, SymmetricEncryption.OperationMode.OFB); + doTest(SymmetricEncryption.AlgorithmType.SM4, SymmetricEncryption.OperationMode.CFB); + doTest(SymmetricEncryption.AlgorithmType.SM4, SymmetricEncryption.OperationMode.CTR); + } + + private void doTest(SymmetricEncryption.AlgorithmType algorithmType, + SymmetricEncryption.OperationMode operationMode) throws JniException { + String hexIv = "30313233343536373839616263646566"; + String hexSk = "8ff6bbbd8b5f79091cbf8e4676b7ff81"; + byte[] bytesIv = DatatypeConverter.parseHexBinary(hexIv); + byte[] bytesSk = DatatypeConverter.parseHexBinary(hexSk); + String plainValue = "caryliao"; + byte[] bytesCipher = SymmetricEncryption.encrypt(algorithmType.ordinal(), operationMode.ordinal(), bytesSk, + bytesIv, plainValue.getBytes(StandardCharsets.UTF_8)); + String hexCipher = DatatypeConverter.printHexBinary(bytesCipher); + System.out.println("hexCipher:" + hexCipher); + + SymDecryptionUDF symDecUDF = new SymDecryptionUDF(); + String decryptValueStr = + symDecUDF.evaluate(hexCipher, algorithmType.ordinal(), operationMode.ordinal(), hexIv, hexSk); + System.out.println("decryptValueStr:" + decryptValueStr); + Assert.assertTrue(plainValue.equals(decryptValueStr)); + + // evaluate with invalid cipher + Assert.assertThrows(DecryptionException.class, + () -> symDecUDF.evaluate("abc1wer", algorithmType.ordinal(), operationMode.ordinal(), hexIv, hexSk)); + } + +} diff --git a/cpp/wedpr-crypto/ppc-udf/hive/src/test/java/com/webank/wedpr/hive/udf/impl/SymEncryptionUDFTest.java b/cpp/wedpr-crypto/ppc-udf/hive/src/test/java/com/webank/wedpr/hive/udf/impl/SymEncryptionUDFTest.java new file mode 100644 index 00000000..f57de858 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-udf/hive/src/test/java/com/webank/wedpr/hive/udf/impl/SymEncryptionUDFTest.java @@ -0,0 +1,172 @@ +/** + * Copyright 2023 [wedpr] + * + *

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. + */ + +package com.webank.wedpr.hive.udf.impl; + +import com.webank.wedpr.hive.udf.impl.symmetric.SymDecryptionUDF; +import com.webank.wedpr.hive.udf.impl.symmetric.SymEncryptionUDF; +import com.webank.wedpr.sdk.jni.common.JniException; +import com.webank.wedpr.sdk.jni.crypto.SymmetricEncryption; +import org.apache.commons.codec.binary.Hex; +import org.junit.Assert; +import org.junit.Test; + +public class SymEncryptionUDFTest +{ +public String testSymmetricEncryptionUDFEvaluateImpl(String plainValue, int algorithmType, int mode, String hexIv, String hexPrivateKey) +{ + SymEncryptionUDF symEncryptionUDF = new SymEncryptionUDF(); + String cipher = symEncryptionUDF.evaluate(plainValue, algorithmType, mode, hexIv, hexPrivateKey); + // decrypt + SymDecryptionUDF symDecUDF = new SymDecryptionUDF(); + String decodedPlain = symDecUDF.evaluate(cipher, algorithmType, mode, hexIv, hexPrivateKey); + Assert.assertTrue(decodedPlain.equals(plainValue)); + return cipher; +} + +public void checkDeterministic(String plainValue, int algorithmType, int mode, String hexPrivateKey, String hexIv) +{ + String cipher = ""; + for(int i = 0; i < 20; i++) { + String currentCipher = testSymmetricEncryptionUDFEvaluateImpl(plainValue, algorithmType, mode, hexIv, hexPrivateKey); + if(i >= 1) + { + Assert.assertTrue(currentCipher.equals(cipher)); + } + cipher = currentCipher; + } +} + +@Test +public void testSymmetricEncryptionUDFEvaluate() throws JniException { + String hexIv = "AABBCC"; + // sm4-ctr + byte[] privateKey = SymmetricEncryption.generateKey(SymmetricEncryption.AlgorithmType.SM4.ordinal(), SymmetricEncryption.OperationMode.CTR.ordinal()); + String hexPrivateKey = Hex.encodeHexString(privateKey); + testSymmetricEncryptionUDFEvaluateImpl("abc", SymmetricEncryption.AlgorithmType.SM4.ordinal(), SymmetricEncryption.OperationMode.CTR.ordinal(), hexPrivateKey, hexIv); + testSymmetricEncryptionUDFEvaluateImpl("中文abc@#@$中文@Sf中国", SymmetricEncryption.AlgorithmType.SM4.ordinal(), SymmetricEncryption.OperationMode.CTR.ordinal(), hexPrivateKey, hexIv); + // sm4-cbc + privateKey = SymmetricEncryption.generateKey(SymmetricEncryption.AlgorithmType.SM4.ordinal(), SymmetricEncryption.OperationMode.CBC.ordinal()); + hexPrivateKey = Hex.encodeHexString(privateKey); + // check deterministic for cbc mode + checkDeterministic("中文abc@#@$中文@Sf中国", SymmetricEncryption.AlgorithmType.SM4.ordinal(), SymmetricEncryption.OperationMode.CBC.ordinal(), hexPrivateKey, hexIv); + // sm4-cfb + privateKey = SymmetricEncryption.generateKey(SymmetricEncryption.AlgorithmType.SM4.ordinal(), SymmetricEncryption.OperationMode.CFB.ordinal()); + hexPrivateKey = Hex.encodeHexString(privateKey); + testSymmetricEncryptionUDFEvaluateImpl("中文abc@#@$中文@Sf中国", SymmetricEncryption.AlgorithmType.SM4.ordinal(), SymmetricEncryption.OperationMode.CFB.ordinal(), hexPrivateKey, hexIv); + //sm4-ecb + privateKey = SymmetricEncryption.generateKey(SymmetricEncryption.AlgorithmType.SM4.ordinal(), SymmetricEncryption.OperationMode.ECB.ordinal()); + hexPrivateKey = Hex.encodeHexString(privateKey); + testSymmetricEncryptionUDFEvaluateImpl("中文abc@#@$中文@Sf中国", SymmetricEncryption.AlgorithmType.SM4.ordinal(), SymmetricEncryption.OperationMode.ECB.ordinal(), hexPrivateKey, hexIv); + // sm4-ofb + privateKey = SymmetricEncryption.generateKey(SymmetricEncryption.AlgorithmType.SM4.ordinal(), SymmetricEncryption.OperationMode.OFB.ordinal()); + hexPrivateKey = Hex.encodeHexString(privateKey); + testSymmetricEncryptionUDFEvaluateImpl("中文abc@#@$中文@Sf中国", SymmetricEncryption.AlgorithmType.SM4.ordinal(), SymmetricEncryption.OperationMode.OFB.ordinal(), hexPrivateKey, hexIv); + + // AES-128-ctr + privateKey = SymmetricEncryption.generateKey(SymmetricEncryption.AlgorithmType.AES_128.ordinal(), SymmetricEncryption.OperationMode.CTR.ordinal()); + hexPrivateKey = Hex.encodeHexString(privateKey); + testSymmetricEncryptionUDFEvaluateImpl("中文abc@#@$中文@Sf中国", SymmetricEncryption.AlgorithmType.AES_128.ordinal(), SymmetricEncryption.OperationMode.CTR.ordinal(), hexPrivateKey, hexIv); + + // AES-128-ofb + privateKey = SymmetricEncryption.generateKey(SymmetricEncryption.AlgorithmType.AES_128.ordinal(), SymmetricEncryption.OperationMode.OFB.ordinal()); + hexPrivateKey = Hex.encodeHexString(privateKey); + testSymmetricEncryptionUDFEvaluateImpl("中文abc@#@$中文@Sf中国", SymmetricEncryption.AlgorithmType.AES_128.ordinal(), SymmetricEncryption.OperationMode.OFB.ordinal(), hexPrivateKey, hexIv); + + // AES-128-cfb + privateKey = SymmetricEncryption.generateKey(SymmetricEncryption.AlgorithmType.AES_128.ordinal(), SymmetricEncryption.OperationMode.CFB.ordinal()); + hexPrivateKey = Hex.encodeHexString(privateKey); + testSymmetricEncryptionUDFEvaluateImpl("中文abc@#@$中文@Sf中国", SymmetricEncryption.AlgorithmType.AES_128.ordinal(), SymmetricEncryption.OperationMode.CFB.ordinal(), hexPrivateKey, hexIv); + + // AES-128-ecb + privateKey = SymmetricEncryption.generateKey(SymmetricEncryption.AlgorithmType.AES_128.ordinal(), SymmetricEncryption.OperationMode.ECB.ordinal()); + hexPrivateKey = Hex.encodeHexString(privateKey); + testSymmetricEncryptionUDFEvaluateImpl("中文abc@#@$中文@Sf中国", SymmetricEncryption.AlgorithmType.AES_128.ordinal(), SymmetricEncryption.OperationMode.ECB.ordinal(), hexPrivateKey, hexIv); + + // AES-128-cbc + privateKey = SymmetricEncryption.generateKey(SymmetricEncryption.AlgorithmType.AES_128.ordinal(), SymmetricEncryption.OperationMode.CBC.ordinal()); + hexPrivateKey = Hex.encodeHexString(privateKey); + checkDeterministic("中文abc@#@$中文@Sf中国", SymmetricEncryption.AlgorithmType.AES_128.ordinal(), SymmetricEncryption.OperationMode.CBC.ordinal(), hexPrivateKey, hexIv); + + // AES-192-ofb + privateKey = SymmetricEncryption.generateKey(SymmetricEncryption.AlgorithmType.AES_192.ordinal(), SymmetricEncryption.OperationMode.OFB.ordinal()); + hexPrivateKey = Hex.encodeHexString(privateKey); + testSymmetricEncryptionUDFEvaluateImpl("中文abc@#@$中文@Sf中国", SymmetricEncryption.AlgorithmType.AES_192.ordinal(), SymmetricEncryption.OperationMode.OFB.ordinal(), hexPrivateKey, hexIv); + + // AES-192-ctr + privateKey = SymmetricEncryption.generateKey(SymmetricEncryption.AlgorithmType.AES_192.ordinal(), SymmetricEncryption.OperationMode.CTR.ordinal()); + hexPrivateKey = Hex.encodeHexString(privateKey); + testSymmetricEncryptionUDFEvaluateImpl("中文abc@#@$中文@Sf中国", SymmetricEncryption.AlgorithmType.AES_192.ordinal(), SymmetricEncryption.OperationMode.CTR.ordinal(), hexPrivateKey, hexIv); + + // AES-192-cfb + privateKey = SymmetricEncryption.generateKey(SymmetricEncryption.AlgorithmType.AES_192.ordinal(), SymmetricEncryption.OperationMode.CFB.ordinal()); + hexPrivateKey = Hex.encodeHexString(privateKey); + testSymmetricEncryptionUDFEvaluateImpl("中文abc@#@$中文@Sf中国", SymmetricEncryption.AlgorithmType.AES_192.ordinal(), SymmetricEncryption.OperationMode.CFB.ordinal(), hexPrivateKey, hexIv); + + // AES-192-ecb + privateKey = SymmetricEncryption.generateKey(SymmetricEncryption.AlgorithmType.AES_192.ordinal(), SymmetricEncryption.OperationMode.ECB.ordinal()); + hexPrivateKey = Hex.encodeHexString(privateKey); + testSymmetricEncryptionUDFEvaluateImpl("中文abc@#@$中文@Sf中国", SymmetricEncryption.AlgorithmType.AES_192.ordinal(), SymmetricEncryption.OperationMode.ECB.ordinal(), hexPrivateKey, hexIv); + + // AES-192-cbc + privateKey = SymmetricEncryption.generateKey(SymmetricEncryption.AlgorithmType.AES_192.ordinal(), SymmetricEncryption.OperationMode.CBC.ordinal()); + hexPrivateKey = Hex.encodeHexString(privateKey); + checkDeterministic("中文abc@#@$中文@Sf中国", SymmetricEncryption.AlgorithmType.AES_192.ordinal(), SymmetricEncryption.OperationMode.CBC.ordinal(), hexPrivateKey, hexIv); + + // AES-256-ctr + privateKey = SymmetricEncryption.generateKey(SymmetricEncryption.AlgorithmType.AES_256.ordinal(), SymmetricEncryption.OperationMode.CTR.ordinal()); + hexPrivateKey = Hex.encodeHexString(privateKey); + testSymmetricEncryptionUDFEvaluateImpl("中文abc@#@$中文@Sf中国", SymmetricEncryption.AlgorithmType.AES_256.ordinal(), SymmetricEncryption.OperationMode.CTR.ordinal(), hexPrivateKey, hexIv); + + // AES-256-ofb + privateKey = SymmetricEncryption.generateKey(SymmetricEncryption.AlgorithmType.AES_256.ordinal(), SymmetricEncryption.OperationMode.OFB.ordinal()); + hexPrivateKey = Hex.encodeHexString(privateKey); + testSymmetricEncryptionUDFEvaluateImpl("中文abc@#@$中文@Sf中国", SymmetricEncryption.AlgorithmType.AES_256.ordinal(), SymmetricEncryption.OperationMode.OFB.ordinal(), hexPrivateKey, hexIv); + + // AES-256-cfb + privateKey = SymmetricEncryption.generateKey(SymmetricEncryption.AlgorithmType.AES_256.ordinal(), SymmetricEncryption.OperationMode.CFB.ordinal()); + hexPrivateKey = Hex.encodeHexString(privateKey); + testSymmetricEncryptionUDFEvaluateImpl("中文abc@#@$中文@Sf中国", SymmetricEncryption.AlgorithmType.AES_256.ordinal(), SymmetricEncryption.OperationMode.CFB.ordinal(), hexPrivateKey, hexIv); + + // AES-256-ecb + privateKey = SymmetricEncryption.generateKey(SymmetricEncryption.AlgorithmType.AES_256.ordinal(), SymmetricEncryption.OperationMode.ECB.ordinal()); + hexPrivateKey = Hex.encodeHexString(privateKey); + testSymmetricEncryptionUDFEvaluateImpl("中文abc@#@$中文@Sf中国", SymmetricEncryption.AlgorithmType.AES_256.ordinal(), SymmetricEncryption.OperationMode.ECB.ordinal(), hexPrivateKey, hexIv); + + // AES-256-cbc + privateKey = SymmetricEncryption.generateKey(SymmetricEncryption.AlgorithmType.AES_256.ordinal(), SymmetricEncryption.OperationMode.CBC.ordinal()); + hexPrivateKey = Hex.encodeHexString(privateKey); + checkDeterministic("中文abc@#@$中文@Sf中国", SymmetricEncryption.AlgorithmType.AES_256.ordinal(), SymmetricEncryption.OperationMode.CBC.ordinal(), hexPrivateKey, hexIv); + + // 3des-cfb + privateKey = SymmetricEncryption.generateKey(SymmetricEncryption.AlgorithmType.TrippleDES.ordinal(), SymmetricEncryption.OperationMode.CFB.ordinal()); + hexPrivateKey = Hex.encodeHexString(privateKey); + testSymmetricEncryptionUDFEvaluateImpl("中文abc@#@$中文@Sf中国", SymmetricEncryption.AlgorithmType.TrippleDES.ordinal(), SymmetricEncryption.OperationMode.CFB.ordinal(), hexPrivateKey, hexIv); + + // 3des-ofb + privateKey = SymmetricEncryption.generateKey(SymmetricEncryption.AlgorithmType.TrippleDES.ordinal(), SymmetricEncryption.OperationMode.OFB.ordinal()); + hexPrivateKey = Hex.encodeHexString(privateKey); + testSymmetricEncryptionUDFEvaluateImpl("中文abc@#@$中文@Sf中国", SymmetricEncryption.AlgorithmType.TrippleDES.ordinal(), SymmetricEncryption.OperationMode.OFB.ordinal(), hexPrivateKey, hexIv); + + // 3des-ofb + privateKey = SymmetricEncryption.generateKey(SymmetricEncryption.AlgorithmType.TrippleDES.ordinal(), SymmetricEncryption.OperationMode.ECB.ordinal()); + hexPrivateKey = Hex.encodeHexString(privateKey); + testSymmetricEncryptionUDFEvaluateImpl("中文abc@#@$中文@Sf中国", SymmetricEncryption.AlgorithmType.TrippleDES.ordinal(), SymmetricEncryption.OperationMode.ECB.ordinal(), hexPrivateKey, hexIv); + + // 3des-cbc + privateKey = SymmetricEncryption.generateKey(SymmetricEncryption.AlgorithmType.TrippleDES.ordinal(), SymmetricEncryption.OperationMode.CBC.ordinal()); + hexPrivateKey = Hex.encodeHexString(privateKey); + checkDeterministic("中文abc@#@$中文@Sf中国", SymmetricEncryption.AlgorithmType.TrippleDES.ordinal(), SymmetricEncryption.OperationMode.CBC.ordinal(), hexPrivateKey, hexIv); +} +} \ No newline at end of file diff --git a/cpp/wedpr-crypto/ppc-udf/hive/src/test/resources/config.toml b/cpp/wedpr-crypto/ppc-udf/hive/src/test/resources/config.toml new file mode 100644 index 00000000..39e1b909 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-udf/hive/src/test/resources/config.toml @@ -0,0 +1,7 @@ +[keys] +aes_sk = "AEAC6BCB142F8945E57935D1506E3A9D" +aes_iv = "0123456789" +ore_sk = "A9F524FC2BC9CDCCC6C76EC26238D5E4" +ihc_sk = "436BBF943B43449B16BE19D90ED558F5" +paillier_sk = "000008000101006EFDA25C7DF1F497DBEEA2F08ADFD030066A4BC0ABD9905FA128BDFC81780D2936EAC40299B93F222675C75B0C57107EA034744C352C2B3EC07D2943A974A1F602A0AAA7FC382E6F0AFFFC4B878F007D80FDF03028502416D8FCABBED033EBFDF0A3EE552D41F167E52F1CFEE4990CDD003FF582CF18D095CB71A0212B80DB9D73A8451F5491F7F34CA523222CCBF5CB9FC2753D45C5CE327F3D9DDCC5E79C57BC956B4E84214CC37B048AD631F1DFA9EC0CCFACF16FD5B5EC804CCBBC46449CFFBE7D8DCA9577E643814389EFFEE62D8F4320D9E246CFB3B20464B74014A2FFFBBA0223514CBE479620A0F8D941DECB19B46497EA0B8CBBBDB42C0C0AE75432008100E8219B3E57789D4EC59D133446132F5B1697D5134F0B24967E5C99A63740F6904F159ED8AE4C59421C053E0225EBDB1929CD7A9D2B43FB86D02C8DADEE8F5570AFA2D5A2D0842832A1CB233CF0CE3F699FE8F29CE1326DA91AD02156E7E076A5B6CB2EB6F4B9828F4AA37D23F9D2772FD41634CDCC43DE94EC2401E3D31C5DFF008100F4CE7D67EC0992CAC78169EC32180EFC8E99C0DED88C1332E29B2895EC4F59B0339D335694F93A8262F2A48A9AFC1F8F7E9142F834761E3AA9FAE910C298CAF4B5D4A972BFB44A5CFF66814EE4785231BAE80DDCB65F7FF6B807D31CB12FE3901274019DDBD17BD9E257F5496D81F2B602BDB17FF1055B460B3D2946CD757DCF" +paillier_pk = "00000800010100DDFB44B8FBE3E92FB7DD45E115BFA0600CD4978157B320BF42517BF902F01A526DD5880533727E444CEB8EB618AE20FD4068E8986A58567D80FA528752E943EC0541554FF8705CDE15FFF8970F1E00FB01FBE06050A0482DB1F9577DA067D7FBE147DCAA5A83E2CFCA5E39FDC93219BA007FEB059E31A12B96E340425701B73CC440A2E4ECA620002668C364D1C329EEE4B6806CB322D42E5F72FDF5AF5F88EFFBDDA8CC4B882D4B7500F83924CBB9FC80785CEF4299C52D5328105629B4A99F64F47A312563625C28342B9FB5445DF67957422D5C1F8D0736E0BDE21939A035C0B3349B73247AF8593CB45F19D8277C0A3CAF7D9160535272C98342B66084310201FF0E06E2102360C675C143D2E0543D7A35FE8A9169368ADDE79082AD93E6EB62495A751FB46CAFE23C5990FE1BD8EDF894AB049A1970B6BD6E2B48BA3DD68ADE3FB916BDACB9948CDC03168E30EB9819A8A341AB4B5FFD9276388303F5771271AFFEEC2C3D9BED3354DF51971AC5E0EDB62A5F0796E29FB48C8DDB47B184F183CAD9751A22303D4D1C7415390B9F4E4954C226DAD2935801C64F605E3DE12607469408FEAEA3BC6AA277E2811EFBA39C50931B8D665CC35AF4D2E8A4DC62DE6B5087991AAB5C64ED389C66CF2096C4870F8BF893E73891F0E263F2181DB2B89C5F10A4D8C16FDE25FAFFF744B3517A3F13D3E3E0C9DD96F59775236E4986C19677813FB3914338F51620E8679C7CA64BAFF1C7C6CD0216874FF82EC403AE7A47FBD542724E49F2897A7CCA5F7D2340C946534BD45BB483EE56244BE5E61FBF669DB7024151E33D60AB50E44BBA9DD91584E67409F7240EAC4234D8AD6D2FD2CF41C81E3BEB894D593177B8DC162B77694FEBDDA2248E6603BF11DCF1C963F870F1A35767179E3112DED335E9D187B0A197667C47628B4718A326D754F6415B4A6F1DC4F99EFCFEA9A5F99DF56C9BB911825B7AF7308FF0BF595EB1B6E60FA864B73F3C8E82247567867470737BC1431FF5808B00B52C2A025D741E72A94594285BEBE9986C1A0FB13606C00F7CC6061EE141BEEE3E2DA9E740C4C23EC1FB778440" \ No newline at end of file diff --git a/cpp/wedpr-crypto/ppc-udf/mysql/ore_dec.cpp b/cpp/wedpr-crypto/ppc-udf/mysql/ore_dec.cpp new file mode 100644 index 00000000..a97eb109 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-udf/mysql/ore_dec.cpp @@ -0,0 +1,119 @@ +/** + * Copyright (C) 2022 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 ore_dec.cpp + * @author: caryliao + * @date 2023-10-26 + */ +#include "ore_dec.h" +#include "ppc-crypto-c-sdk/fast_ore.h" +#include "ppc-crypto-c-sdk/utils/error.h" +#include "ppc-crypto-c-sdk/utils/utilities.h" +#include "ppc-framework/libwrapper/Buffer.h" +#include +#include +#include + +using namespace std; + +bool isHexInDec = true; +struct OreDecData { + InputBuffer oreSk; + char* oreDecryptResult = NULL; +}; + +// eg:ore_dec(columnName, sk) +my_bool ore_dec_init(UDF_INIT* initid, UDF_ARGS* args, char* message) +{ + if (args->arg_count != 2) + { + const char* errorMsg = + "\nUsage:ore_dec(columnName, hexSk)" + "\nExample:select ore_dec(encrypted_name, '303132...') as user_name from t_user"; + snprintf(message, max_msg_size, "%s", errorMsg); + return 1; + } + + if (args->arg_type[0] != STRING_RESULT || args->arg_type[1] != STRING_RESULT) + { + snprintf(message, max_msg_size, "%s", "ore_dec() requires (string, string) as parameter types"); + return 1; + } + uint64_t skBytesLen = args->lengths[1] / 2; + unsigned char* skBytesData = (unsigned char*)malloc(skBytesLen); + if (!skBytesData) + { + snprintf(message, max_msg_size, "%s", "allocate memory for sk failed"); + return 1; + } + OutputBuffer skBytesBuffer = {skBytesData, skBytesLen}; + InputBuffer skHexBuffer = {(const unsigned char*)args->args[1], args->lengths[1]}; + from_hex(&skBytesBuffer, &skHexBuffer); + if (get_last_error() != 0) + { + snprintf(message, max_msg_size, "%s", "invalid hexSk"); + return 1; + } + OreDecData* oreDataPtr = new OreDecData; + initid->ptr = (char*)oreDataPtr; + oreDataPtr->oreSk.data = skBytesBuffer.data; + oreDataPtr->oreSk.len = skBytesBuffer.len; + oreDataPtr->oreDecryptResult = (char*)malloc(fast_ore_get_plain_size(args->lengths[0] / 2, isHexInDec)); + if (!oreDataPtr->oreDecryptResult) + { + snprintf(message, max_msg_size, "%s", "malloc memory for oreDecryptResult failed!"); + return 1; + } + + return 0; +} + +void ore_dec_deinit(UDF_INIT* initid) +{ + if (initid->ptr) + { + OreDecData* oreDataPtr = (OreDecData*)initid->ptr; + if (oreDataPtr->oreSk.data) + { + free((void*)oreDataPtr->oreSk.data); + oreDataPtr->oreSk.data = NULL; + } + if (oreDataPtr->oreDecryptResult) + { + free(oreDataPtr->oreDecryptResult); + oreDataPtr->oreDecryptResult = NULL; + } + free(initid->ptr); + initid->ptr = NULL; + } +} + +char* ore_dec(UDF_INIT* initid, UDF_ARGS* args, char* result, unsigned long* length, char* is_null, + char* error) +{ + InputBuffer ciphertext = {(const unsigned char*)args->args[0], args->lengths[0]}; + OreDecData* oreDataPtr = (OreDecData*)initid->ptr; + // ore_decrypt + OutputBuffer plainBuffer = { + (unsigned char*)oreDataPtr->oreDecryptResult, fast_ore_get_plain_size(ciphertext.len, isHexInDec)}; + string_fast_ore_decrypt(&plainBuffer, &oreDataPtr->oreSk, &ciphertext, isHexInDec); + if (get_last_error() != 0) + { + snprintf(error, max_msg_size, "%s", "decrypt ore cipher failed"); + return NULL; + }; + *length = plainBuffer.len; + return oreDataPtr->oreDecryptResult; +} diff --git a/cpp/wedpr-crypto/ppc-udf/mysql/ore_dec.h b/cpp/wedpr-crypto/ppc-udf/mysql/ore_dec.h new file mode 100644 index 00000000..11719e46 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-udf/mysql/ore_dec.h @@ -0,0 +1,42 @@ +/** + * Copyright (C) 2022 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 ore_dec.h + * @author: caryliao + * @date 2023-10-26 + */ + +#ifndef __PAILLIER_DECRYPT_H__ +#define __PAILLIER_DECRYPT_H__ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +my_bool ore_dec_init(UDF_INIT* initid, UDF_ARGS* args, char* message); + +void ore_dec_deinit(UDF_INIT* initid); + +// Note: every row data will trigger this function +char* ore_dec(UDF_INIT* initid, UDF_ARGS* args, char* result, unsigned long* length, + char* is_null, char* error); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/cpp/wedpr-crypto/ppc-udf/mysql/ore_enc.cpp b/cpp/wedpr-crypto/ppc-udf/mysql/ore_enc.cpp new file mode 100644 index 00000000..789eaed7 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-udf/mysql/ore_enc.cpp @@ -0,0 +1,119 @@ +/** + * Copyright (C) 2022 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 ore_enc.cpp + * @author: caryliao + * @date 2023-11-30 + */ +#include "ore_enc.h" +#include "ppc-crypto-c-sdk/fast_ore.h" +#include "ppc-crypto-c-sdk/utils/error.h" +#include "ppc-crypto-c-sdk/utils/utilities.h" +#include "ppc-framework/libwrapper/Buffer.h" +#include +#include +#include + +using namespace std; + +bool isHexInEnc = true; +struct OreEncData { + InputBuffer oreSk; + char* oreEncryptResult = NULL; +}; + +// eg:ore_enc(columnName, sk) +my_bool ore_enc_init(UDF_INIT* initid, UDF_ARGS* args, char* message) +{ + if (args->arg_count != 2) + { + const char* errorMsg = + "\nUsage:ore_enc(columnName, hexSk)" + "\nExample:select ore_enc(name, '303132...') as user_name from t_user"; + snprintf(message, max_msg_size, "%s", errorMsg); + return 1; + } + + if (args->arg_type[0] != STRING_RESULT || args->arg_type[1] != STRING_RESULT) + { + snprintf(message, max_msg_size, "%s", "ore_enc() requires (string, string) as parameter types"); + return 1; + } + uint64_t skBytesLen = args->lengths[1] / 2; + unsigned char* skBytesData = (unsigned char*)malloc(skBytesLen); + if (!skBytesData) + { + snprintf(message, max_msg_size, "%s", "allocate memory for sk failed"); + return 1; + } + OutputBuffer skBytesBuffer = {skBytesData, skBytesLen}; + InputBuffer skHexBuffer = {(const unsigned char*)args->args[1], args->lengths[1]}; + from_hex(&skBytesBuffer, &skHexBuffer); + if (get_last_error() != 0) + { + snprintf(message, max_msg_size, "%s", "invalid hexSk"); + return 1; + } + OreEncData* oreDataPtr = new OreEncData; + initid->ptr = (char*)oreDataPtr; + oreDataPtr->oreSk.data = skBytesBuffer.data; + oreDataPtr->oreSk.len = skBytesBuffer.len; + oreDataPtr->oreEncryptResult = (char*)malloc(fast_ore_get_cipher_size(args->lengths[0], isHexInEnc)); + if (!oreDataPtr->oreEncryptResult) + { + snprintf(message, max_msg_size, "%s", "malloc memory for oreEncryptResult failed!"); + return 1; + } + + return 0; +} + +void ore_enc_deinit(UDF_INIT* initid) +{ + if (initid->ptr) + { + OreEncData* oreDataPtr = (OreEncData*)initid->ptr; + if (oreDataPtr->oreSk.data) + { + free((void*)oreDataPtr->oreSk.data); + oreDataPtr->oreSk.data = NULL; + } + if (oreDataPtr->oreEncryptResult) + { + free(oreDataPtr->oreEncryptResult); + oreDataPtr->oreEncryptResult = NULL; + } + free(initid->ptr); + initid->ptr = NULL; + } +} + +char* ore_enc(UDF_INIT* initid, UDF_ARGS* args, char* result, unsigned long* length, char* is_null, + char* error) +{ + InputBuffer plaintext = {(const unsigned char*)args->args[0], args->lengths[0]}; + OreEncData* oreDataPtr = (OreEncData*)initid->ptr; + // ore_encrypt + OutputBuffer cipherBuffer = { + (unsigned char*)oreDataPtr->oreEncryptResult, fast_ore_get_cipher_size(plaintext.len, isHexInEnc)}; + string_fast_ore_encrypt(&cipherBuffer, &oreDataPtr->oreSk, &plaintext, isHexInEnc); + if (get_last_error() != 0) + { + snprintf(error, max_msg_size, "%s", "encrypt ore cipher failed"); + return NULL; + }; + *length = cipherBuffer.len; + return oreDataPtr->oreEncryptResult; +} diff --git a/cpp/wedpr-crypto/ppc-udf/mysql/ore_enc.h b/cpp/wedpr-crypto/ppc-udf/mysql/ore_enc.h new file mode 100644 index 00000000..2b99afd5 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-udf/mysql/ore_enc.h @@ -0,0 +1,42 @@ +/** + * Copyright (C) 2022 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 ore_enc.h + * @author: caryliao + * @date 2023-11-30 + */ + +#ifndef __PAILLIER_DECRYPT_H__ +#define __PAILLIER_DECRYPT_H__ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +my_bool ore_enc_init(UDF_INIT* initid, UDF_ARGS* args, char* message); + +void ore_enc_deinit(UDF_INIT* initid); + +// Note: every row data will trigger this function +char* ore_enc(UDF_INIT* initid, UDF_ARGS* args, char* result, unsigned long* length, + char* is_null, char* error); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/cpp/wedpr-crypto/ppc-udf/mysql/paillier_dec.cpp b/cpp/wedpr-crypto/ppc-udf/mysql/paillier_dec.cpp new file mode 100644 index 00000000..a3e7635c --- /dev/null +++ b/cpp/wedpr-crypto/ppc-udf/mysql/paillier_dec.cpp @@ -0,0 +1,160 @@ +/** + * Copyright (C) 2022 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 paillier_dec.cpp + * @author: caryliao + * @date 2023-10-24 + */ +#include "paillier_dec.h" +#include "ppc-crypto-c-sdk/floating_point_paillier.h" +#include "ppc-crypto-c-sdk/homo_paillier.h" +#include "ppc-crypto-c-sdk/utils/error.h" +#include "ppc-crypto-c-sdk/utils/utilities.h" +#include "ppc-framework/libwrapper/Buffer.h" +#include "ppc-framework/libwrapper/FloatingPointNumber.h" +#include "ppc-homo/codec/FloatingPointCodec.h" +#include +#include +#include +#include + +using namespace std; +using namespace ppc; +using namespace ppc::homo; +using namespace ppc::crypto; + +struct PaillierDecData +{ + void* keyPair = NULL; +}; + +// eg:paillier_dec(columnName, hexPk, hexSk, scale) +my_bool paillier_dec_init(UDF_INIT* initid, UDF_ARGS* args, char* message) +{ + if (args->arg_count != 4) + { + const char* errorMsg = + "\nUsage:paillier_dec(columnName, hexPk, hexSk, scale)" + "\nExample:select paillier_dec(encrypted_salary,'0000080001...', '0000821BA...', 2)"; + snprintf(message, max_msg_size, "%s", errorMsg); + return 1; + } + if (args->arg_type[0] != STRING_RESULT || args->arg_type[1] != STRING_RESULT || + args->arg_type[2] != STRING_RESULT || args->arg_type[3] != INT_RESULT) + { + snprintf(message, max_msg_size, "%s", + "paillier_dec() requires as (string, string, string, int) as parameter types"); + return 1; + } + uint64_t pkBytesLen = args->lengths[1] / 2; + uint64_t skBytesLen = args->lengths[2] / 2; + unsigned char* pkBytesData = (unsigned char*)malloc(pkBytesLen); + unsigned char* skBytesData = (unsigned char*)malloc(skBytesLen); + if (!pkBytesData) + { + snprintf(message, max_msg_size, "%s", "allocate memory for public-key failed"); + return 1; + } + if (!skBytesData) + { + snprintf(message, max_msg_size, "%s", "allocate memory for private-key failed"); + return 1; + } + OutputBuffer pkBytesBuffer = {pkBytesData, pkBytesLen}; + OutputBuffer skBytesBuffer = {skBytesData, skBytesLen}; + InputBuffer pkHexBuffer = {(const unsigned char*)args->args[1], args->lengths[1]}; + InputBuffer skHexBuffer = {(const unsigned char*)args->args[2], args->lengths[2]}; + from_hex(&pkBytesBuffer, &pkHexBuffer); + if (get_last_error() != 0) + { + snprintf( + message, max_msg_size, "%s%s", "Invalid public key! error: ", get_last_error_msg()); + return 1; + } + from_hex(&skBytesBuffer, &skHexBuffer); + if (get_last_error() != 0) + { + snprintf( + message, max_msg_size, "%s%s", "Invalid private key! error: ", get_last_error_msg()); + return 1; + } + PaillierDecData* paillierDecDataPtr = new PaillierDecData; + initid->ptr = (char*)paillierDecDataPtr; + // load the public key + InputBuffer pkBuffer = {pkBytesBuffer.data, pkBytesBuffer.len}; + // load the private key + InputBuffer skBuffer = {skBytesBuffer.data, skBytesBuffer.len}; + paillierDecDataPtr->keyPair = paillier_load_keypair(&skBuffer, &pkBuffer); + free(pkBytesData); + free(skBytesData); + if (get_last_error() != 0) + { + snprintf(message, max_msg_size, "%s%s", "Invalid key pair! error: ", get_last_error_msg()); + return 1; + } + return 0; +} + +void paillier_dec_deinit(UDF_INIT* initid) +{ + if (initid->ptr) + { + PaillierDecData* paillierDecDataPtr = (PaillierDecData*)initid->ptr; + if (paillierDecDataPtr->keyPair) + { + paillier_free_key_pair(paillierDecDataPtr->keyPair); + paillierDecDataPtr->keyPair = NULL; + } + } + free(initid->ptr); + initid->ptr = NULL; +} + +double paillier_dec(UDF_INIT* initid, UDF_ARGS* args, char* result, unsigned long* length, + char* is_null, char* error) +{ + // convert the args0 to bytes + InputBuffer hexArgs = {(const unsigned char*)args->args[0], args->lengths[0]}; + OutputBuffer bytesArgsBuffer = {(unsigned char*)args->args[0], args->lengths[0] / 2}; + from_hex(&bytesArgsBuffer, &hexArgs); + if (get_last_error() != 0) + { + snprintf(error, max_msg_size, "%s%s", "Invalid hex cipher! error: ", get_last_error_msg()); + return 1; + } + // paillier_decrypt + InputBuffer ciphertext = {(const unsigned char*)bytesArgsBuffer.data, bytesArgsBuffer.len}; + BIGNUM* decrypted_significant = BN_new(); + int16_t exponent = 0; + PaillierDecData* paillierDecDataPtr = (PaillierDecData*)initid->ptr; + floating_point_paillier_decrypt( + decrypted_significant, &exponent, &ciphertext, paillierDecDataPtr->keyPair); + if (get_last_error() != 0) + { + snprintf(error, max_msg_size, "%s%s", + "decrypt paillier cipher failed! error: ", get_last_error_msg()); + return 0; + } + int scale = *(int*)(args->args[3]); + BigNum v; + v.swap(decrypted_significant); + FloatingPointNumber floatingPointNumber(std::move(v), exponent); + auto floatingPointCodec = std::make_shared(); + float50 decryptResult = floatingPointCodec->toFloat50(floatingPointNumber); + double multiplier = pow(10.0, scale); + double finalResult = round((double)decryptResult * multiplier) / multiplier; + + return finalResult; +} diff --git a/cpp/wedpr-crypto/ppc-udf/mysql/paillier_dec.h b/cpp/wedpr-crypto/ppc-udf/mysql/paillier_dec.h new file mode 100644 index 00000000..60a0c43e --- /dev/null +++ b/cpp/wedpr-crypto/ppc-udf/mysql/paillier_dec.h @@ -0,0 +1,41 @@ +/** + * Copyright (C) 2022 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 paillier_dec.h + * @author: caryliao + * @date 2023-10-24 + */ + +#ifndef __PAILLIER_DECRYPT_H__ +#define __PAILLIER_DECRYPT_H__ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif +my_bool paillier_dec_init(UDF_INIT* initid, UDF_ARGS* args, char* message); + +void paillier_dec_deinit(UDF_INIT* initid); + +// Note: every row data will trigger this function +double paillier_dec(UDF_INIT* initid, UDF_ARGS* args, char* result, unsigned long* length, + char* is_null, char* error); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/cpp/wedpr-crypto/ppc-udf/mysql/paillier_enc.cpp b/cpp/wedpr-crypto/ppc-udf/mysql/paillier_enc.cpp new file mode 100644 index 00000000..3acf1f00 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-udf/mysql/paillier_enc.cpp @@ -0,0 +1,150 @@ +/** + * Copyright (C) 2022 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 paillier_enc.cpp + * @author: caryliao + * @date 2023-10-24 + */ +#include "paillier_enc.h" +#include "ppc-crypto-c-sdk/floating_point_paillier.h" +#include "ppc-crypto-c-sdk/homo_paillier.h" +#include "ppc-crypto-c-sdk/utils/error.h" +#include "ppc-crypto-c-sdk/utils/utilities.h" +#include "ppc-framework/libwrapper/Buffer.h" +#include "ppc-framework/libwrapper/FloatingPointNumber.h" +#include "ppc-homo/codec/FloatingPointCodec.h" +#include +#include +#include +#include + +using namespace std; +using namespace ppc; +using namespace ppc::homo; +using namespace ppc::crypto; + +struct PaillierEncData +{ + void* publicKey = NULL; + char* cipher_result; +}; + +// eg:paillier_enc(columnName, hexPk) +my_bool paillier_enc_init(UDF_INIT* initid, UDF_ARGS* args, char* message) +{ + if (args->arg_count != 2) + { + const char* errorMsg = + "\nUsage:paillier_enc(columnName, hexPk)" + "\nExample:select paillier_enc(salary,'0000080001...')"; + snprintf(message, max_msg_size, "%s", errorMsg); + return 1; + } + // TODO 使用double类型,目前没有获取到参数值,一直是0.00000 + // double plainValue = *(double*)args->args[0]; + double plainValue = strtod(args->args[0], NULL); + // std::cout << "double plainValue:" << plainValue << std::endl; + // snprintf(message, max_msg_size, "%f", plainValue); + // return 1; + if (args->arg_type[0] != STRING_RESULT || args->arg_type[1] != STRING_RESULT) + { + snprintf(message, max_msg_size, "%s", + "paillier_enc() requires as (string, string) as parameter types"); + return 1; + } + uint64_t pkBytesLen = args->lengths[1] / 2; + unsigned char* pkBytesData = (unsigned char*)malloc(pkBytesLen); + if (!pkBytesData) + { + snprintf(message, max_msg_size, "%s", "allocate memory for public-key failed"); + return 1; + } + OutputBuffer pkBytesBuffer = {pkBytesData, pkBytesLen}; + InputBuffer pkHexBuffer = {(const unsigned char*)args->args[1], args->lengths[1]}; + from_hex(&pkBytesBuffer, &pkHexBuffer); + if (get_last_error() != 0) + { + snprintf( + message, max_msg_size, "%s%s", "Invalid public key! error: ", get_last_error_msg()); + return 1; + } + PaillierEncData* paillierEncDataPtr = new PaillierEncData; + initid->ptr = (char*)paillierEncDataPtr; + // load the public key + InputBuffer pkBuffer = {pkBytesBuffer.data, pkBytesBuffer.len}; + paillierEncDataPtr->publicKey = paillier_load_public_key(&pkBuffer); + free(pkBytesData); + if (get_last_error() != 0) + { + snprintf(message, max_msg_size, "%s%s", "Invalid key pair! error: ", get_last_error_msg()); + return 1; + } + auto keyBits = paillier_key_bits_from_public_key(paillierEncDataPtr->publicKey); + auto cipherBytes = floating_point_paillier_cipher_bytes(keyBits); + initid->max_length = cipherBytes; + paillierEncDataPtr->cipher_result = (char*)malloc(initid->max_length); + if (!paillierEncDataPtr->cipher_result) + { + snprintf(message, max_msg_size, "%s", "Malloc memory for cipher_result failed!"); + return 1; + } + return 0; +} + +void paillier_enc_deinit(UDF_INIT* initid) +{ + std::cout << "#### paillier_enc_deinit" << std::endl; + if (initid->ptr) + { + PaillierEncData* paillierEncDataPtr = (PaillierEncData*)initid->ptr; + if (paillierEncDataPtr->publicKey) + { + paillier_free_public_key(paillierEncDataPtr->publicKey); + paillierEncDataPtr->publicKey = NULL; + } + if (paillierEncDataPtr->cipher_result) + { + free(paillierEncDataPtr->cipher_result); + paillierEncDataPtr->cipher_result = NULL; + } + free(initid->ptr); + } + initid->ptr = NULL; +} + +char* paillier_enc(UDF_INIT* initid, UDF_ARGS* args, char* result, unsigned long* length, + char* is_null, char* error) +{ + PaillierEncData* paillierEncDataPtr = (PaillierEncData*)initid->ptr; + float50 plainValue(args->args[0]); + auto floatingPointCodec = std::make_shared(); + auto fpn = floatingPointCodec->toFloatingPoint(std::string(args->args[0])); + int16_t exponent = fpn.exponent; + OutputBuffer cipherBuffer{ + (unsigned char*)paillierEncDataPtr->cipher_result, initid->max_length}; + floating_point_paillier_encrypt( + &cipherBuffer, fpn.value.bn().get(), exponent, paillierEncDataPtr->publicKey); + if (get_last_error() != 0) + { + const char* errorMsg = get_last_error_msg(); + snprintf(error, max_msg_size, "%s%s", "encrypt failed! error: ", errorMsg); + return NULL; + } + // OutputBuffer resultBuffer = {(unsigned char*)paillierEncDataPtr->cipher_result, + // cipherBuffer.len * 2}; InputBuffer bytesBuffer = {(unsigned char*)cipherBuffer.data, + // cipherBuffer.len}; to_hex(&resultBuffer, &bytesBuffer); + *length = initid->max_length; + return paillierEncDataPtr->cipher_result; +} diff --git a/cpp/wedpr-crypto/ppc-udf/mysql/paillier_enc.h b/cpp/wedpr-crypto/ppc-udf/mysql/paillier_enc.h new file mode 100644 index 00000000..e0021348 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-udf/mysql/paillier_enc.h @@ -0,0 +1,41 @@ +/** + * Copyright (C) 2022 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 paillier_enc.h + * @author: caryliao + * @date 2023-12-4 + */ + +#ifndef __PAILLIER_DECRYPT_H__ +#define __PAILLIER_DECRYPT_H__ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif +my_bool paillier_enc_init(UDF_INIT* initid, UDF_ARGS* args, char* message); + +void paillier_enc_deinit(UDF_INIT* initid); + +// Note: every row data will trigger this function +char* paillier_enc(UDF_INIT* initid, UDF_ARGS* args, char* result, unsigned long* length, + char* is_null, char* error); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/cpp/wedpr-crypto/ppc-udf/mysql/paillier_sum.cpp b/cpp/wedpr-crypto/ppc-udf/mysql/paillier_sum.cpp new file mode 100644 index 00000000..c8fc3f05 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-udf/mysql/paillier_sum.cpp @@ -0,0 +1,184 @@ +/** + * Copyright (C) 2022 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 paillier_sum.cpp + * @author: yujiechen + * @date 2023-08-18 + */ +#include "paillier_sum.h" +#include "ppc-crypto-c-sdk/floating_point_paillier.h" +#include "ppc-crypto-c-sdk/homo_paillier.h" +#include "ppc-crypto-c-sdk/utils/error.h" +#include "ppc-crypto-c-sdk/utils/utilities.h" +#include "ppc-framework/libwrapper/Buffer.h" +#include +#include +#include + +using namespace std; + +struct SumResult +{ + uint64_t max_cipher_bytes = 0; + void* public_key = NULL; + char* sum_result = NULL; + int64_t add_count = 0; +}; + +my_bool paillier_sum_init(UDF_INIT* initid, UDF_ARGS* args, char* message) +{ + if (args->arg_count != 2) + { + const char* errorMsg = + "invalid argument: paillier_sum requires the columnName and the publicKey, " + "e.g. paillier_sum(id, publicKey)"; + snprintf(message, max_msg_size, "%s", errorMsg); + return 1; + } + /// TODO: check the parameters + // convert the hexed public key to bytes + // TODO: decrease the overhead + uint64_t pkBytesLen = args->lengths[1] / 2; + unsigned char* pkBytesData = (unsigned char*)malloc(pkBytesLen); + if (!pkBytesData) + { + snprintf(message, max_msg_size, "%s", "allocate memory for public-key failed"); + return 1; + } + OutputBuffer pkBytesBuffer = {pkBytesData, pkBytesLen}; + InputBuffer pkHexBuffer = {(const unsigned char*)args->args[1], args->lengths[1]}; + from_hex(&pkBytesBuffer, &pkHexBuffer); + if (get_last_error() != 0) + { + snprintf( + message, max_msg_size, "%s%s", "Invalid public key! error: ", get_last_error_msg()); + return 1; + } + SumResult* resultBuffer = new SumResult; + // load the public key + InputBuffer pkBuffer = {pkBytesBuffer.data, pkBytesBuffer.len}; + resultBuffer->public_key = (void*)paillier_load_public_key(&pkBuffer); + // release the allocated memory + free(pkBytesData); + + if (!resultBuffer->public_key) + { + snprintf(message, max_msg_size, "%s%s", "Invalid public key:", get_last_error_msg()); + return 1; + } + + // allocate memory for the result + resultBuffer->max_cipher_bytes = floating_point_paillier_cipher_bytes( + paillier_key_bits_from_public_key(resultBuffer->public_key)); + initid->maybe_null = 1; + // will convert the result to hex when calling sum + initid->max_length = 2 * resultBuffer->max_cipher_bytes; + // Note: The MySQL UDF engine allocates 255 bytes as the buffer for a string return value. If + // the result fits within this limit, simply place the result into this buffer and return the + // pointer. If the result is bigger, you must use a string buffer that you have allocated. + // refer to: https://docstore.mik.ua/orelly/weblinux2/mysql/ch14_01.htm + resultBuffer->sum_result = (char*)malloc(initid->max_length); + if (!resultBuffer->sum_result) + { + snprintf(message, max_msg_size, "%s", "Malloc memory for sum_result failed!"); + return 1; + } + initid->ptr = (char*)resultBuffer; + if (!initid->ptr) + { + snprintf(message, max_msg_size, "%s", "Malloc memory for initid->ptr failed!"); + } + return 0; +} + +void paillier_sum_deinit(UDF_INIT* initid) +{ + paillier_sum_clear(initid, NULL, NULL); + if (initid->ptr) + { + delete initid->ptr; + } + initid->ptr = NULL; +} + +void paillier_sum_clear(UDF_INIT* initid, char* is_null, char* error) +{ + SumResult* result = (SumResult*)(initid->ptr); + result->add_count = 0; + result->max_cipher_bytes = 0; + if (result->public_key) + { + paillier_free_key_pair(result->public_key); + result->public_key = NULL; + } + if (result->sum_result) + { + free(result->sum_result); + result->sum_result = NULL; + } +} + +void paillier_sum_reset(UDF_INIT* initid, UDF_ARGS* args, char* is_null, char* error) +{ + paillier_sum_clear(initid, is_null, error); + paillier_sum_add(initid, args, is_null, error); +} + +void paillier_sum_add(UDF_INIT* initid, UDF_ARGS* args, char* is_null, char* error) +{ + if (args->args[0] == NULL) + { + return; + } + SumResult* resultBuffer = (SumResult*)initid->ptr; + // convert the args0 to bytes + InputBuffer hexArgs = {(const unsigned char*)args->args[0], args->lengths[0]}; + OutputBuffer bytesArgsBuffer = {(unsigned char*)args->args[0], args->lengths[0] / 2}; + from_hex(&bytesArgsBuffer, &hexArgs); + if (get_last_error() != 0) + { + snprintf(error, max_msg_size, "%s", "Invalid hex cipher!"); + return; + } + // the first add + if (0 == resultBuffer->add_count) + { + memcpy((void*)resultBuffer->sum_result, (const void*)bytesArgsBuffer.data, + bytesArgsBuffer.len); + resultBuffer->add_count++; + return; + } + // paillier_add + InputBuffer c1 = { + (const unsigned char*)resultBuffer->sum_result, resultBuffer->max_cipher_bytes}; + InputBuffer c2 = {(const unsigned char*)bytesArgsBuffer.data, bytesArgsBuffer.len}; + OutputBuffer result = { + (unsigned char*)resultBuffer->sum_result, resultBuffer->max_cipher_bytes}; + floating_point_paillier_add(&result, &c1, &c2, resultBuffer->public_key); + resultBuffer->add_count++; +} + +char* paillier_sum(UDF_INIT* initid, UDF_ARGS* args, char* result, unsigned long* length, + char* is_null, char* error) +{ + SumResult* sum_result = (SumResult*)initid->ptr; + // convert to hex + OutputBuffer resultBuffer = {(unsigned char*)sum_result->sum_result, initid->max_length}; + InputBuffer bytesBuffer = { + (unsigned char*)sum_result->sum_result, sum_result->max_cipher_bytes}; + to_hex(&resultBuffer, &bytesBuffer); + *length = resultBuffer.len; + return sum_result->sum_result; +} diff --git a/cpp/wedpr-crypto/ppc-udf/mysql/paillier_sum.h b/cpp/wedpr-crypto/ppc-udf/mysql/paillier_sum.h new file mode 100644 index 00000000..c4c67eac --- /dev/null +++ b/cpp/wedpr-crypto/ppc-udf/mysql/paillier_sum.h @@ -0,0 +1,44 @@ +/** + * Copyright (C) 2022 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 paillier_sum.h + * @author: yujiechen + * @date 2023-08-18 + */ + +#ifndef __PAILLIER_SUM_H__ +#define __PAILLIER_SUM_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif +my_bool paillier_sum_init(UDF_INIT* initid, UDF_ARGS* args, char* message); + +void paillier_sum_deinit(UDF_INIT* initid); +void paillier_sum_clear(UDF_INIT* initid, char* is_null, char* error); +void paillier_sum_reset(UDF_INIT* initid, UDF_ARGS* args, char* is_null, char* error); + +// Note: every row data will trigger this function +void paillier_sum_add(UDF_INIT* initid, UDF_ARGS* args, char* is_null, char* error); + +char* paillier_sum(UDF_INIT* initid, UDF_ARGS* args, char* result, unsigned long* length, + char* is_null, char* error); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/cpp/wedpr-crypto/ppc-udf/mysql/sym_dec.cpp b/cpp/wedpr-crypto/ppc-udf/mysql/sym_dec.cpp new file mode 100644 index 00000000..7bdec184 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-udf/mysql/sym_dec.cpp @@ -0,0 +1,178 @@ +/** + * Copyright (C) 2022 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 sym_dec.cpp + * @author: caryliao + * @date 2023-10-25 + */ +#include "sym_dec.h" +#include "ppc-crypto-c-sdk/symmetric_encryption.h" +#include "ppc-crypto-c-sdk/utils/error.h" +#include "ppc-crypto-c-sdk/utils/utilities.h" +#include "ppc-framework/libwrapper/Buffer.h" +#include +#include +#include + +using namespace std; + +struct SymDecData { + int algorithmType = 0; + int mode = 0; + InputBuffer iv; + InputBuffer symSk; + char* symDecryptResult = NULL; +}; + + +// eg:sym_dec(columnName, algorithmType, mode, hexIv, hexSk) +my_bool sym_dec_init(UDF_INIT* initid, UDF_ARGS* args, char* message) +{ + SymDecData* data = new SymDecData; + initid->ptr = (char*)data; + + if (args->arg_count != 5) + { + const char* errorMsg = + "\nUsage:sym_dec(columnName, algorithmType, mode, hexIv, hexSk)" + "\nalgorithmType(0:AES_128, 1:AES_192, 2:AES_256, 3:TrippleDES, 4:SM4), mode(0:ECB, " + "1:CBC, 2:CFB, 3:OFB, 4:CTR)"; + snprintf(message, max_msg_size, "%s", errorMsg); + return 1; + } + if (args->arg_type[0] != STRING_RESULT || args->arg_type[1] != INT_RESULT || + args->arg_type[2] != INT_RESULT || args->arg_type[3] != STRING_RESULT || + args->arg_type[4] != STRING_RESULT) + { + snprintf(message, max_msg_size, "%s", "sym_dec() requires (string, int, int, string, string) as parameters"); + return 1; + } + int algorithmType = *(int*)(args->args[1]); + int mode = *(int*)(args->args[2]); + // check algorithmType and mode in [0, 4] + if (algorithmType < 0 || algorithmType > 4) + { + snprintf(message, max_msg_size, "%s", "invalid algorithmType, algorithmType must be 0, 1, 2, 3 or 4"); + return 1; + } + if (mode < 0 || mode > 4) + { + snprintf(message, max_msg_size, "%s", "invalid mode, mode must be 0, 1, 2, 3 or 4"); + return 1; + } + // algorithmType is 3 and mode is 4 is not match + if (algorithmType == 3 && mode == 4) + { + snprintf(message, max_msg_size, "%s", "TrippleDES does not support CTR mode"); + return 1; + } + data->algorithmType = algorithmType; + data->mode = mode; + unsigned char* ivBytesData = (unsigned char*)malloc(args->lengths[3] / 2); + unsigned char* skBytesData = (unsigned char*)malloc(args->lengths[4] / 2); + if (!ivBytesData) + { + snprintf(message, max_msg_size, "%s", "allocate memory for iv failed"); + return 1; + } + if (!skBytesData) + { + snprintf(message, max_msg_size, "%s", "allocate memory for sk failed"); + return 1; + } + OutputBuffer ivBytesBuffer = {ivBytesData, args->lengths[3] / 2}; + OutputBuffer skBytesBuffer = {skBytesData, args->lengths[4] / 2}; + InputBuffer ivHexBuffer = {(const unsigned char*)args->args[3], args->lengths[3]}; + InputBuffer skHexBuffer = {(const unsigned char*)args->args[4], args->lengths[4]}; + + from_hex(&ivBytesBuffer, &ivHexBuffer); + if (get_last_error() != 0) + { + snprintf(message, max_msg_size, "%s", "Invalid hex iv!"); + return 1; + } + from_hex(&skBytesBuffer, &skHexBuffer); + if (get_last_error() != 0) + { + snprintf(message, max_msg_size, "%s", "Invalid hex sk!"); + return 1; + } + data->iv.data = ivBytesBuffer.data; + data->iv.len = ivBytesBuffer.len; + + data->symSk.data = skBytesBuffer.data; + data->symSk.len = skBytesBuffer.len; + + data->symDecryptResult = (char*)malloc(symmetric_block_size(data->algorithmType) + args->lengths[0] / 2); + if (!data->symDecryptResult) + { + snprintf(message, max_msg_size, "%s", "Malloc memory for symDecryptResult failed!"); + return 1; + } + + return 0; +} + +void sym_dec_deinit(UDF_INIT* initid) +{ + if (initid->ptr) + { + SymDecData* data = (SymDecData*)initid->ptr; + if(data->symDecryptResult) + { + free(data->symDecryptResult); + data->symDecryptResult = NULL; + } + if(data->iv.data) + { + free((void*)data->iv.data); + data->iv.data = NULL; + } + if(data->symSk.data) + { + free((void*)data->symSk.data); + data->symSk.data = NULL; + } + free(initid->ptr); + initid->ptr = NULL; + } +} + +char* sym_dec(UDF_INIT* initid, UDF_ARGS* args, char* result, unsigned long* length, char* is_null, + char* error) +{ + InputBuffer hexArgs = {(const unsigned char*)args->args[0], args->lengths[0]}; + OutputBuffer bytesArgsBuffer = {(unsigned char*)args->args[0], args->lengths[0] / 2}; + from_hex(&bytesArgsBuffer, &hexArgs); + if (get_last_error() != 0) + { + snprintf(error, max_msg_size, "%s", "Invalid hex cipher!"); + return NULL; + } + // sym_decrypt + SymDecData* data = (SymDecData*)initid->ptr; + InputBuffer ciphertext = {(const unsigned char*)bytesArgsBuffer.data, bytesArgsBuffer.len}; + OutputBuffer plainBuffer = {(unsigned char*)(data->symDecryptResult), + symmetric_block_size(data->algorithmType) + args->lengths[0] / 2}; + symmetric_decrypt(&plainBuffer, data->algorithmType, data->mode, &data->symSk, &data->iv, &ciphertext); + if (get_last_error() != 0) + { + const char* errorMsg = get_last_error_msg(); + snprintf(error, max_msg_size, "%s", errorMsg); + return NULL; + }; + *length = plainBuffer.len; + return data->symDecryptResult; +} diff --git a/cpp/wedpr-crypto/ppc-udf/mysql/sym_dec.h b/cpp/wedpr-crypto/ppc-udf/mysql/sym_dec.h new file mode 100644 index 00000000..f5b90ca4 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-udf/mysql/sym_dec.h @@ -0,0 +1,42 @@ +/** + * Copyright (C) 2022 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 sym_dec.h + * @author: caryliao + * @date 2023-10-25 + */ + +#ifndef __PAILLIER_DECRYPT_H__ +#define __PAILLIER_DECRYPT_H__ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +my_bool sym_dec_init(UDF_INIT* initid, UDF_ARGS* args, char* message); + +void sym_dec_deinit(UDF_INIT* initid); + +// Note: every row data will trigger this function +char* sym_dec(UDF_INIT* initid, UDF_ARGS* args, char* result, unsigned long* length, + char* is_null, char* error); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/cpp/wedpr-crypto/ppc-udf/mysql/sym_enc.cpp b/cpp/wedpr-crypto/ppc-udf/mysql/sym_enc.cpp new file mode 100644 index 00000000..9ff3153c --- /dev/null +++ b/cpp/wedpr-crypto/ppc-udf/mysql/sym_enc.cpp @@ -0,0 +1,171 @@ +/** + * Copyright (C) 2022 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 sym_enc.cpp + * @author: caryliao + * @date 2023-11-29 + */ +#include "sym_enc.h" +#include "ppc-crypto-c-sdk/symmetric_encryption.h" +#include "ppc-crypto-c-sdk/utils/error.h" +#include "ppc-crypto-c-sdk/utils/utilities.h" +#include "ppc-framework/libwrapper/Buffer.h" +#include +#include +#include +#include + +using namespace std; +using namespace bcos; + +struct SymEncData { + int algorithmType = 0; + int mode = 0; + InputBuffer iv; + InputBuffer symSk; + char* symEncryptResult = NULL; +}; + + +// eg:sym_enc(columnName, algorithmType, mode, hexIv, hexSk) +my_bool sym_enc_init(UDF_INIT* initid, UDF_ARGS* args, char* message) +{ + SymEncData* data = new SymEncData; + initid->ptr = (char*)data; + + if (args->arg_count != 5) + { + const char* errorMsg = + "\nUsage:sym_enc(columnName, algorithmType, mode, hexIv, hexSk)" + "\nalgorithmType(0:AES_128, 1:AES_192, 2:AES_256, 3:TrippleDES, 4:SM4), mode(0:ECB, " + "1:CBC, 2:CFB, 3:OFB, 4:CTR)"; + snprintf(message, max_msg_size, "%s", errorMsg); + return 1; + } + if (args->arg_type[0] != STRING_RESULT || args->arg_type[1] != INT_RESULT || + args->arg_type[2] != INT_RESULT || args->arg_type[3] != STRING_RESULT || + args->arg_type[4] != STRING_RESULT) + { + snprintf(message, max_msg_size, "%s", "sym_enc() requires (string, int, int, string, string) as parameters"); + return 1; + } + int algorithmType = *(int*)(args->args[1]); + int mode = *(int*)(args->args[2]); + // check algorithmType and mode in [0, 4] + if (algorithmType < 0 || algorithmType > 4) + { + snprintf(message, max_msg_size, "%s", "invalid algorithmType, algorithmType must be 0, 1, 2, 3 or 4"); + return 1; + } + if (mode < 0 || mode > 4) + { + snprintf(message, max_msg_size, "%s", "invalid mode, mode must be 0, 1, 2, 3 or 4"); + return 1; + } + // algorithmType is 3 and mode is 4 is not match + if (algorithmType == 3 && mode == 4) + { + snprintf(message, max_msg_size, "%s", "TrippleDES does not support CTR mode"); + return 1; + } + data->algorithmType = algorithmType; + data->mode = mode; + unsigned char* ivBytesData = (unsigned char*)malloc(args->lengths[3] / 2); + unsigned char* skBytesData = (unsigned char*)malloc(args->lengths[4] / 2); + if (!ivBytesData) + { + snprintf(message, max_msg_size, "%s", "allocate memory for iv failed"); + return 1; + } + if (!skBytesData) + { + snprintf(message, max_msg_size, "%s", "allocate memory for sk failed"); + return 1; + } + OutputBuffer ivBytesBuffer = {ivBytesData, args->lengths[3] / 2}; + OutputBuffer skBytesBuffer = {skBytesData, args->lengths[4] / 2}; + InputBuffer ivHexBuffer = {(const unsigned char*)args->args[3], args->lengths[3]}; + InputBuffer skHexBuffer = {(const unsigned char*)args->args[4], args->lengths[4]}; + + from_hex(&ivBytesBuffer, &ivHexBuffer); + if (get_last_error() != 0) + { + snprintf(message, max_msg_size, "%s", "Invalid hex iv!"); + return 1; + } + from_hex(&skBytesBuffer, &skHexBuffer); + if (get_last_error() != 0) + { + snprintf(message, max_msg_size, "%s", "Invalid hex sk!"); + return 1; + } + data->iv.data = ivBytesBuffer.data; + data->iv.len = ivBytesBuffer.len; + + data->symSk.data = skBytesBuffer.data; + data->symSk.len = skBytesBuffer.len; + + data->symEncryptResult = (char*)malloc(symmetric_block_size(data->algorithmType) + args->lengths[0]); + if (!data->symEncryptResult) + { + snprintf(message, max_msg_size, "%s", "Malloc memory for symEncryptResult failed!"); + return 1; + } + + return 0; +} + +void sym_enc_deinit(UDF_INIT* initid) +{ + if (initid->ptr) + { + SymEncData* data = (SymEncData*)initid->ptr; + if(data->symEncryptResult) + { + free(data->symEncryptResult); + data->symEncryptResult = NULL; + } + if(data->iv.data) + { + free((void*)data->iv.data); + data->iv.data = NULL; + } + if(data->symSk.data) + { + free((void*)data->symSk.data); + data->symSk.data = NULL; + } + free(initid->ptr); + initid->ptr = NULL; + } +} + +char* sym_enc(UDF_INIT* initid, UDF_ARGS* args, char* result, unsigned long* length, char* is_null, + char* error) +{ + InputBuffer plainText = {(const unsigned char*)args->args[0], args->lengths[0]}; + SymEncData* data = (SymEncData*)initid->ptr; + OutputBuffer cipherBuffer = {(unsigned char*)(data->symEncryptResult), + symmetric_block_size(data->algorithmType) + args->lengths[0]}; + symmetric_encrypt(&cipherBuffer, data->algorithmType, data->mode, &data->symSk, &data->iv, &plainText); + if (get_last_error() != 0) + { + const char* errorMsg = get_last_error_msg(); + snprintf(error, max_msg_size, "%s", errorMsg); + return NULL; + }; + *length = cipherBuffer.len; + return data->symEncryptResult; +} diff --git a/cpp/wedpr-crypto/ppc-udf/mysql/sym_enc.h b/cpp/wedpr-crypto/ppc-udf/mysql/sym_enc.h new file mode 100644 index 00000000..aad19a22 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-udf/mysql/sym_enc.h @@ -0,0 +1,42 @@ +/** + * Copyright (C) 2022 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 sym_enc.h + * @author: caryliao + * @date 2023-11-25 + */ + +#ifndef __PAILLIER_DECRYPT_H__ +#define __PAILLIER_DECRYPT_H__ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +my_bool sym_enc_init(UDF_INIT* initid, UDF_ARGS* args, char* message); + +void sym_enc_deinit(UDF_INIT* initid); + +// Note: every row data will trigger this function +char* sym_enc(UDF_INIT* initid, UDF_ARGS* args, char* result, unsigned long* length, + char* is_null, char* error); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/cpp/wedpr-crypto/ppc-udf/tests/CMakeLists.txt b/cpp/wedpr-crypto/ppc-udf/tests/CMakeLists.txt new file mode 100644 index 00000000..aab162b0 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-udf/tests/CMakeLists.txt @@ -0,0 +1,10 @@ +file(GLOB_RECURSE SOURCES "*.cpp" "*.h") + +# cmake settings +set(TEST_BINARY_NAME test-ppc-udf) + +add_executable(${TEST_BINARY_NAME} ${SOURCES}) +target_include_directories(${TEST_BINARY_NAME} PRIVATE .) + +target_link_libraries(${TEST_BINARY_NAME} ${PPC_UDF_STATIC_TARGET} ${BOOST_UNIT_TEST}) +add_test(NAME test-ppc-udf WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} COMMAND ${TEST_BINARY_NAME}) diff --git a/cpp/wedpr-crypto/ppc-udf/tests/OreDecUDFTest.cpp b/cpp/wedpr-crypto/ppc-udf/tests/OreDecUDFTest.cpp new file mode 100644 index 00000000..bf605775 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-udf/tests/OreDecUDFTest.cpp @@ -0,0 +1,153 @@ +/* + * 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 applicabl 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 OreDecUDFTest.cpp + * @author: caryliao + * @date 2023-10-25 + */ +#include "openssl/bn.h" +#include "ppc-crypto-c-sdk/fast_ore.h" +#include "ppc-framework/libwrapper/BigNum.h" +#include "ppc-framework/libwrapper/Buffer.h" +#include "ppc-udf/mysql/ore_dec.h" +#include +#include +#include + +using namespace bcos; +using namespace bcos::test; +using namespace ppc; +using namespace ppc::crypto; + +namespace ppc::test +{ +BOOST_FIXTURE_TEST_SUITE(oreDecUDFTest, TestPromptFixture) + +std::pair fakeMySQLParameters() +{ + UDF_INIT* initid = new UDF_INIT(); + UDF_ARGS* args = new UDF_ARGS(); + int argCount = 2; + args->arg_count = argCount; + args->args = new char*[argCount]; + args->lengths = new unsigned long[argCount]; + args->arg_type = new Item_result[argCount]; + + args->arg_type[0] = STRING_RESULT; + args->arg_type[1] = STRING_RESULT; + + return std::make_pair(initid, args); +} + +void testOreDec(InputBuffer const* plainTextBytesBuffer, InputBuffer const* skBytesBuffer) +{ + char* message = new char[1000]; + char* error = new char[1000]; + memset(message, 0, 1000); + memset(error, 0, 1000); + auto fakedArgs = fakeMySQLParameters(); + std::cout << "#### testOreDec" << std::endl; + bool isHex = true; + bcos::bytes cipherData(fast_ore_get_cipher_size(plainTextBytesBuffer->len, isHex)); + OutputBuffer cipherBuffer{cipherData.data(), cipherData.size()}; + string_fast_ore_encrypt(&cipherBuffer, skBytesBuffer, plainTextBytesBuffer, isHex); + // InputBuffer inputBufferCipher{cipherBuffer.data, cipherBuffer.len}; + + // convert cipherBytes to hex + // auto hexCipher = *(bcos::toHexString(cipherData.data(), cipherData.data() + cipherBuffer.len)); + // std::cout << "#### hexCipher: " << hexCipher << std::endl; + // fakedArgs.second->args[0] = (char*)hexCipher.data(); + // fakedArgs.second->lengths[0] = hexCipher.size(); + fakedArgs.second->args[0] = (char*)cipherData.data(); + fakedArgs.second->lengths[0] = cipherBuffer.len; + + // std::cout << "#### decrypt" << std::endl; + // bcos::bytes plain(plainTextBytesBuffer->len); + // OutputBuffer plainBuffer{plain.data(), plain.size()}; + // string_fast_ore_decrypt(&plainBuffer, skBytesBuffer, &inputBufferCipher, isHex); + // std::cout << "#### decrypt end: " << plainBuffer.data << "# len: " << + // plainBuffer.len << ", size: " << plain.size()<data, skBytesBuffer->data + skBytesBuffer->len)); + InputBuffer inputBufferHexSk{(const unsigned char*)hexSk.data(), hexSk.size()}; + + fakedArgs.second->args[1] = (char*)hexSk.data(); + fakedArgs.second->lengths[1] = hexSk.size(); + + std::cout << "args[0]" << fakedArgs.second->args[0] << std::endl; + std::cout << "lengths[0]" << fakedArgs.second->lengths[0] << std::endl; + std::cout << "args[1]" << fakedArgs.second->args[1] << std::endl; + std::cout << "lengths[1]" << fakedArgs.second->lengths[1] << std::endl; + + std::cout << "### before init" << std::endl; + auto start = std::chrono::high_resolution_clock::now(); + auto ret = ore_dec_init(fakedArgs.first, fakedArgs.second, message); + // init failed + if (ret) + { + std::cout << "#### init fail" << std::endl; + return; + } + std::cout << "#### init success" << std::endl; + // obtain the result + char* result = new char[fakedArgs.first->max_length]; + unsigned long length; + auto decryptV = ore_dec(fakedArgs.first, fakedArgs.second, result, &length, nullptr, error); + auto end = std::chrono::high_resolution_clock::now(); + auto duration = std::chrono::duration_cast(end - start).count(); + // Print the execution time + std::cout << " ore execution time: " << duration << " microseconds" << std::endl; + auto plainText = plainTextBytesBuffer->data; + std::cout << "#### ore pV: " << plainText << ", len:" << plainTextBytesBuffer->len << std::endl; + std::cout << "#### ore dV: " << decryptV << ", len:" << strlen(decryptV) << std::endl; + BOOST_CHECK(*plainText == *decryptV); + ore_dec_deinit(fakedArgs.first); + delete fakedArgs.first; + delete fakedArgs.second; + if (message) + { + delete[] message; + } + if (error) + { + delete[] error; + } +} + +void testOreDecUDFImpl() +{ + srand(bcos::utcSteadyTime()); + std::string plainText = "19014527865"; + bcos::bytes plainTextBytes(plainText.begin(), plainText.end()); + InputBuffer plainTextBytesBuffer{ + (const unsigned char*)plainTextBytes.data(), plainTextBytes.size()}; + + bcos::bytes skBytes(fast_ore_key_bytes(), 0); + OutputBuffer skBuffer{skBytes.data(), skBytes.size()}; + fast_ore_generate_key(&skBuffer); + + + InputBuffer skBytesBuffer{(const unsigned char*)skBytes.data(), skBytes.size()}; + testOreDec(&plainTextBytesBuffer, &skBytesBuffer); +} + +BOOST_AUTO_TEST_CASE(testOreDecUDF) +{ + testOreDecUDFImpl(); +} + +BOOST_AUTO_TEST_SUITE_END() +} // namespace ppc::test diff --git a/cpp/wedpr-crypto/ppc-udf/tests/OreEncUDFTest.cpp b/cpp/wedpr-crypto/ppc-udf/tests/OreEncUDFTest.cpp new file mode 100644 index 00000000..e789af1e --- /dev/null +++ b/cpp/wedpr-crypto/ppc-udf/tests/OreEncUDFTest.cpp @@ -0,0 +1,154 @@ +/* + * 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 applicabl 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 OreEncUDFTest.cpp + * @author: caryliao + * @date 2023-11-30 + */ +#include "openssl/bn.h" +#include "ppc-crypto-c-sdk/fast_ore.h" +#include "ppc-framework/libwrapper/BigNum.h" +#include "ppc-framework/libwrapper/Buffer.h" +#include "ppc-udf/mysql/ore_enc.h" +#include +#include +#include + +using namespace bcos; +using namespace bcos::test; +using namespace ppc; +using namespace ppc::crypto; + +namespace ppc::test +{ +BOOST_FIXTURE_TEST_SUITE(oreEncUDFTest, TestPromptFixture) + +std::pair fakeMySQLParameters() +{ + UDF_INIT* initid = new UDF_INIT(); + UDF_ARGS* args = new UDF_ARGS(); + int argCount = 2; + args->arg_count = argCount; + args->args = new char*[argCount]; + args->lengths = new unsigned long[argCount]; + args->arg_type = new Item_result[argCount]; + + args->arg_type[0] = STRING_RESULT; + args->arg_type[1] = STRING_RESULT; + + return std::make_pair(initid, args); +} + +void testOreEnc( + InputBuffer const* plainTextBytesBuffer, InputBuffer const* skBytesBuffer) +{ + char* message = new char[1000]; + char* error = new char[1000]; + memset(message, 0, 1000); + memset(error, 0, 1000); + auto fakedArgs = fakeMySQLParameters(); + std::cout << "#### testOreEnc" << std::endl; + bool isHex = true; + bcos::bytes cipherData(fast_ore_get_cipher_size(plainTextBytesBuffer->len, isHex)); + OutputBuffer cipherBuffer{cipherData.data(), cipherData.size()}; + string_fast_ore_encrypt(&cipherBuffer, skBytesBuffer, plainTextBytesBuffer, isHex); + // InputBuffer inputBufferCipher{cipherBuffer.data, cipherBuffer.len}; + + // convert cipherBytes to hex + // auto hexCipher = *(bcos::toHexString(cipherData.data(), cipherData.data() + cipherBuffer.len)); + // std::cout << "#### hexCipher: " << hexCipher << std::endl; + // fakedArgs.second->args[0] = (char*)hexCipher.data(); + // fakedArgs.second->lengths[0] = hexCipher.size(); + fakedArgs.second->args[0] = (char*)plainTextBytesBuffer->data; + fakedArgs.second->lengths[0] = plainTextBytesBuffer->len; + + // std::cout << "#### encrypt" << std::endl; + // bcos::bytes plain(plainTextBytesBuffer->len); + // OutputBuffer plainBuffer{plain.data(), plain.size()}; + // string_fast_ore_encrypt(&plainBuffer, skBytesBuffer, &inputBufferCipher, isHex); + // std::cout << "#### encrypt end: " << plainBuffer.data << "# len: " << + // plainBuffer.len << ", size: " << plain.size()<data, skBytesBuffer->data + skBytesBuffer->len)); + InputBuffer inputBufferHexSk{(const unsigned char*)hexSk.data(), hexSk.size()}; + + fakedArgs.second->args[1] = (char*)hexSk.data(); + fakedArgs.second->lengths[1] = hexSk.size(); + + std::cout << "args[0]" << fakedArgs.second->args[0] << std::endl; + std::cout << "lengths[0]" << fakedArgs.second->lengths[0] << std::endl; + std::cout << "args[1]" << fakedArgs.second->args[1] << std::endl; + std::cout << "lengths[1]" << fakedArgs.second->lengths[1] << std::endl; + + std::cout << "### before init" << std::endl; + auto start = std::chrono::high_resolution_clock::now(); + auto ret = ore_enc_init(fakedArgs.first, fakedArgs.second, message); + // init failed + if (ret) + { + std::cout << "#### init fail" << std::endl; + return; + } + std::cout << "#### init success" << std::endl; + // obtain the result + char* result = new char[fakedArgs.first->max_length]; + unsigned long length; + auto encryptV = ore_enc(fakedArgs.first, fakedArgs.second, result, &length, nullptr, error); + auto end = std::chrono::high_resolution_clock::now(); + auto duration = std::chrono::duration_cast(end - start).count(); + // Print the execution time + std::cout << " ore execution time: " << duration << " microseconds" << std::endl; + auto plainText = plainTextBytesBuffer->data; + std::cout << "#### ore pV: " << plainText << ", len:" << plainTextBytesBuffer->len << std::endl; + std::cout << "#### ore dV: " << encryptV << ", len:" << strlen(encryptV) << std::endl; + BOOST_CHECK(*cipherBuffer.data == *encryptV); + ore_enc_deinit(fakedArgs.first); + delete fakedArgs.first; + delete fakedArgs.second; + if (message) + { + delete[] message; + } + if (error) + { + delete[] error; + } +} + +void testOreEncUDFImpl() +{ + srand(bcos::utcSteadyTime()); + std::string plainText = "19014527865"; + bcos::bytes plainTextBytes(plainText.begin(), plainText.end()); + InputBuffer plainTextBytesBuffer{ + (const unsigned char*)plainTextBytes.data(), plainTextBytes.size()}; + + bcos::bytes skBytes(fast_ore_key_bytes(), 0); + OutputBuffer skBuffer{skBytes.data(), skBytes.size()}; + fast_ore_generate_key(&skBuffer); + + + InputBuffer skBytesBuffer{(const unsigned char*)skBytes.data(), skBytes.size()}; + testOreEnc(&plainTextBytesBuffer, &skBytesBuffer); +} + +BOOST_AUTO_TEST_CASE(testOreEncUDF) +{ + testOreEncUDFImpl(); +} + +BOOST_AUTO_TEST_SUITE_END() +} // namespace ppc::test diff --git a/cpp/wedpr-crypto/ppc-udf/tests/PaillierDecUDFTest.cpp b/cpp/wedpr-crypto/ppc-udf/tests/PaillierDecUDFTest.cpp new file mode 100644 index 00000000..7b1154d2 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-udf/tests/PaillierDecUDFTest.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 applicabl 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 PaillierDecryptionUDFTest.cpp + * @author: caryliao + * @date 2023-10-24 + */ +#include "openssl/bn.h" +#include "ppc-crypto-c-sdk/floating_point_paillier.h" +#include "ppc-crypto-c-sdk/homo_paillier.h" +#include "ppc-crypto-c-sdk/utils/error.h" +#include "ppc-framework/libwrapper/BigNum.h" +#include "ppc-framework/libwrapper/Buffer.h" +#include "ppc-homo/codec/FloatingPointCodec.h" +#include "ppc-homo/paillier/OpenSSLPaillier.h" +#include "ppc-udf/mysql/paillier_dec.h" +#include +#include +#include +#include + +using namespace bcos; +using namespace bcos::test; +using namespace ppc; +using namespace ppc::crypto; +using namespace ppc::homo; + +namespace ppc::test +{ +BOOST_FIXTURE_TEST_SUITE(PaillierDecryptionUDFTest, TestPromptFixture) + +std::pair fakeMySQLParameters( + InputBuffer const* cipherBytes, InputBuffer const* pkBytes, InputBuffer const* skBytes) +{ + UDF_INIT* initid = new UDF_INIT(); + UDF_ARGS* args = new UDF_ARGS(); + args->arg_count = 4; + args->args = new char*[4]; + args->lengths = new unsigned long[4]; + args->arg_type = new Item_result[4]; + if (cipherBytes) + { + args->args[0] = (char*)cipherBytes->data; + args->lengths[0] = cipherBytes->len; + } + args->args[1] = (char*)pkBytes->data; + args->lengths[1] = pkBytes->len; + args->args[2] = (char*)skBytes->data; + args->lengths[2] = skBytes->len; + + args->arg_type[0] = STRING_RESULT; + args->arg_type[1] = STRING_RESULT; + args->arg_type[2] = STRING_RESULT; + args->arg_type[3] = INT_RESULT; + return std::make_pair(initid, args); +} + +void testPaillierDecInt(std::vector const& values, InputBuffer const* pkBytes, + InputBuffer const* skBytes, int keyBits, void* keypair) +{ + char* message = new char[1000]; + char* error = new char[1000]; + memset(message, 0, 1000); + memset(error, 0, 1000); + auto fakedArgs = fakeMySQLParameters(nullptr, pkBytes, skBytes); + std::cout << "#### testPaillierDec" << std::endl; + int i = 0; + for (auto it : values) + { + BigNum v(it); + bcos::bytes cipherData(floating_point_paillier_cipher_bytes(keyBits), 0); + OutputBuffer cipherBuffer{cipherData.data(), cipherData.size()}; + int16_t exponent = 0; + auto _keyPair = (OpenSSLPaillierKeyPair*)keypair; + auto pk = _keyPair->pk(); + floating_point_paillier_encrypt(&cipherBuffer, v.bn().get(), exponent, pk); + if (get_last_error() != 0) + { + const char* errorMsg = get_last_error_msg(); + std::cout << "#### floating_point_paillier_encrypt error:" << errorMsg << std::endl; + return; + } + InputBuffer cipherBytes{cipherData.data(), cipherData.size()}; + // convert cipherBytes to hex + auto hexCipher = *(bcos::toHexString(cipherData)); + std::cout << "#### hexCipher: " << hexCipher << std::endl; + fakedArgs.second->args[0] = (char*)hexCipher.data(); + fakedArgs.second->lengths[0] = hexCipher.size(); + // fakedArgs.second->args[3] = (char*)"0"; + // fakedArgs.second->lengths[3] = 1; + int scale = 0; + fakedArgs.second->args[3] = (char*)&scale; + fakedArgs.second->lengths[3] = sizeof(int*); + // init for the fist element + if (i == 0) + { + std::cout << "#### before init" << std::endl; + auto ret = paillier_dec_init(fakedArgs.first, fakedArgs.second, message); + // init failed + if (ret) + { + std::cout << "#### init fail" << std::endl; + break; + } + std::cout << "#### init success" << std::endl; + } + i++; + // obtain the result + char* result = new char[fakedArgs.first->max_length]; + unsigned long length; + auto decryptV = + paillier_dec(fakedArgs.first, fakedArgs.second, result, &length, nullptr, error); + std::cout << "#### int pV: " << it << std::endl; + std::cout << "#### int dV: " << decryptV << std::endl; + BOOST_CHECK(decryptV == it); + } + paillier_dec_deinit(fakedArgs.first); + delete fakedArgs.first; + delete fakedArgs.second; + if (message) + { + delete[] message; + } + if (error) + { + delete[] error; + } +} + +void testPaillierDoubleDec(std::vector const& values, InputBuffer const* pkBytes, + InputBuffer const* skBytes, int keyBits, void* keypair) +{ + char* message = new char[1000]; + char* error = new char[1000]; + memset(message, 0, 1000); + memset(error, 0, 1000); + auto fakedArgs = fakeMySQLParameters(nullptr, pkBytes, skBytes); + std::cout << "#### testPaillierDoubleDec" << std::endl; + int i = 0; + auto codec = std::make_shared(); + for (auto strValue : values) + { + auto it = float50(strValue); + auto fpn = codec->toFloatingPoint(strValue); + bcos::bytes cipherData(floating_point_paillier_cipher_bytes(keyBits), 0); + OutputBuffer cipherBuffer{cipherData.data(), cipherData.size()}; + int16_t exponent = fpn.exponent; + auto _keyPair = (OpenSSLPaillierKeyPair*)keypair; + auto pk = _keyPair->pk(); + floating_point_paillier_encrypt(&cipherBuffer, fpn.value.bn().get(), exponent, pk); + if (get_last_error() != 0) + { + const char* errorMsg = get_last_error_msg(); + std::cout << "#### floating_point_paillier_encrypt error:" << errorMsg << std::endl; + return; + } + InputBuffer cipherBytes{cipherData.data(), cipherData.size()}; + // convert cipherBytes to hex + auto hexCipher = *(bcos::toHexString(cipherData)); + std::cout << "#### hexCipher: " << hexCipher << std::endl; + fakedArgs.second->args[0] = (char*)hexCipher.data(); + fakedArgs.second->lengths[0] = hexCipher.size(); + int scale = 2; + fakedArgs.second->args[3] = (char*)&scale; + fakedArgs.second->lengths[3] = sizeof(int*); + // init for the fist element + auto start = std::chrono::high_resolution_clock::now(); + if (i == 0) + { + // std::cout << "#### before init" << std::endl; + auto ret = paillier_dec_init(fakedArgs.first, fakedArgs.second, message); + // init failed + if (ret) + { + std::cout << "#### init fail" << std::endl; + break; + } + std::cout << "#### init success" << std::endl; + } + i++; + // obtain the result + char* result = new char[fakedArgs.first->max_length]; + unsigned long length; + auto decryptV = + paillier_dec(fakedArgs.first, fakedArgs.second, result, &length, nullptr, error); + auto end = std::chrono::high_resolution_clock::now(); + auto duration = std::chrono::duration_cast(end - start).count(); + // Print the execution time + std::cout << " paillier execution time: " << duration << " microseconds" << std::endl; + + double multiplier = pow(10.0, scale); + double roundPv = round((double)it * multiplier) / multiplier; + std::cout << "#### double pV: " << roundPv << std::endl; + std::cout << "#### double dV: " << decryptV << std::endl; + BOOST_CHECK(decryptV == roundPv); + } + paillier_dec_deinit(fakedArgs.first); + delete fakedArgs.first; + delete fakedArgs.second; + if (message) + { + delete[] message; + } + if (error) + { + delete[] error; + } +} + +void testPaillierDecryptionUDFIntImpl(int iter) +{ + srand(bcos::utcSteadyTime()); + int64_t m = 0; + std::vector values(iter); + for (int64_t i = 0; i < iter; i++) + { + m = 12323434 + rand(); + if (i % 3 == 0) + { + m = -1234324 - rand(); + } + values[i] = m; + } + int keyBits = 2048; + auto keypair = paillier_generate_keypair(keyBits); + + bcos::bytes pkBytes(paillier_max_public_key_bytes(keyBits), 0); + bcos::bytes skBytes(paillier_max_private_key_bytes(keyBits), 0); + OutputBuffer pkBuffer{pkBytes.data(), pkBytes.size()}; + OutputBuffer skBuffer{skBytes.data(), skBytes.size()}; + paillier_set_public_key_bytes_from_keypair(&pkBuffer, keypair); + paillier_set_private_key_bytes_from_keypair(&skBuffer, keypair); + + // convert to hexedPk + auto hexPk = *(bcos::toHexString(pkBytes)); + auto hexSk = *(bcos::toHexString(skBytes)); + InputBuffer pkBytesBuffer{(const unsigned char*)hexPk.data(), hexPk.size()}; + InputBuffer skBytesBuffer{(const unsigned char*)hexSk.data(), hexSk.size()}; + std::cout << "#### hexPk:" << pkBytesBuffer.data << std::endl; + std::cout << "#### hexSk:" << skBytesBuffer.data << std::endl; + testPaillierDecInt(values, &pkBytesBuffer, &skBytesBuffer, keyBits, keypair); +} + +void testPaillierDecryptionUDFDoubleImpl(int iter) +{ + srand(bcos::utcSteadyTime()); + std::vector values; + std::random_device rd; + std::mt19937 generator(rd()); + std::uniform_real_distribution distribution(-109900234.23432434, 10990023423432434); + for (int i = 0; i < iter; ++i) + { + float50 randomValue = float50(distribution(generator)); + values.push_back(randomValue.str(10)); + } + for (const auto& value : values) + { + std::cout << value << " "; + } + int keyBits = 2048; + auto keypair = paillier_generate_keypair(keyBits); + + bcos::bytes pkBytes(paillier_max_public_key_bytes(keyBits), 0); + bcos::bytes skBytes(paillier_max_private_key_bytes(keyBits), 0); + OutputBuffer pkBuffer{pkBytes.data(), pkBytes.size()}; + OutputBuffer skBuffer{skBytes.data(), skBytes.size()}; + paillier_set_public_key_bytes_from_keypair(&pkBuffer, keypair); + paillier_set_private_key_bytes_from_keypair(&skBuffer, keypair); + + // convert to hexedPk + auto hexPk = *(bcos::toHexString(pkBytes)); + auto hexSk = *(bcos::toHexString(skBytes)); + InputBuffer pkBytesBuffer{(const unsigned char*)hexPk.data(), hexPk.size()}; + InputBuffer skBytesBuffer{(const unsigned char*)hexSk.data(), hexSk.size()}; + std::cout << "#### hexPk:" << pkBytesBuffer.data << std::endl; + std::cout << "#### hexSk:" << skBytesBuffer.data << std::endl; + testPaillierDoubleDec(values, &pkBytesBuffer, &skBytesBuffer, keyBits, keypair); +} + +BOOST_AUTO_TEST_CASE(testPaillierDecryptionUDF) +{ + testPaillierDecryptionUDFIntImpl(3); + testPaillierDecryptionUDFDoubleImpl(3); +} + +BOOST_AUTO_TEST_SUITE_END() +} // namespace ppc::test diff --git a/cpp/wedpr-crypto/ppc-udf/tests/PaillierEncUDFTest.cpp b/cpp/wedpr-crypto/ppc-udf/tests/PaillierEncUDFTest.cpp new file mode 100644 index 00000000..5b1c7f93 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-udf/tests/PaillierEncUDFTest.cpp @@ -0,0 +1,178 @@ +/* + * 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 applicabl 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 PaillierEncryptionUDFTest.cpp + * @author: caryliao + * @date 2023-10-24 + */ +#include "openssl/bn.h" +#include "ppc-crypto-c-sdk/homo_paillier.h" +#include "ppc-crypto-c-sdk/floating_point_paillier.h" +#include "ppc-framework/libwrapper/BigNum.h" +#include "ppc-framework/libwrapper/Buffer.h" +#include "ppc-udf/mysql/paillier_enc.h" +#include +#include +#include +#include "ppc-crypto-c-sdk/utils/error.h" +#include "ppc-homo/paillier/OpenSSLPaillier.h" +#include "ppc-homo/codec/FloatingPointCodec.h" +#include + +using namespace bcos; +using namespace bcos::test; +using namespace ppc; +using namespace ppc::crypto; +using namespace ppc::homo; + +namespace ppc::test +{ +BOOST_FIXTURE_TEST_SUITE(PaillierEncryptionUDFTest, TestPromptFixture) + +std::pair fakeMySQLParameters( + InputBuffer const* cipherBytes, InputBuffer const* pkBytes, InputBuffer const* skBytes) +{ + UDF_INIT* initid = new UDF_INIT(); + UDF_ARGS* args = new UDF_ARGS(); + args->arg_count = 2; + args->args = new char*[args->arg_count]; + args->lengths = new unsigned long[args->arg_count]; + args->arg_type = new Item_result[args->arg_count]; + args->args[1] = (char*)pkBytes->data; + args->lengths[1] = pkBytes->len; + + args->arg_type[0] = STRING_RESULT; + args->arg_type[1] = STRING_RESULT; + return std::make_pair(initid, args); +} + +void testPaillierDoubleEnc(std::vector const& values, InputBuffer const* pkBytes, + InputBuffer const* skBytes, int keyBits, void* keypair) +{ + char* message = new char[1000]; + char* error = new char[1000]; + char* result = new char[10000]; + memset(message, 0, 1000); + memset(error, 0, 1000); + memset(result, 0, 10000); + auto fakedArgs = fakeMySQLParameters(nullptr, pkBytes, skBytes); + std::cout << "#### testPaillierDoubleEnc" << std::endl; + int i = 0; + auto codec = std::make_shared(); + for (auto it : values) + { + // fakedArgs.second->args[0] = (char*)⁢ + const char* strValue = it.c_str(); + fakedArgs.second->args[0] = (char*)strValue; + fakedArgs.second->lengths[0] = strlen(strValue); + // init for the fist element + auto start = std::chrono::high_resolution_clock::now(); + if (i == 0) + { + // std::cout << "#### before init" << std::endl; + auto ret = paillier_enc_init(fakedArgs.first, fakedArgs.second, message); + // init failed + if (ret) + { + std::cout << "#### init fail" << std::endl; + break; + } + std::cout << "#### init success" << std::endl; + } + i++; + // obtain the result + unsigned long length = 0; + auto cipherValue = + paillier_enc(fakedArgs.first, fakedArgs.second, result, &length, nullptr, error); + auto end = std::chrono::high_resolution_clock::now(); + auto duration = std::chrono::duration_cast(end - start).count(); + // Print the execution time + std::cout << " paillier enc execution time: " << duration << " microseconds" << std::endl; + std::cout << "#### cipherValue: " << cipherValue << std::endl; + + InputBuffer cipherBuffer{(unsigned char*)cipherValue, length}; + BigNum decryptV; + int16_t exponent; + floating_point_paillier_decrypt(decryptV.bn().get(), &exponent, &cipherBuffer, keypair); + if (get_last_error()) + { + std::cout << "#### floating_point_paillier_decrypt error: " << get_last_error_msg() + << std::endl; + } + BOOST_CHECK(get_last_error() == 0); + FloatingPointNumber floatingPointNumber(std::move(decryptV), exponent); + BN_print_fp(stdout, floatingPointNumber.value.bn().get()); + auto decryptedResult = codec->toFloat50(floatingPointNumber); + std::cout << "#### decryptedResult: " << decryptedResult << std::endl; + std::cout << "#### float50(it): " << float50(it) << std::endl; + // BOOST_CHECK(decryptedResult == float50(it)); + } + paillier_enc_deinit(fakedArgs.first); + delete fakedArgs.first; + delete fakedArgs.second; + if (message) + { + delete[] message; + } + if (error) + { + delete[] error; + } +} + +void testPaillierEncryptionUDFDoubleImpl(int iter) +{ + srand(bcos::utcSteadyTime()); + std::vector values; + std::random_device rd; + std::mt19937 generator(rd()); + std::uniform_real_distribution distribution(0.0, 1.0); + // for (int i = 0; i < iter; ++i) { + // double randomValue = distribution(generator); + // values.push_back(randomValue*10000); + // } + values.push_back("123.56"); + values.push_back("1000.89"); + values.push_back("2000.76"); + for (const auto& value : values) { + std::cout << value << " "; + } + int keyBits = 2048; + auto keypair = paillier_generate_keypair(keyBits); + + bcos::bytes pkBytes(paillier_max_public_key_bytes(keyBits), 0); + bcos::bytes skBytes(paillier_max_private_key_bytes(keyBits), 0); + OutputBuffer pkBuffer{pkBytes.data(), pkBytes.size()}; + OutputBuffer skBuffer{skBytes.data(), skBytes.size()}; + paillier_set_public_key_bytes_from_keypair(&pkBuffer, keypair); + paillier_set_private_key_bytes_from_keypair(&skBuffer, keypair); + + // convert to hexedPk + auto hexPk = *(bcos::toHexString(pkBytes)); + auto hexSk = *(bcos::toHexString(skBytes)); + InputBuffer pkBytesBuffer{(const unsigned char*)hexPk.data(), hexPk.size()}; + InputBuffer skBytesBuffer{(const unsigned char*)hexSk.data(), hexSk.size()}; + std::cout << "#### hexPk:" << pkBytesBuffer.data << std::endl; + std::cout << "#### hexSk:" << skBytesBuffer.data << std::endl; + testPaillierDoubleEnc(values, &pkBytesBuffer, &skBytesBuffer, keyBits, keypair); +} + +BOOST_AUTO_TEST_CASE(testPaillierEncryptionUDF) +{ + testPaillierEncryptionUDFDoubleImpl(3); +} + +BOOST_AUTO_TEST_SUITE_END() +} // namespace ppc::test diff --git a/cpp/wedpr-crypto/ppc-udf/tests/PaillierSumUDFTest.cpp b/cpp/wedpr-crypto/ppc-udf/tests/PaillierSumUDFTest.cpp new file mode 100644 index 00000000..7b93fcc6 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-udf/tests/PaillierSumUDFTest.cpp @@ -0,0 +1,200 @@ +/* + * 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 applicabl 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 PaillierSumUDFTest.cpp + * @author: yujiechen + * @date 2023-08-22 + */ +#include "openssl/bn.h" +#include "ppc-crypto-c-sdk/floating_point_paillier.h" +#include "ppc-crypto-c-sdk/homo_paillier.h" +#include "ppc-crypto-c-sdk/utils/error.h" +#include "ppc-framework/libwrapper/BigNum.h" +#include "ppc-framework/libwrapper/Buffer.h" +#include "ppc-homo/codec/FloatingPointCodec.h" +#include "ppc-udf/mysql/paillier_sum.h" +#include +#include +#include + +using namespace bcos; +using namespace bcos::test; +using namespace ppc; +using namespace ppc::homo; +using namespace ppc::crypto; + +namespace ppc::test +{ +BOOST_FIXTURE_TEST_SUITE(paillierSumUDFTest, TestPromptFixture) + +std::pair fakeMySQLParameters( + InputBuffer const* cipherBytes, InputBuffer const* pkBytes) +{ + UDF_INIT* initid = new UDF_INIT(); + UDF_ARGS* args = new UDF_ARGS(); + args->arg_count = 2; + args->args = new char*[2]; + if (cipherBytes) + { + args->args[0] = (char*)cipherBytes->data; + } + args->args[1] = (char*)pkBytes->data; + args->lengths = new unsigned long[2]; + if (cipherBytes) + { + args->lengths[0] = cipherBytes->len; + } + args->lengths[1] = pkBytes->len; + return std::make_pair(initid, args); +} + +void testPaillierSum( + std::vector const& values, InputBuffer const* pkBytes, int keyBits, void* keypair) +{ + int i = 0; + char* message = new char[1000]; + char* error = new char[1000]; + memset(message, 0, 1000); + memset(error, 0, 1000); + float50 expectedSum = 0; + auto fakedArgs = fakeMySQLParameters(nullptr, pkBytes); + auto codec = std::make_shared(); + for (auto it : values) + { + expectedSum += it; + bcos::bytes cipherData(floating_point_paillier_cipher_bytes(keyBits), 0); + OutputBuffer cipherBuffer{cipherData.data(), cipherData.size()}; + + auto ffpNumber = codec->toFloatingPoint(it); + BN_print_fp(stdout, ffpNumber.value.bn().get()); + floating_point_paillier_encrypt_fast( + &cipherBuffer, ffpNumber.value.bn().get(), ffpNumber.exponent, keypair); + + InputBuffer cipherBytes{cipherData.data(), cipherBuffer.len}; + // convert cipherBytes to hex + auto hexCipher = *(bcos::toHexString(cipherData)); + fakedArgs.second->args[0] = (char*)hexCipher.data(); + fakedArgs.second->lengths[0] = hexCipher.size(); + // init for the fist element + if (i == 0) + { + auto ret = paillier_sum_init(fakedArgs.first, fakedArgs.second, message); + // init failed + if (ret) + { + break; + } + } + // add for every element + paillier_sum_add(fakedArgs.first, fakedArgs.second, nullptr, error); + i++; + } + // obtain the result + char* result = new char[fakedArgs.first->max_length]; + unsigned long length; + auto retResult = + paillier_sum(fakedArgs.first, fakedArgs.second, result, &length, nullptr, error); + // check the result + std::string hexCipherSum = std::string(retResult, retResult + length); + + bcos::bytes bytesCipherSum = *(bcos::fromHexString(hexCipherSum)); + InputBuffer sumCipherBuffer{bytesCipherSum.data(), bytesCipherSum.size()}; + BigNum decryptV; + int16_t exponent; + floating_point_paillier_decrypt(decryptV.bn().get(), &exponent, &sumCipherBuffer, keypair); + if (get_last_error()) + { + std::cout << "#### floating_point_paillier_decrypt error: " << get_last_error_msg() + << std::endl; + } + BOOST_CHECK(get_last_error() == 0); + FloatingPointNumber floatingPointNumber(std::move(decryptV), exponent); + BN_print_fp(stdout, floatingPointNumber.value.bn().get()); + auto decryptedResult = codec->toFloat50(floatingPointNumber); + BOOST_CHECK(decryptedResult == expectedSum); + + paillier_sum_clear(fakedArgs.first, NULL, NULL); + paillier_sum_deinit(fakedArgs.first); + delete fakedArgs.first; + delete fakedArgs.second; + if (message) + { + delete[] message; + } + if (error) + { + delete[] error; + } +} + +void testPaillierSumUDFImpl(int iter) +{ + srand(bcos::utcSteadyTime()); + int64_t m = 0; + std::vector values(iter); + for (int64_t i = 0; i < iter; i++) + { + m = 12323434 + rand(); + if (i % 3 == 0) + { + m = -1234324 - rand(); + } + values[i] = m; + } + int keyBits = 2048; + auto keypair = paillier_generate_keypair(keyBits); + + bcos::bytes pkBytes(paillier_max_public_key_bytes(keyBits), 0); + OutputBuffer pkBuffer{pkBytes.data(), pkBytes.size()}; + paillier_set_public_key_bytes_from_keypair(&pkBuffer, keypair); + + // convert to hexedPk + auto hexPk = *(bcos::toHexString(pkBytes)); + InputBuffer pkBytesBuffer{(const unsigned char*)hexPk.data(), hexPk.size()}; + testPaillierSum(values, &pkBytesBuffer, keyBits, keypair); +} + +BOOST_AUTO_TEST_CASE(testPaillierSumUDF) +{ + testPaillierSumUDFImpl(1); + testPaillierSumUDFImpl(2); + testPaillierSumUDFImpl(3); + testPaillierSumUDFImpl(10); +} + +BOOST_AUTO_TEST_CASE(testInvalidPaillierSum) +{ + std::string pk = "234324"; + std::string cipher = "234234"; + InputBuffer cipherBuffer{(const unsigned char*)cipher.data(), cipher.size()}; + InputBuffer pkBuffer{(const unsigned char*)pk.data(), pk.size()}; + auto ret = fakeMySQLParameters(&cipherBuffer, &pkBuffer); + char* message = new char[1000]; + paillier_sum_init(ret.first, ret.second, message); + if (ret.first) + { + delete ret.first; + } + if (ret.second) + { + delete ret.second; + } + if (message) + { + delete[] message; + } +} +BOOST_AUTO_TEST_SUITE_END() +} // namespace ppc::test \ No newline at end of file diff --git a/cpp/wedpr-crypto/ppc-udf/tests/SymDecUDFTest.cpp b/cpp/wedpr-crypto/ppc-udf/tests/SymDecUDFTest.cpp new file mode 100644 index 00000000..0151ee74 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-udf/tests/SymDecUDFTest.cpp @@ -0,0 +1,252 @@ +/* + * 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 applicabl 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 SymDecUDFTest.cpp + * @author: caryliao + * @date 2023-10-25 + */ +#include "openssl/bn.h" +#include "ppc-crypto-c-sdk/symmetric_encryption.h" +#include "ppc-crypto-c-sdk/utils/error.h" +#include "ppc-framework/crypto/SymCrypto.h" +#include "ppc-framework/libwrapper/BigNum.h" +#include "ppc-framework/libwrapper/Buffer.h" +#include "ppc-udf/mysql/sym_dec.h" +#include +#include +#include + +using namespace bcos; +using namespace bcos::test; +using namespace ppc; +using namespace ppc::crypto; + +namespace ppc::test +{ +BOOST_FIXTURE_TEST_SUITE(symDecUDFTest, TestPromptFixture) + +std::pair fakeMySQLParameters(InputBuffer const* cipherBytes, + int* algorithmType, int* mode, InputBuffer const* ivBytesBuffer, + InputBuffer const* skBytesBuffer) +{ + UDF_INIT* initid = new UDF_INIT(); + UDF_ARGS* args = new UDF_ARGS(); + args->arg_count = 5; + args->args = new char*[5]; + args->lengths = new unsigned long[5]; + args->arg_type = new Item_result[5]; + if (cipherBytes) + { + args->args[0] = (char*)cipherBytes->data; + args->lengths[0] = cipherBytes->len; + } + args->args[1] = (char*)algorithmType; + args->lengths[1] = sizeof(int); + args->args[2] = (char*)mode; + args->lengths[2] = sizeof(int); + + args->arg_type[0] = STRING_RESULT; + args->arg_type[1] = INT_RESULT; + args->arg_type[2] = INT_RESULT; + args->arg_type[3] = STRING_RESULT; + args->arg_type[4] = STRING_RESULT; + return std::make_pair(initid, args); +} + +void testSymDec(InputBuffer const* plainTextBytesBuffer, int algorithmType, int mode, + InputBuffer const* ivBytesBuffer, InputBuffer const* skBytesBuffer) +{ + char* message = new char[1000]; + char* error = new char[1000]; + memset(message, 0, 1000); + memset(error, 0, 1000); + BigNum expectedSum(0); + auto fakedArgs = + fakeMySQLParameters(nullptr, &algorithmType, &mode, ivBytesBuffer, skBytesBuffer); + std::cout << "#### testSymDec" << std::endl; + bcos::bytes cipherData(symmetric_block_size(algorithmType) + plainTextBytesBuffer->len); + OutputBuffer cipherBuffer{cipherData.data(), cipherData.size()}; + symmetric_encrypt( + &cipherBuffer, algorithmType, mode, skBytesBuffer, ivBytesBuffer, plainTextBytesBuffer); + + // encrypt and decrypt test + // std::cout << "### before dec, plain: " + // << std::string(plainTextBytesBuffer->data, + // plainTextBytesBuffer->data + plainTextBytesBuffer->len) + // << std::endl; + // std::cout << "#### decrypt, cipher len: " << cipherBuffer.len << std::endl; + // bcos::bytes plain(cipherBuffer.len + symmetric_block_size(algorithmType)); + // OutputBuffer plainBuffer{plain.data(), plain.size()}; + // InputBuffer cipherBuffer2{cipherBuffer.data, cipherBuffer.len}; + // symmetric_decrypt( + // &plainBuffer, algorithmType, mode, skBytesBuffer, ivBytesBuffer, &cipherBuffer2); + // std::cout << "#### error: " << get_last_error_msg() << std::endl; + // std::cout << "#### decrypt end: " << std::string(plain.begin(), plain.end()) + // << "# len: " << plainBuffer.len << ", size: " << plain.size() << std::endl; + + InputBuffer cipherBytes{cipherData.data(), cipherBuffer.len}; + // convert cipherBytes to hex + auto hexCipher = *(bcos::toHexString(cipherData.data(), cipherData.data() + cipherBuffer.len)); + std::cout << "#### hexCipher: " << hexCipher << std::endl; + fakedArgs.second->args[0] = (char*)hexCipher.data(); + fakedArgs.second->lengths[0] = hexCipher.size(); + + auto hexIv = + *(bcos::toHexString(ivBytesBuffer->data, ivBytesBuffer->data + ivBytesBuffer->len)); + // InputBuffer ivHexBuffer{(const unsigned char*)hexIv.data(), hexIv.size()}; + fakedArgs.second->args[3] = (char*)hexIv.data(); + fakedArgs.second->lengths[3] = hexIv.size(); + std::cout << "#### fakeMySQLParameters iv:" << fakedArgs.second->args[3] << std::endl; + std::cout << "#### fakeMySQLParameters iv len:" << fakedArgs.second->lengths[3] << std::endl; + + auto hexSk = + *(bcos::toHexString(skBytesBuffer->data, skBytesBuffer->data + skBytesBuffer->len)); + // InputBuffer skHexBuffer{(const unsigned char*)hexSk.data(), hexSk.size()}; + fakedArgs.second->args[4] = (char*)hexSk.data(); + fakedArgs.second->lengths[4] = hexSk.size(); + std::cout << "fakeMySQLParameters sk:" << fakedArgs.second->args[4] << std::endl; + std::cout << "fakeMySQLParameters sk len:" << fakedArgs.second->lengths[4] << std::endl; + + std::cout << "args[0]" << fakedArgs.second->args[0] << std::endl; + std::cout << "lengths[0]" << fakedArgs.second->lengths[0] << std::endl; + std::cout << "args[1]" << fakedArgs.second->args[1] << std::endl; + std::cout << "lengths[1]" << fakedArgs.second->lengths[1] << std::endl; + std::cout << "args[2]" << fakedArgs.second->args[2] << std::endl; + std::cout << "lengths[2]" << fakedArgs.second->lengths[2] << std::endl; + std::cout << "args[3]" << fakedArgs.second->args[3] << std::endl; + std::cout << "lengths[3]" << fakedArgs.second->lengths[3] << std::endl; + std::cout << "args[4]" << fakedArgs.second->args[4] << std::endl; + std::cout << "lengths[4]" << fakedArgs.second->lengths[4] << std::endl; + + std::cout << "#### before init" << std::endl; + auto start = std::chrono::high_resolution_clock::now(); + auto ret = sym_dec_init(fakedArgs.first, fakedArgs.second, message); + // init failed + if (ret) + { + std::cout << "#### init fail" << std::endl; + return; + } + std::cout << "#### init success" << std::endl; + // obtain the result + char* result = new char[fakedArgs.first->max_length]; + unsigned long length; + auto decryptV = sym_dec(fakedArgs.first, fakedArgs.second, result, &length, nullptr, error); + auto end = std::chrono::high_resolution_clock::now(); + auto duration = std::chrono::duration_cast(end - start).count(); + // Print the execution time + std::cout << " sym execution time: " << duration << " microseconds" << std::endl; + auto plainText = plainTextBytesBuffer->data; + std::cout << "#### sym pV: " << plainText << std::endl; + std::cout << "#### sym pV len: " << plainTextBytesBuffer->len << std::endl; + std::cout << "#### sym dV: " << decryptV << std::endl; + std::cout << "#### sym dV len : " << strlen(decryptV) << std::endl; + BOOST_CHECK(*plainText == *decryptV); + sym_dec_deinit(fakedArgs.first); + delete fakedArgs.first; + delete fakedArgs.second; + if (message) + { + delete[] message; + } + if (error) + { + delete[] error; + } +} + +void testSymDecUDFImpl(int algorithmType, int mode) +{ + srand(bcos::utcSteadyTime()); + // std::string plainText = "Hello, World, Hello Tomorrow."; + std::string plainText = "caryliao"; + bcos::bytes plainTextBytes(plainText.begin(), plainText.end()); + // auto hexPlain = *(bcos::toHexString(plainTextBytes)); + // InputBuffer plainTextBytesBuffer{(const unsigned char*)hexPlain.data(), hexPlain.size()}; + InputBuffer plainTextBytesBuffer{ + (const unsigned char*)plainTextBytes.data(), plainTextBytes.size()}; + std::cout << "plain:" << plainTextBytesBuffer.data << std::endl; + + std::string iv = "0123456789abcdef"; + bcos::bytes ivBytes(iv.begin(), iv.end()); + InputBuffer ivBytesBuffer{(const unsigned char*)ivBytes.data(), ivBytes.size()}; + std::cout << "#### symmetric_key_bytes(algorithmType, mode):" + << symmetric_key_bytes(algorithmType, mode) << std::endl; + if (get_last_error() != 0) + { + std::cout << "error: " << get_last_error_msg() << std::endl; + } + bcos::bytes skBytes(symmetric_key_bytes(algorithmType, mode), 0); + OutputBuffer skBuffer{skBytes.data(), skBytes.size()}; + symmetric_generate_key(&skBuffer, algorithmType, mode); + + // convert to hexedSk + InputBuffer skBytesBuffer{(const unsigned char*)skBytes.data(), skBytes.size()}; + testSymDec(&plainTextBytesBuffer, algorithmType, mode, &ivBytesBuffer, &skBytesBuffer); +} + +BOOST_AUTO_TEST_CASE(testSymDecUDF) +{ + std::cout << "run AES_128 ECB" << std::endl; + testSymDecUDFImpl( + static_cast(AlgorithmType::AES_128), static_cast(SymCrypto::OperationMode::ECB)); + std::cout << "run AES_128 CBC" << std::endl; + testSymDecUDFImpl( + static_cast(AlgorithmType::AES_128), static_cast(SymCrypto::OperationMode::CBC)); + std::cout << "run AES_128 CFB" << std::endl; + testSymDecUDFImpl( + static_cast(AlgorithmType::AES_128), static_cast(SymCrypto::OperationMode::CFB)); + std::cout << "run AES_128 CTR" << std::endl; + testSymDecUDFImpl( + static_cast(AlgorithmType::AES_128), static_cast(SymCrypto::OperationMode::CTR)); + std::cout << "run AES_192 OFB" << std::endl; + testSymDecUDFImpl( + static_cast(AlgorithmType::AES_192), static_cast(SymCrypto::OperationMode::OFB)); + std::cout << "run AES_256 CTR" << std::endl; + testSymDecUDFImpl( + static_cast(AlgorithmType::AES_256), static_cast(SymCrypto::OperationMode::CTR)); + + std::cout << "run TrippleDES ECB" << std::endl; + testSymDecUDFImpl(static_cast(AlgorithmType::TrippleDES), + static_cast(SymCrypto::OperationMode::ECB)); + std::cout << "run TrippleDES CBC" << std::endl; + testSymDecUDFImpl(static_cast(AlgorithmType::TrippleDES), + static_cast(SymCrypto::OperationMode::CBC)); + std::cout << "run TrippleDES CFB" << std::endl; + testSymDecUDFImpl(static_cast(AlgorithmType::TrippleDES), + static_cast(SymCrypto::OperationMode::CFB)); + std::cout << "run TrippleDES OFB" << std::endl; + testSymDecUDFImpl(static_cast(AlgorithmType::TrippleDES), + static_cast(SymCrypto::OperationMode::OFB)); + + std::cout << "run SM4 ECB" << std::endl; + testSymDecUDFImpl( + static_cast(AlgorithmType::SM4), static_cast(SymCrypto::OperationMode::ECB)); + std::cout << "run SM4 CBC" << std::endl; + testSymDecUDFImpl( + static_cast(AlgorithmType::SM4), static_cast(SymCrypto::OperationMode::CBC)); + std::cout << "run SM4 CFB" << std::endl; + testSymDecUDFImpl( + static_cast(AlgorithmType::SM4), static_cast(SymCrypto::OperationMode::CFB)); + std::cout << "run SM4 OFB" << std::endl; + testSymDecUDFImpl( + static_cast(AlgorithmType::SM4), static_cast(SymCrypto::OperationMode::OFB)); + std::cout << "run SM4 CTR" << std::endl; + testSymDecUDFImpl( + static_cast(AlgorithmType::SM4), static_cast(SymCrypto::OperationMode::CTR)); +} + +BOOST_AUTO_TEST_SUITE_END() +} // namespace ppc::test diff --git a/cpp/wedpr-crypto/ppc-udf/tests/SymEncUDFTest.cpp b/cpp/wedpr-crypto/ppc-udf/tests/SymEncUDFTest.cpp new file mode 100644 index 00000000..b3197438 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-udf/tests/SymEncUDFTest.cpp @@ -0,0 +1,228 @@ +/* + * 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 applicabl 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 SymEncUDFTest.cpp + * @author: caryliao + * @date 2023-10-25 + */ +#include "openssl/bn.h" +#include "ppc-crypto-c-sdk/symmetric_encryption.h" +#include "ppc-crypto-c-sdk/utils/error.h" +#include "ppc-framework/crypto/SymCrypto.h" +#include "ppc-framework/libwrapper/BigNum.h" +#include "ppc-framework/libwrapper/Buffer.h" +#include "ppc-udf/mysql/sym_enc.h" +#include +#include +#include + +using namespace bcos; +using namespace bcos::test; +using namespace ppc; +using namespace ppc::crypto; + +namespace ppc::test +{ +BOOST_FIXTURE_TEST_SUITE(symEncUDFTest, TestPromptFixture) + +std::pair fakeMySQLParameters(InputBuffer const* plainBytes, + int* algorithmType, int* mode, InputBuffer const* ivBytesBuffer, InputBuffer const* skBytesBuffer) +{ + UDF_INIT* initid = new UDF_INIT(); + UDF_ARGS* args = new UDF_ARGS(); + args->arg_count = 5; + args->args = new char*[5]; + args->lengths = new unsigned long[5]; + args->arg_type = new Item_result[5]; + if (plainBytes) + { + args->args[0] = (char*)plainBytes->data; + args->lengths[0] = plainBytes->len; + } + args->args[1] = (char*)algorithmType; + args->lengths[1] = sizeof(int); + args->args[2] = (char*)mode; + args->lengths[2] = sizeof(int); + + args->arg_type[0] = STRING_RESULT; + args->arg_type[1] = INT_RESULT; + args->arg_type[2] = INT_RESULT; + args->arg_type[3] = STRING_RESULT; + args->arg_type[4] = STRING_RESULT; + return std::make_pair(initid, args); +} + +void testSymEnc(InputBuffer const* plainTextBytesBuffer, int algorithmType, int mode, + InputBuffer const* ivBytesBuffer, InputBuffer const* skBytesBuffer) +{ + char* message = new char[1000]; + char* error = new char[1000]; + memset(message, 0, 1000); + memset(error, 0, 1000); + BigNum expectedSum(0); + auto fakedArgs = + fakeMySQLParameters(nullptr, &algorithmType, &mode, ivBytesBuffer, skBytesBuffer); + std::cout << "#### testSymEnc" << std::endl; + fakedArgs.second->args[0] = (char*)plainTextBytesBuffer->data; + fakedArgs.second->lengths[0] = plainTextBytesBuffer->len; + + auto hexIv = + *(bcos::toHexString(ivBytesBuffer->data, ivBytesBuffer->data + ivBytesBuffer->len)); + // InputBuffer ivHexBuffer{(const unsigned char*)hexIv.data(), hexIv.size()}; + fakedArgs.second->args[3] = (char*)hexIv.data(); + fakedArgs.second->lengths[3] = hexIv.size(); + std::cout << "#### fakeMySQLParameters iv:" << fakedArgs.second->args[3] << std::endl; + std::cout << "#### fakeMySQLParameters iv len:" << fakedArgs.second->lengths[3] << std::endl; + + auto hexSk = + *(bcos::toHexString(skBytesBuffer->data, skBytesBuffer->data + skBytesBuffer->len)); + // InputBuffer skHexBuffer{(const unsigned char*)hexSk.data(), hexSk.size()}; + fakedArgs.second->args[4] = (char*)hexSk.data(); + fakedArgs.second->lengths[4] = hexSk.size(); + std::cout << "fakeMySQLParameters sk:" << fakedArgs.second->args[4] << std::endl; + std::cout << "fakeMySQLParameters sk len:" << fakedArgs.second->lengths[4] << std::endl; + + std::cout << "args[0]" << fakedArgs.second->args[0] << std::endl; + std::cout << "lengths[0]" << fakedArgs.second->lengths[0] << std::endl; + std::cout << "args[1]" << fakedArgs.second->args[1] << std::endl; + std::cout << "lengths[1]" << fakedArgs.second->lengths[1] << std::endl; + std::cout << "args[2]" << fakedArgs.second->args[2] << std::endl; + std::cout << "lengths[2]" << fakedArgs.second->lengths[2] << std::endl; + std::cout << "args[3]" << fakedArgs.second->args[3] << std::endl; + std::cout << "lengths[3]" << fakedArgs.second->lengths[3] << std::endl; + std::cout << "args[4]" << fakedArgs.second->args[4] << std::endl; + std::cout << "lengths[4]" << fakedArgs.second->lengths[4] << std::endl; + + std::cout << "#### before init" << std::endl; + auto start = std::chrono::high_resolution_clock::now(); + auto ret = sym_enc_init(fakedArgs.first, fakedArgs.second, message); + // init failed + if (ret) + { + std::cout << "#### init fail" << std::endl; + return; + } + std::cout << "#### init success" << std::endl; + // obtain the result + char* result = new char[fakedArgs.first->max_length]; + unsigned long length; + auto cipherValue = sym_enc(fakedArgs.first, fakedArgs.second, result, &length, nullptr, error); + auto end = std::chrono::high_resolution_clock::now(); + auto duration = std::chrono::duration_cast(end - start).count(); + // Print the execution time + std::cout << " sym execution time: " << duration << " microseconds" << std::endl; + std::cout << "#### sym cipher: " << cipherValue << std::endl; + std::cout << "#### sym cipher len : " << strlen(cipherValue) << std::endl; + + bcos::bytes cipherData(symmetric_block_size(algorithmType) + plainTextBytesBuffer->len); + OutputBuffer cipherBuffer{cipherData.data(), cipherData.size()}; + symmetric_encrypt( + &cipherBuffer, algorithmType, mode, skBytesBuffer, ivBytesBuffer, plainTextBytesBuffer); + + BOOST_CHECK(strlen(cipherValue) != 0); + BOOST_CHECK(*cipherData.data() = *cipherValue); + sym_enc_deinit(fakedArgs.first); + delete fakedArgs.first; + delete fakedArgs.second; + if (message) + { + delete[] message; + } + if (error) + { + delete[] error; + } +} + +void testSymEncUDFImpl(int algorithmType, int mode) +{ + srand(bcos::utcSteadyTime()); + // std::string plainText = "Hello, World, Hello Tomorrow."; + std::string plainText = "caryliao"; + bcos::bytes plainTextBytes(plainText.begin(), plainText.end()); + // auto hexPlain = *(bcos::toHexString(plainTextBytes)); + // InputBuffer plainTextBytesBuffer{(const unsigned char*)hexPlain.data(), hexPlain.size()}; + InputBuffer plainTextBytesBuffer{ + (const unsigned char*)plainTextBytes.data(), plainTextBytes.size()}; + std::cout << "plain:" << plainTextBytesBuffer.data << std::endl; + + std::string iv = "0123456789abcdef"; + bcos::bytes ivBytes(iv.begin(), iv.end()); + InputBuffer ivBytesBuffer{(const unsigned char*)ivBytes.data(), ivBytes.size()}; + std::cout << "#### symmetric_key_bytes(algorithmType, mode):" + << symmetric_key_bytes(algorithmType, mode) << std::endl; + std::cout << "error: " << get_last_error_msg() << std::endl; + bcos::bytes skBytes(symmetric_key_bytes(algorithmType, mode), 0); + OutputBuffer skBuffer{skBytes.data(), skBytes.size()}; + symmetric_generate_key(&skBuffer, algorithmType, mode); + + // convert to hexedSk + InputBuffer skBytesBuffer{(const unsigned char*)skBytes.data(), skBytes.size()}; + testSymEnc(&plainTextBytesBuffer, algorithmType, mode, &ivBytesBuffer, &skBytesBuffer); +} + +BOOST_AUTO_TEST_CASE(testSymEncUDF) +{ + std::cout << "run AES_128 ECB" << std::endl; + testSymEncUDFImpl( + static_cast(AlgorithmType::AES_128), static_cast(SymCrypto::OperationMode::ECB)); + std::cout << "run AES_128 CBC" << std::endl; + testSymEncUDFImpl( + static_cast(AlgorithmType::AES_128), static_cast(SymCrypto::OperationMode::CBC)); + std::cout << "run AES_128 CFB" << std::endl; + testSymEncUDFImpl( + static_cast(AlgorithmType::AES_128), static_cast(SymCrypto::OperationMode::CFB)); + std::cout << "run AES_128 CTR" << std::endl; + testSymEncUDFImpl( + static_cast(AlgorithmType::AES_128), static_cast(SymCrypto::OperationMode::CTR)); + std::cout << "run AES_192 OFB" << std::endl; + testSymEncUDFImpl( + static_cast(AlgorithmType::AES_192), static_cast(SymCrypto::OperationMode::OFB)); + std::cout << "run AES_256 CTR" << std::endl; + testSymEncUDFImpl( + static_cast(AlgorithmType::AES_256), static_cast(SymCrypto::OperationMode::CTR)); + + std::cout << "run TrippleDES ECB" << std::endl; + testSymEncUDFImpl(static_cast(AlgorithmType::TrippleDES), + static_cast(SymCrypto::OperationMode::ECB)); + std::cout << "run TrippleDES CBC" << std::endl; + testSymEncUDFImpl(static_cast(AlgorithmType::TrippleDES), + static_cast(SymCrypto::OperationMode::CBC)); + std::cout << "run TrippleDES CFB" << std::endl; + testSymEncUDFImpl(static_cast(AlgorithmType::TrippleDES), + static_cast(SymCrypto::OperationMode::CFB)); + std::cout << "run TrippleDES OFB" << std::endl; + testSymEncUDFImpl(static_cast(AlgorithmType::TrippleDES), + static_cast(SymCrypto::OperationMode::OFB)); + + std::cout << "run SM4 ECB" << std::endl; + testSymEncUDFImpl( + static_cast(AlgorithmType::SM4), static_cast(SymCrypto::OperationMode::ECB)); + std::cout << "run SM4 CBC" << std::endl; + testSymEncUDFImpl( + static_cast(AlgorithmType::SM4), static_cast(SymCrypto::OperationMode::CBC)); + std::cout << "run SM4 CFB" << std::endl; + testSymEncUDFImpl( + static_cast(AlgorithmType::SM4), static_cast(SymCrypto::OperationMode::CFB)); + std::cout << "run SM4 OFB" << std::endl; + testSymEncUDFImpl( + static_cast(AlgorithmType::SM4), static_cast(SymCrypto::OperationMode::OFB)); + std::cout << "run SM4 CTR" << std::endl; + testSymEncUDFImpl( + static_cast(AlgorithmType::SM4), static_cast(SymCrypto::OperationMode::CTR)); +} + +BOOST_AUTO_TEST_SUITE_END() +} // namespace ppc::test diff --git a/cpp/wedpr-crypto/ppc-udf/tests/main.cpp b/cpp/wedpr-crypto/ppc-udf/tests/main.cpp new file mode 100644 index 00000000..2c06f9b5 --- /dev/null +++ b/cpp/wedpr-crypto/ppc-udf/tests/main.cpp @@ -0,0 +1,2 @@ +#define BOOST_TEST_MAIN +#include \ No newline at end of file diff --git a/cpp/wedpr-crypto/sdk/CMakeLists.txt b/cpp/wedpr-crypto/sdk/CMakeLists.txt new file mode 100644 index 00000000..5fb633c2 --- /dev/null +++ b/cpp/wedpr-crypto/sdk/CMakeLists.txt @@ -0,0 +1,12 @@ +# 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) + +if (TESTS) + enable_testing() + set(CTEST_OUTPUT_ON_FAILURE TRUE) + add_subdirectory(tests) +endif() diff --git a/cpp/wedpr-crypto/sdk/bindings/java/build.gradle b/cpp/wedpr-crypto/sdk/bindings/java/build.gradle new file mode 100644 index 00000000..b379d40b --- /dev/null +++ b/cpp/wedpr-crypto/sdk/bindings/java/build.gradle @@ -0,0 +1,199 @@ +plugins { + id 'java' + id 'idea' + id 'java-library' + id 'maven-publish' + //id 'org.ajoberstar.grgit' version '4.1.1' + //id "de.undercouch.download" version "4.1.2" +// id 'com.github.sherter.google-java-format' version '0.9' +} + +println("Notice: current gradle version is " + gradle.gradleVersion) +sourceCompatibility = 1.8 +targetCompatibility = 1.8 + +[compileJava, compileTestJava, javadoc]*.options*.encoding = 'UTF-8' + +repositories { + maven { url "https://maven.aliyun.com/nexus/content/groups/public/" } + maven { url "https://oss.sonatype.org/service/local/staging/deploy/maven2"} + maven { url "https://oss.sonatype.org/content/repositories/snapshots" } + maven {url "https://plugins.gradle.org/m2/"} + mavenCentral() + mavenLocal() +} + +// googleJavaFormat { +// toolVersion = '1.7' +// options style: 'AOSP' +// source = sourceSets*.allJava +// include '**/*.java' +// exclude '**/*Test.java' +// exclude '**/Test*.java' +// exclude '**/Mock*.java' +// } + +sourceSets { + main { + java { + srcDir 'src/main/java' + } + resources { + srcDir 'src/main/resources' + } + } + + jmh { + java { + srcDir 'src/jmh/java' + } + resources { + srcDir 'src/jmh/resources' + } + + runtimeClasspath += sourceSets.main.runtimeClasspath + compileClasspath += sourceSets.main.compileClasspath + + compileClasspath += main.output + runtimeClasspath += main.output + } +} +dependencies { + api ('org.slf4j:slf4j-api:1.7.36') + + jmhImplementation 'org.openjdk.jmh:jmh-core:1.36' + jmhAnnotationProcessor 'org.openjdk.jmh:jmh-generator-annprocess:1.36' + + testImplementation ('org.slf4j:slf4j-log4j12:1.7.36') + testImplementation ('junit:junit:4.13.2') +} + +archivesBaseName = 'ppc-crypto-sdk-jni' +group = 'com.webank.wedpr' +version = '1.0.0.20240325' + +// Additional attribute definition +ext { + if (!project.hasProperty("ossrhUsername")) { + ossrhUsername="xxx" + } + + if (!project.hasProperty("ossrhPassword")) { + ossrhPassword="xxx" + } +} + +jar { + exclude '**/*.xml' + exclude '**/*.properties' + /*manifest { + try { + def repo = grgit.open(currentDir: project.rootDir) + if (repo != null) { + + def date = new Date().format("yyyy-MM-dd'T'HH:mm:ssZ") + def branch = repo.branch.getCurrent().getName() + def commit = repo.head().getAbbreviatedId(40) + + attributes(["Implementation-Timestamp": date, + "Git-Branch" : branch, + "Git-Commit" : commit]) + } + } catch (Exception e) { + e.printStackTrace() + } + } from sourceSets.main.output*/ + + doLast { + copy { + from destinationDirectory + into 'dist/apps' + } + + copy { + from configurations.runtimeClasspath + into 'dist/lib' + } + } +} + +javadoc { + options.addStringOption('Xdoclint:none', '-quiet') + options.addStringOption('encoding', 'UTF-8') + options.addStringOption('charSet', 'UTF-8') +} + +task sourcesJar(type: Jar) { + from sourceSets.main.allJava + archiveClassifier = 'sources' + duplicatesStrategy 'exclude' +} +tasks.withType(Copy).all { + duplicatesStrategy 'exclude' +} + + +task javadocJar(type: Jar) { + from javadoc + archiveClassifier = 'javadoc' +} + +task jmh(type: JavaExec, dependsOn: jmhClasses) { + main = 'com.webank.wedpr.sdk.jni.jmh.BenchmarkMain' + classpath = sourceSets.jmh.compileClasspath + sourceSets.jmh.runtimeClasspath +} + +publishing { + publications { + mavenJava(MavenPublication) { + + artifactId project.name + groupId project.group + version project.version + + from components.java + artifact sourcesJar + artifact javadocJar + + pom { + name = 'wedpr' + description = 'wedpr ppc-crypto-sdk-jni' + url = 'http://www.fisco-bcos.org' + + licenses { + license { + name = 'The Apache License, Version 2.0' + url = 'http://www.apache.org/licenses/LICENSE-2.0.txt' + } + } + scm { + connection = 'http://github.com/WeBankBlockchain/wedpr-components.git' + url = 'http://github.com/WeBankBlockchain/wedpr-components.git' + } + + developers { + developer { + id = 'zhangsan' + name = 'zhangsan' + email = 'zhangsan@example.com' + } + } + } + } + } + repositories { + maven { + def releasesRepoURL = "https://oss.sonatype.org/service/local/staging/deploy/maven2" + def snapshotsRepoURL = "https://oss.sonatype.org/content/repositories/snapshots" + allowInsecureProtocol = true + url = !version.endsWith("SNAPSHOT") ? releasesRepoURL : snapshotsRepoURL + + credentials { + username 'deployment' + password 'deployment123' + } + } + } + +} + diff --git a/cpp/wedpr-crypto/sdk/bindings/java/gradle/wrapper/gradle-wrapper.jar b/cpp/wedpr-crypto/sdk/bindings/java/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 00000000..e708b1c0 Binary files /dev/null and b/cpp/wedpr-crypto/sdk/bindings/java/gradle/wrapper/gradle-wrapper.jar differ diff --git a/cpp/wedpr-crypto/sdk/bindings/java/gradle/wrapper/gradle-wrapper.properties b/cpp/wedpr-crypto/sdk/bindings/java/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 00000000..a33e7343 --- /dev/null +++ b/cpp/wedpr-crypto/sdk/bindings/java/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +# distributionUrl=https\://services.gradle.org/distributions/gradle-7.3-bin.zip +distributionUrl=https://mirrors.cloud.tencent.com/gradle/gradle-7.3-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/cpp/wedpr-crypto/sdk/bindings/java/gradlew b/cpp/wedpr-crypto/sdk/bindings/java/gradlew new file mode 100644 index 00000000..4f906e0c --- /dev/null +++ b/cpp/wedpr-crypto/sdk/bindings/java/gradlew @@ -0,0 +1,185 @@ +#!/usr/bin/env sh + +# +# Copyright 2015 the original author or authors. +# +# 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 +# +# https://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. +# + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$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 "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# 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 + ;; + 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" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin or MSYS, switch paths to Windows format before running java +if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=`expr $i + 1` + done + case $i in + 0) set -- ;; + 1) set -- "$args0" ;; + 2) set -- "$args0" "$args1" ;; + 3) set -- "$args0" "$args1" "$args2" ;; + 4) set -- "$args0" "$args1" "$args2" "$args3" ;; + 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=`save "$@"` + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +exec "$JAVACMD" "$@" diff --git a/cpp/wedpr-crypto/sdk/bindings/java/gradlew.bat b/cpp/wedpr-crypto/sdk/bindings/java/gradlew.bat new file mode 100644 index 00000000..ac1b06f9 --- /dev/null +++ b/cpp/wedpr-crypto/sdk/bindings/java/gradlew.bat @@ -0,0 +1,89 @@ +@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%" == "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%"=="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! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/cpp/wedpr-crypto/sdk/bindings/java/settings.gradle b/cpp/wedpr-crypto/sdk/bindings/java/settings.gradle new file mode 100644 index 00000000..4f80dfb3 --- /dev/null +++ b/cpp/wedpr-crypto/sdk/bindings/java/settings.gradle @@ -0,0 +1,2 @@ +rootProject.name = 'ppc-crypto-sdk-jni' + diff --git a/cpp/wedpr-crypto/sdk/bindings/java/src/jmh/java/com/webank/wedpr/sdk/jni/jmh/BenchmarkMain.java b/cpp/wedpr-crypto/sdk/bindings/java/src/jmh/java/com/webank/wedpr/sdk/jni/jmh/BenchmarkMain.java new file mode 100644 index 00000000..4100ca99 --- /dev/null +++ b/cpp/wedpr-crypto/sdk/bindings/java/src/jmh/java/com/webank/wedpr/sdk/jni/jmh/BenchmarkMain.java @@ -0,0 +1,27 @@ +package com.webank.wedpr.sdk.jni.jmh; + +import java.util.concurrent.TimeUnit; +import org.openjdk.jmh.results.format.ResultFormatType; +import org.openjdk.jmh.runner.Runner; +import org.openjdk.jmh.runner.options.Options; +import org.openjdk.jmh.runner.options.OptionsBuilder; +import org.openjdk.jmh.runner.options.TimeValue; + +public class BenchmarkMain { + public static void main(String[] args) throws Exception { + Options opt = + new OptionsBuilder() + .include("com.webank.wedpr.sdk.jni.jmh.*") + .forks(1) + .timeUnit(TimeUnit.NANOSECONDS) + .warmupIterations(5) + .warmupTime(TimeValue.valueOf("1s")) + .measurementIterations(60) + .measurementTime(TimeValue.valueOf("1s")) + // .resultFormat(ResultFormatType.JSON) + .resultFormat(ResultFormatType.TEXT) + .build(); + + new Runner(opt).run(); + } +} \ No newline at end of file diff --git a/cpp/wedpr-crypto/sdk/bindings/java/src/jmh/java/com/webank/wedpr/sdk/jni/jmh/PaillierBenchmark.java b/cpp/wedpr-crypto/sdk/bindings/java/src/jmh/java/com/webank/wedpr/sdk/jni/jmh/PaillierBenchmark.java new file mode 100644 index 00000000..d9e2c34f --- /dev/null +++ b/cpp/wedpr-crypto/sdk/bindings/java/src/jmh/java/com/webank/wedpr/sdk/jni/jmh/PaillierBenchmark.java @@ -0,0 +1,101 @@ +package com.webank.wedpr.sdk.jni.jmh; + +import com.webank.wedpr.sdk.jni.common.JniException; +import com.webank.wedpr.sdk.jni.homo.Paillier; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.TearDown; +import org.openjdk.jmh.annotations.Warmup; +import org.openjdk.jmh.runner.Runner; +import org.openjdk.jmh.runner.options.Options; +import org.openjdk.jmh.runner.options.OptionsBuilder; + +import java.math.BigInteger; +import java.util.concurrent.TimeUnit; + +@State(Scope.Thread) +@BenchmarkMode(Mode.AverageTime) +@OutputTimeUnit(TimeUnit.NANOSECONDS) +@Warmup(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS) +@Measurement(iterations = 120, time = 1, timeUnit = TimeUnit.SECONDS) +public class PaillierBenchmark +{ + private Paillier paillier = new Paillier(); + // the keypair + private long keypair; + // the public key + private long publickey; + // m1 + private byte[] m1; + // m2 + private byte[] m2; + // v + private byte[] v; + int keyBits; + // cipher1 + public byte[] c1; + public byte[] c2; + + @Setup + public void setup() throws JniException { + m1 = BigInteger.valueOf(System.currentTimeMillis()).toByteArray(); + m2 = BigInteger.valueOf(System.currentTimeMillis() + 100000).toByteArray(); + v = BigInteger.valueOf(2134234).toByteArray(); + keyBits = 2048; + keypair = paillier.generateKeyPair(2048); + publickey = paillier.getPublicKeyJniObject(keypair); + c1 = paillier.encryptFast(m1, keypair); + c2 = paillier.encryptFast(m2, keypair); + } + + @TearDown + public void tearDown() { + // Clean up resources if needed + } + + @Benchmark + public void generateKeyPair() throws JniException { + paillier.generateKeyPair(keyBits); + } + + @Benchmark + public void encryptionFast() throws JniException { + paillier.encryptFast(m1, keypair); + } + + @Benchmark + public void encrypt() throws JniException { + paillier.encrypt(m1, publickey); + } + + @Benchmark + public void decryption() throws JniException { + paillier.decrypt(c1, keypair); + } + + @Benchmark + public void add() throws JniException { + paillier.add(c1, c2, publickey); + } + + @Benchmark + public void sub() throws JniException { + paillier.sub(c1, c2, publickey); + } + + @Benchmark + public void scalaMul() throws JniException { + paillier.scalaMul(v, c1, publickey); + } + + public static void main(String[] args) throws Exception { + Options opt = new OptionsBuilder().include(PaillierBenchmark.class.getSimpleName()).forks(1).build(); + new Runner(opt).run(); + } +} \ No newline at end of file diff --git a/cpp/wedpr-crypto/sdk/bindings/java/src/main/c/CMakeLists.txt b/cpp/wedpr-crypto/sdk/bindings/java/src/main/c/CMakeLists.txt new file mode 100644 index 00000000..94a27864 --- /dev/null +++ b/cpp/wedpr-crypto/sdk/bindings/java/src/main/c/CMakeLists.txt @@ -0,0 +1,14 @@ +# source +file(GLOB_RECURSE SOURCES "jni/*.h" "jni/*.cpp" "jni/*.c") + +add_library(${PPC_CRYPTO_SDK_JNI_TARGET} SHARED ${SOURCES}) +target_link_libraries(${PPC_CRYPTO_SDK_JNI_TARGET} PUBLIC ${PPC_CRYPTO_C_SDK_STATIC_TARGET}) + +add_library(${PPC_CRYPTO_SDK_JNI_STATIC_TARGET} ${SOURCES}) +target_link_libraries(${PPC_CRYPTO_SDK_JNI_STATIC_TARGET} PUBLIC ${PPC_CRYPTO_C_SDK_STATIC_TARGET}) + + +SET(LIBRARY_OUTPUT_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../resources/META-INF/native/) + +message(STATUS "CMAKE_INSTALL_INCLUDEDIR => ${CMAKE_INSTALL_INCLUDEDIR}") +message(STATUS "CMAKE_CURRENT_SOURCE_DIR => ${CMAKE_CURRENT_SOURCE_DIR}") \ No newline at end of file diff --git a/cpp/wedpr-crypto/sdk/bindings/java/src/main/c/jni/Common.cpp b/cpp/wedpr-crypto/sdk/bindings/java/src/main/c/jni/Common.cpp new file mode 100644 index 00000000..62dc727f --- /dev/null +++ b/cpp/wedpr-crypto/sdk/bindings/java/src/main/c/jni/Common.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 Common.cpp + * @author: yujiechen + * @date 2023-08-30 + */ +#include "Common.h" +#include "JNIException.h" +#include "openssl/err.h" +#include + +// convert java bytes to InputBuffer +InputBuffer convertToInputBuffer(bcos::bytes& resultBuffer, JNIEnv* env, jbyteArray arrayData) +{ + resultBuffer.resize(env->GetArrayLength(arrayData)); + env->GetByteArrayRegion(arrayData, 0, resultBuffer.size(), (jbyte*)resultBuffer.data()); + return InputBuffer{resultBuffer.data(), resultBuffer.size()}; +} + +jbyteArray BigNumToJavaBigIntegerBytes(JNIEnv* env, BIGNUM* value) +{ + if (!value) + { + THROW_JNI_EXCEPTION(env, "Not support convert null big-num to big-integer!"); + return NULL; + } + auto resultLen = BN_num_bytes(value) + 1; + bcos::bytes valueBin(resultLen); + if (BN_bn2bin(value, valueBin.data() + 1) < 0) + { + THROW_JNI_EXCEPTION( + env, "BN_bn2bin error: " + std::string(ERR_error_string(ERR_get_error(), NULL))); + return NULL; + } + // negative case + if (BN_is_negative(value)) + { + bool carry = true; + for (int64_t i = resultLen - 1; i >= 0; i--) + { + valueBin[i] ^= 0xff; + if (carry) + { + carry = (++(valueBin[i])) == 0; + } + } + valueBin[0] |= 0x80; + } + else + { + valueBin[0] = 0x00; + } + jbyteArray ret = env->NewByteArray(resultLen); + env->SetByteArrayRegion(ret, 0, resultLen, (jbyte*)valueBin.data()); + return ret; +} + +// convert java big-integer to openssl BIGNUM +ppc::crypto::BigNum JavaBigIntegerToBigNum(JNIEnv* env, jbyteArray bigIntegerData) +{ + bcos::bytes javaBigIntegerBytes; + convertToInputBuffer(javaBigIntegerBytes, env, bigIntegerData); + unsigned char* data = javaBigIntegerBytes.data(); + unsigned char* pData = data; + auto len = javaBigIntegerBytes.size(); + ppc::crypto::BigNum result; + // zero + if (0 == len) + { + BN_zero(result.bn().get()); + return result; + } + bool negative = (data[0] & 0x80) != 0; + // convert to two's complement if negative + bcos::bytes twosComplement(len, 0); + if (negative) + { + bool carry = true; + for (int i = len - 1; i >= 0; i--) + { + twosComplement[i] = (data[i] ^ 0xFF); + if (carry) + { + carry = (++twosComplement[i]) == 0; + } + } + pData = twosComplement.data(); + } + // convert to BIGNUM + if (!BN_bin2bn(pData, len, result.bn().get())) + { + BN_clear_free(result.bn().get()); + THROW_JNI_EXCEPTION(env, "convert java bigInteger data to BigNum error" + + std::string(ERR_error_string(ERR_get_error(), NULL))); + } + if (negative) + { + BN_set_negative(result.bn().get(), 1); + } + return result; +} \ No newline at end of file diff --git a/cpp/wedpr-crypto/sdk/bindings/java/src/main/c/jni/Common.h b/cpp/wedpr-crypto/sdk/bindings/java/src/main/c/jni/Common.h new file mode 100644 index 00000000..e26fad72 --- /dev/null +++ b/cpp/wedpr-crypto/sdk/bindings/java/src/main/c/jni/Common.h @@ -0,0 +1,33 @@ +/** + * 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 Common.h + * @author: yujiechen + * @date 2023-08-14 + */ + +#pragma once + +#include "openssl/bn.h" +#include "ppc-framework/libwrapper/BigNum.h" +#include "ppc-framework/libwrapper/Buffer.h" +#include +#include + +// convert java bytes to InputBuffer +InputBuffer convertToInputBuffer(bcos::bytes& resultBuffer, JNIEnv* env, jbyteArray arrayData); +jbyteArray BigNumToJavaBigIntegerBytes(JNIEnv* env, BIGNUM* value); +// convert java big-integer to openssl BIGNUM +ppc::crypto::BigNum JavaBigIntegerToBigNum(JNIEnv* env, jbyteArray bigIntegerData); \ No newline at end of file diff --git a/cpp/wedpr-crypto/sdk/bindings/java/src/main/c/jni/JNIException.cpp b/cpp/wedpr-crypto/sdk/bindings/java/src/main/c/jni/JNIException.cpp new file mode 100644 index 00000000..e9a907de --- /dev/null +++ b/cpp/wedpr-crypto/sdk/bindings/java/src/main/c/jni/JNIException.cpp @@ -0,0 +1,49 @@ +/** + * 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 JNIException.cpp + * @author: yujiechen + * @date 2023-08-14 + */ +#include "JNIException.h" +#include +#include + +void ThrowJNIException(JNIEnv* env, const char* kpFile, int iLine, const std::string& message) +{ + const char* className = "com/webank/wedpr/sdk/jni/common/JniException"; + (void)kpFile; + (void)iLine; + + // Find the exception class. + jclass tClass = env->FindClass(className); + if (env->ExceptionCheck()) + { + env->ExceptionDescribe(); + env->ExceptionClear(); + tClass = env->FindClass("java/lang/Exception"); + if (tClass == NULL) + { + std::cerr << " Not found exception class: " + << "java/lang/Exception" << std::endl; + env->DeleteLocalRef(tClass); + return; + } + } + + // Throw the exception with error info + env->ThrowNew(tClass, message.c_str()); + env->DeleteLocalRef(tClass); +} diff --git a/cpp/wedpr-crypto/sdk/bindings/java/src/main/c/jni/JNIException.h b/cpp/wedpr-crypto/sdk/bindings/java/src/main/c/jni/JNIException.h new file mode 100644 index 00000000..6bf6dc22 --- /dev/null +++ b/cpp/wedpr-crypto/sdk/bindings/java/src/main/c/jni/JNIException.h @@ -0,0 +1,38 @@ +/** + * 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 JNIException.h + * @author: yujiechen + * @date 2023-08-14 + */ +#include +#include +/* Header for class common */ + +#ifndef __JNI_EXCEPTION_H__ +#define __JNI_EXCEPTION_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#define THROW_JNI_EXCEPTION(_ENV_, _INFO_) ThrowJNIException(_ENV_, __FILE__, __LINE__, _INFO_); + +void ThrowJNIException(JNIEnv* env, const char* kpFile, int iLine, const std::string& message); + +#ifdef __cplusplus +} +#endif +#endif \ No newline at end of file diff --git a/cpp/wedpr-crypto/sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_crypto_FastOre.cpp b/cpp/wedpr-crypto/sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_crypto_FastOre.cpp new file mode 100644 index 00000000..26218da3 --- /dev/null +++ b/cpp/wedpr-crypto/sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_crypto_FastOre.cpp @@ -0,0 +1,251 @@ +#include "com_webank_wedpr_sdk_jni_crypto_FastOre.h" +#include "Common.h" +#include "JNIException.h" +#include "ppc-crypto-c-sdk/fast_ore.h" +#include "ppc-crypto-c-sdk/utils/error.h" +#include + +/* + * Class: com_webank_wedpr_sdk_jni_crypto_FastOre + * Method: keyBytes + * Signature: ()I + */ +JNIEXPORT jint JNICALL Java_com_webank_wedpr_sdk_jni_crypto_FastOre_keyBytes(JNIEnv* env, jclass) +{ + auto keyBytes = fast_ore_key_bytes(); + if (!last_call_success()) + { + THROW_JNI_EXCEPTION(env, get_last_error_msg()); + } + return keyBytes; +} + +/* + * Class: com_webank_wedpr_sdk_jni_crypto_FastOre + * Method: cipherSize + * Signature: (JZ)J + */ +JNIEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_crypto_FastOre_cipherSize( + JNIEnv* env, jclass, jlong plainSize, jboolean hex) +{ + auto cipherSize = fast_ore_get_cipher_size(plainSize, hex); + if (!last_call_success()) + { + THROW_JNI_EXCEPTION(env, get_last_error_msg()); + } + return cipherSize; +} + +/* + * Class: com_webank_wedpr_sdk_jni_crypto_FastOre + * Method: plainSize + * Signature: (JZ)J + */ +JNIEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_crypto_FastOre_plainSize( + JNIEnv* env, jclass, jlong cipherSize, jboolean hex) +{ + auto plainSize = fast_ore_get_plain_size(cipherSize, hex); + if (!last_call_success()) + { + THROW_JNI_EXCEPTION(env, get_last_error_msg()); + } + return plainSize; +} + +/* + * Class: com_webank_wedpr_sdk_jni_crypto_FastOre + * Method: generateKey + * Signature: ()[B + */ +JNIEXPORT jbyteArray JNICALL Java_com_webank_wedpr_sdk_jni_crypto_FastOre_generateKey( + JNIEnv* env, jclass cls) +{ + auto keyBytes = Java_com_webank_wedpr_sdk_jni_crypto_FastOre_keyBytes(env, cls); + bcos::bytes keyData(keyBytes); + OutputBuffer keyBuffer{keyData.data(), keyData.size()}; + fast_ore_generate_key(&keyBuffer); + if (!last_call_success()) + { + THROW_JNI_EXCEPTION(env, get_last_error_msg()); + return nullptr; + } + auto jResult = env->NewByteArray(keyBuffer.len); + env->SetByteArrayRegion(jResult, 0, keyBuffer.len, (jbyte*)keyBuffer.data); + return jResult; +} + +/* + * Class: com_webank_wedpr_sdk_jni_crypto_FastOre + * Method: encrypt4String + * Signature: ([B[BZ)[B + */ +JNIEXPORT jbyteArray JNICALL Java_com_webank_wedpr_sdk_jni_crypto_FastOre_encrypt4String( + JNIEnv* env, jclass cls, jbyteArray sk, jbyteArray plainData, jboolean hex) +{ + bcos::bytes skBytes; + auto skBuffer = convertToInputBuffer(skBytes, env, sk); + bcos::bytes plainBytes; + auto plainBuffer = convertToInputBuffer(plainBytes, env, plainData); + bcos::bytes cipherBytes( + Java_com_webank_wedpr_sdk_jni_crypto_FastOre_cipherSize(env, cls, plainBuffer.len, hex)); + OutputBuffer cipherBuffer{cipherBytes.data(), cipherBytes.size()}; + string_fast_ore_encrypt(&cipherBuffer, &skBuffer, &plainBuffer, hex); + + if (!last_call_success()) + { + THROW_JNI_EXCEPTION(env, get_last_error_msg()); + return nullptr; + } + auto jResult = env->NewByteArray(cipherBuffer.len); + env->SetByteArrayRegion(jResult, 0, cipherBuffer.len, (jbyte*)cipherBuffer.data); + return jResult; +} + +/* + * Class: com_webank_wedpr_sdk_jni_crypto_FastOre + * Method: decrypt4String + * Signature: ([B[BZ)[B + */ +JNIEXPORT jbyteArray JNICALL Java_com_webank_wedpr_sdk_jni_crypto_FastOre_decrypt4String( + JNIEnv* env, jclass cls, jbyteArray sk, jbyteArray cipher, jboolean hex) +{ + bcos::bytes skBytes; + auto skBuffer = convertToInputBuffer(skBytes, env, sk); + bcos::bytes cipherBytes; + auto cipherBuffer = convertToInputBuffer(cipherBytes, env, cipher); + bcos::bytes plainBytes( + Java_com_webank_wedpr_sdk_jni_crypto_FastOre_plainSize(env, cls, cipherBuffer.len, hex)); + OutputBuffer plainBuffer{plainBytes.data(), plainBytes.size()}; + string_fast_ore_decrypt(&plainBuffer, &skBuffer, &cipherBuffer, hex); + if (!last_call_success()) + { + THROW_JNI_EXCEPTION(env, get_last_error_msg()); + return nullptr; + } + auto jResult = env->NewByteArray(plainBuffer.len); + env->SetByteArrayRegion(jResult, 0, plainBuffer.len, (jbyte*)plainBuffer.data); + return jResult; +} + +/* + * Class: com_webank_wedpr_sdk_jni_crypto_FastOre + * Method: encrypt4Integer + * Signature: ([BJZ)[B + */ +JNIEXPORT jbyteArray JNICALL Java_com_webank_wedpr_sdk_jni_crypto_FastOre_encrypt4Integer( + JNIEnv* env, jclass cls, jbyteArray sk, jlong plain, jboolean hex) +{ + bcos::bytes skBytes; + auto skBuffer = convertToInputBuffer(skBytes, env, sk); + bcos::bytes cipherBytes( + Java_com_webank_wedpr_sdk_jni_crypto_FastOre_cipherSize(env, cls, sizeof(plain), hex)); + OutputBuffer cipherBuffer{cipherBytes.data(), cipherBytes.size()}; + integer_fast_ore_encrypt(&cipherBuffer, &skBuffer, static_cast(plain), hex); + if (!last_call_success()) + { + THROW_JNI_EXCEPTION(env, get_last_error_msg()); + return nullptr; + } + auto jResult = env->NewByteArray(cipherBuffer.len); + env->SetByteArrayRegion(jResult, 0, cipherBuffer.len, (jbyte*)cipherBuffer.data); + return jResult; +} +/* + * Class: com_webank_wedpr_sdk_jni_crypto_FastOre + * Method: decrypt4Integer + * Signature: ([B[BZ)J + */ +JNIEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_crypto_FastOre_decrypt4Integer( + JNIEnv* env, jclass cls, jbyteArray sk, jbyteArray cipher, jboolean hex) +{ + bcos::bytes skBytes; + auto skBuffer = convertToInputBuffer(skBytes, env, sk); + bcos::bytes cipherBytes; + auto cipherBuffer = convertToInputBuffer(cipherBytes, env, cipher); + int64_t plain = 0; + integer_fast_ore_decrypt(&plain, &skBuffer, &cipherBuffer, hex); + if (!last_call_success()) + { + THROW_JNI_EXCEPTION(env, get_last_error_msg()); + return 0; + } + return plain; +} + +/* + * Class: com_webank_wedpr_sdk_jni_crypto_FastOre + * Method: encrypt4Float + * Signature: ([B[BZ)[B + */ +JNIEXPORT jbyteArray JNICALL Java_com_webank_wedpr_sdk_jni_crypto_FastOre_encrypt4Float( + JNIEnv* env, jclass, jbyteArray sk, jbyteArray plainData, jboolean hex) +{ + bcos::bytes skBytes; + auto skBuffer = convertToInputBuffer(skBytes, env, sk); + bcos::bytes plainBytes; + auto plainBuffer = convertToInputBuffer(plainBytes, env, plainData); + + bcos::bytes cipherBytes(fast_ore_get_float_cipher_size(plainBuffer.len, hex)); + if (!last_call_success()) + { + THROW_JNI_EXCEPTION(env, get_last_error_msg()); + return nullptr; + } + OutputBuffer cipherBuffer{cipherBytes.data(), cipherBytes.size()}; + float_fast_ore_encrypt(&cipherBuffer, &skBuffer, &plainBuffer, hex); + if (!last_call_success()) + { + THROW_JNI_EXCEPTION(env, get_last_error_msg()); + return nullptr; + } + auto jResult = env->NewByteArray(cipherBuffer.len); + env->SetByteArrayRegion(jResult, 0, cipherBuffer.len, (jbyte*)cipherBuffer.data); + return jResult; +} + +/* + * Class: com_webank_wedpr_sdk_jni_crypto_FastOre + * Method: decrypt4Float + * Signature: ([B[BZ)[B + */ +JNIEXPORT jbyteArray JNICALL Java_com_webank_wedpr_sdk_jni_crypto_FastOre_decrypt4Float( + JNIEnv* env, jclass, jbyteArray sk, jbyteArray cipherData, jboolean hex) +{ + bcos::bytes skBytes; + auto skBuffer = convertToInputBuffer(skBytes, env, sk); + bcos::bytes cipherBytes; + auto cipherBuffer = convertToInputBuffer(cipherBytes, env, cipherData); + + bcos::bytes plainBytes(64); + OutputBuffer plainBuffer{plainBytes.data(), plainBytes.size()}; + float_fast_ore_decrypt(&plainBuffer, &skBuffer, &cipherBuffer, hex); + if (!last_call_success()) + { + THROW_JNI_EXCEPTION(env, get_last_error_msg()); + return nullptr; + } + auto jResult = env->NewByteArray(plainBuffer.len); + env->SetByteArrayRegion(jResult, 0, plainBuffer.len, (jbyte*)plainBuffer.data); + return jResult; +} + +/* + * Class: com_webank_wedpr_sdk_jni_crypto_FastOre + * Method: compare + * Signature: ([B[B)I + */ +JNIEXPORT jint JNICALL Java_com_webank_wedpr_sdk_jni_crypto_FastOre_compare( + JNIEnv* env, jclass, jbyteArray c1, jbyteArray c2) +{ + bcos::bytes c1Bytes; + auto c1Buffer = convertToInputBuffer(c1Bytes, env, c1); + bcos::bytes c2Bytes; + auto c2Buffer = convertToInputBuffer(c2Bytes, env, c2); + auto ret = fast_ore_compare(&c1Buffer, &c2Buffer); + if (!last_call_success()) + { + THROW_JNI_EXCEPTION(env, get_last_error_msg()); + return -1; + } + return ret; +} diff --git a/cpp/wedpr-crypto/sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_crypto_FastOre.h b/cpp/wedpr-crypto/sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_crypto_FastOre.h new file mode 100644 index 00000000..8e332da7 --- /dev/null +++ b/cpp/wedpr-crypto/sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_crypto_FastOre.h @@ -0,0 +1,100 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class com_webank_wedpr_sdk_jni_crypto_FastOre */ + +#ifndef _Included_com_webank_wedpr_sdk_jni_crypto_FastOre +#define _Included_com_webank_wedpr_sdk_jni_crypto_FastOre +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: com_webank_wedpr_sdk_jni_crypto_FastOre + * Method: keyBytes + * Signature: ()I + */ +JNIEXPORT jint JNICALL Java_com_webank_wedpr_sdk_jni_crypto_FastOre_keyBytes(JNIEnv*, jclass); + +/* + * Class: com_webank_wedpr_sdk_jni_crypto_FastOre + * Method: cipherSize + * Signature: (JZ)J + */ +JNIEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_crypto_FastOre_cipherSize( + JNIEnv*, jclass, jlong, jboolean); + +/* + * Class: com_webank_wedpr_sdk_jni_crypto_FastOre + * Method: plainSize + * Signature: (JZ)J + */ +JNIEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_crypto_FastOre_plainSize( + JNIEnv*, jclass, jlong, jboolean); + +/* + * Class: com_webank_wedpr_sdk_jni_crypto_FastOre + * Method: generateKey + * Signature: ()[B + */ +JNIEXPORT jbyteArray JNICALL Java_com_webank_wedpr_sdk_jni_crypto_FastOre_generateKey( + JNIEnv*, jclass); + +/* + * Class: com_webank_wedpr_sdk_jni_crypto_FastOre + * Method: encrypt4String + * Signature: ([B[BZ)[B + */ +JNIEXPORT jbyteArray JNICALL Java_com_webank_wedpr_sdk_jni_crypto_FastOre_encrypt4String( + JNIEnv*, jclass, jbyteArray, jbyteArray, jboolean); + +/* + * Class: com_webank_wedpr_sdk_jni_crypto_FastOre + * Method: decrypt4String + * Signature: ([B[BZ)[B + */ +JNIEXPORT jbyteArray JNICALL Java_com_webank_wedpr_sdk_jni_crypto_FastOre_decrypt4String( + JNIEnv*, jclass, jbyteArray, jbyteArray, jboolean); + +/* + * Class: com_webank_wedpr_sdk_jni_crypto_FastOre + * Method: encrypt4Integer + * Signature: ([BJZ)[B + */ +JNIEXPORT jbyteArray JNICALL Java_com_webank_wedpr_sdk_jni_crypto_FastOre_encrypt4Integer( + JNIEnv*, jclass, jbyteArray, jlong, jboolean); + +/* + * Class: com_webank_wedpr_sdk_jni_crypto_FastOre + * Method: decrypt4Integer + * Signature: ([B[BZ)J + */ +JNIEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_crypto_FastOre_decrypt4Integer( + JNIEnv*, jclass, jbyteArray, jbyteArray, jboolean); + +/* + * Class: com_webank_wedpr_sdk_jni_crypto_FastOre + * Method: encrypt4Float + * Signature: ([B[BZ)[B + */ +JNIEXPORT jbyteArray JNICALL Java_com_webank_wedpr_sdk_jni_crypto_FastOre_encrypt4Float( + JNIEnv*, jclass, jbyteArray, jbyteArray, jboolean); + +/* + * Class: com_webank_wedpr_sdk_jni_crypto_FastOre + * Method: decrypt4Float + * Signature: ([B[BZ)[B + */ +JNIEXPORT jbyteArray JNICALL Java_com_webank_wedpr_sdk_jni_crypto_FastOre_decrypt4Float( + JNIEnv*, jclass, jbyteArray, jbyteArray, jboolean); + +/* + * Class: com_webank_wedpr_sdk_jni_crypto_FastOre + * Method: compare + * Signature: ([B[B)I + */ +JNIEXPORT jint JNICALL Java_com_webank_wedpr_sdk_jni_crypto_FastOre_compare( + JNIEnv*, jclass, jbyteArray, jbyteArray); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/cpp/wedpr-crypto/sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_crypto_SymmetricEncryption.cpp b/cpp/wedpr-crypto/sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_crypto_SymmetricEncryption.cpp new file mode 100644 index 00000000..c02b9be1 --- /dev/null +++ b/cpp/wedpr-crypto/sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_crypto_SymmetricEncryption.cpp @@ -0,0 +1,110 @@ +#include "com_webank_wedpr_sdk_jni_crypto_SymmetricEncryption.h" +#include "Common.h" +#include "JNIException.h" +#include "bcos-utilities/Common.h" +#include "ppc-crypto-c-sdk/symmetric_encryption.h" +#include "ppc-crypto-c-sdk/utils/error.h" +/* + * Class: com_webank_wedpr_sdk_jni_crypto_SymmetricEncryption + * Method: keyBytes + * Signature: (II)I + */ +JNIEXPORT jint JNICALL Java_com_webank_wedpr_sdk_jni_crypto_SymmetricEncryption_keyBytes( + JNIEnv* env, jclass, jint algorithmType, jint mode) +{ + auto keyBytes = symmetric_key_bytes(algorithmType, mode); + if (!last_call_success()) + { + THROW_JNI_EXCEPTION(env, get_last_error_msg()); + } + return keyBytes; +} + +/* + * Class: com_webank_wedpr_sdk_jni_crypto_SymmetricEncryption + * Method: generateKey + * Signature: (II)[B + */ +JNIEXPORT jbyteArray JNICALL Java_com_webank_wedpr_sdk_jni_crypto_SymmetricEncryption_generateKey( + JNIEnv* env, jclass, jint algorithmType, jint mode) +{ + bcos::bytes keyData(symmetric_key_bytes(algorithmType, mode)); + if (!last_call_success()) + { + THROW_JNI_EXCEPTION(env, get_last_error_msg()); + } + OutputBuffer keyBuffer{keyData.data(), keyData.size()}; + symmetric_generate_key(&keyBuffer, algorithmType, mode); + if (!last_call_success()) + { + THROW_JNI_EXCEPTION(env, get_last_error_msg()); + } + auto jResult = env->NewByteArray(keyBuffer.len); + env->SetByteArrayRegion(jResult, 0, keyBuffer.len, (jbyte*)keyBuffer.data); + return jResult; +} + +/* + * Class: com_webank_wedpr_sdk_jni_crypto_SymmetricEncryption + * Method: encrypt + * Signature: (II[B[B[B)[B + */ +JNIEXPORT jbyteArray JNICALL Java_com_webank_wedpr_sdk_jni_crypto_SymmetricEncryption_encrypt( + JNIEnv* env, jclass, jint algorithmType, jint mode, jbyteArray sk, jbyteArray iv, + jbyteArray plainData) +{ + bcos::bytes skBytes; + auto skBuffer = convertToInputBuffer(skBytes, env, sk); + bcos::bytes ivBytes; + auto ivBuffer = convertToInputBuffer(ivBytes, env, iv); + bcos::bytes plainBytes; + auto plainBuffer = convertToInputBuffer(plainBytes, env, plainData); + bcos::bytes cipherData(symmetric_block_size(algorithmType) + plainBuffer.len); + if (!last_call_success()) + { + THROW_JNI_EXCEPTION(env, get_last_error_msg()); + return nullptr; + } + OutputBuffer cipherBuffer{cipherData.data(), cipherData.size()}; + symmetric_encrypt(&cipherBuffer, algorithmType, mode, &skBuffer, &ivBuffer, &plainBuffer); + if (!last_call_success()) + { + THROW_JNI_EXCEPTION(env, get_last_error_msg()); + return nullptr; + } + auto jResult = env->NewByteArray(cipherBuffer.len); + env->SetByteArrayRegion(jResult, 0, cipherBuffer.len, (jbyte*)cipherBuffer.data); + return jResult; +} + +/* + * Class: com_webank_wedpr_sdk_jni_crypto_SymmetricEncryption + * Method: decrypt + * Signature: (II[B[B[B)[B + */ +JNIEXPORT jbyteArray JNICALL Java_com_webank_wedpr_sdk_jni_crypto_SymmetricEncryption_decrypt( + JNIEnv* env, jclass, jint algorithm, jint mode, jbyteArray sk, jbyteArray iv, jbyteArray cipher) +{ + bcos::bytes skBytes; + auto skBuffer = convertToInputBuffer(skBytes, env, sk); + bcos::bytes ivBytes; + auto ivBuffer = convertToInputBuffer(ivBytes, env, iv); + bcos::bytes cipherBytes; + auto cipherBuffer = convertToInputBuffer(cipherBytes, env, cipher); + bcos::bytes plainData(symmetric_block_size(algorithm) + cipherBuffer.len); + if (!last_call_success()) + { + THROW_JNI_EXCEPTION(env, get_last_error_msg()); + return nullptr; + } + OutputBuffer plainBuffer{plainData.data(), plainData.size()}; + symmetric_decrypt(&plainBuffer, algorithm, mode, &skBuffer, &ivBuffer, &cipherBuffer); + if (!last_call_success()) + { + THROW_JNI_EXCEPTION(env, get_last_error_msg()); + return nullptr; + } + auto jResult = env->NewByteArray(plainBuffer.len); + env->SetByteArrayRegion(jResult, 0, plainBuffer.len, (jbyte*)plainBuffer.data); + return jResult; +} \ No newline at end of file diff --git a/cpp/wedpr-crypto/sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_crypto_SymmetricEncryption.h b/cpp/wedpr-crypto/sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_crypto_SymmetricEncryption.h new file mode 100644 index 00000000..a220d023 --- /dev/null +++ b/cpp/wedpr-crypto/sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_crypto_SymmetricEncryption.h @@ -0,0 +1,45 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class com_webank_wedpr_sdk_jni_crypto_SymmetricEncryption */ + +#ifndef _Included_com_webank_wedpr_sdk_jni_crypto_SymmetricEncryption +#define _Included_com_webank_wedpr_sdk_jni_crypto_SymmetricEncryption +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: com_webank_wedpr_sdk_jni_crypto_SymmetricEncryption + * Method: keyBytes + * Signature: (II)I + */ +JNIEXPORT jint JNICALL Java_com_webank_wedpr_sdk_jni_crypto_SymmetricEncryption_keyBytes( + JNIEnv*, jclass, jint, jint); + +/* + * Class: com_webank_wedpr_sdk_jni_crypto_SymmetricEncryption + * Method: generateKey + * Signature: (II)[B + */ +JNIEXPORT jbyteArray JNICALL Java_com_webank_wedpr_sdk_jni_crypto_SymmetricEncryption_generateKey( + JNIEnv*, jclass, jint, jint); + +/* + * Class: com_webank_wedpr_sdk_jni_crypto_SymmetricEncryption + * Method: encrypt + * Signature: (II[B[B[B)[B + */ +JNIEXPORT jbyteArray JNICALL Java_com_webank_wedpr_sdk_jni_crypto_SymmetricEncryption_encrypt( + JNIEnv*, jclass, jint, jint, jbyteArray, jbyteArray, jbyteArray); + +/* + * Class: com_webank_wedpr_sdk_jni_crypto_SymmetricEncryption + * Method: decrypt + * Signature: (II[B[B[B)[B + */ +JNIEXPORT jbyteArray JNICALL Java_com_webank_wedpr_sdk_jni_crypto_SymmetricEncryption_decrypt( + JNIEnv*, jclass, jint, jint, jbyteArray, jbyteArray, jbyteArray); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/cpp/wedpr-crypto/sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_homo_NativeFloatingIhc.cpp b/cpp/wedpr-crypto/sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_homo_NativeFloatingIhc.cpp new file mode 100644 index 00000000..cc8677ef --- /dev/null +++ b/cpp/wedpr-crypto/sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_homo_NativeFloatingIhc.cpp @@ -0,0 +1,142 @@ +#include "com_webank_wedpr_sdk_jni_homo_NativeFloatingIhc.h" +#include "Common.h" +#include "JNIException.h" +#include "ppc-crypto-c-sdk/floating_point_ihc.h" +#include "ppc-crypto-c-sdk/homo_ihc.h" +#include "ppc-crypto-c-sdk/utils/error.h" +#include "ppc-framework/libwrapper/FloatingPointNumber.h" +#include +#include + +JNIEXPORT jbyteArray JNICALL Java_com_webank_wedpr_sdk_jni_homo_NativeFloatingIhc_generateKey( + JNIEnv* env, jclass, jint mode) +{ + bcos::bytes keyBytes(ihc_key_bytes(mode)); + OutputBuffer key{keyBytes.data(), keyBytes.size()}; + ihc_generate_key(&key, mode); + if (!last_call_success()) + { + THROW_JNI_EXCEPTION(env, get_last_error_msg()); + } + auto jResult = env->NewByteArray(key.len); + env->SetByteArrayRegion(jResult, 0, key.len, (jbyte*)key.data); + return jResult; +} + +JNIEXPORT jbyteArray JNICALL Java_com_webank_wedpr_sdk_jni_homo_NativeFloatingIhc_encrypt( + JNIEnv* env, jclass, jint mode, jbyteArray key, jbyteArray significant, jint exponent) +{ + bcos::bytes cipherBytes(ihc_floating_cipher_bytes(mode)); + if (!last_call_success()) + { + THROW_JNI_EXCEPTION(env, get_last_error_msg()); + return nullptr; + } + OutputBuffer cipherBuffer{cipherBytes.data(), cipherBytes.size()}; + auto bigNumValue = JavaBigIntegerToBigNum(env, significant); + + bcos::bytes keyBytes; + auto keyBuffer = convertToInputBuffer(keyBytes, env, key); + ihc_floating_encrypt(&cipherBuffer, mode, &keyBuffer, bigNumValue.bn().get(), exponent); + + if (!last_call_success()) + { + THROW_JNI_EXCEPTION(env, get_last_error_msg()); + return nullptr; + } + auto jResult = env->NewByteArray(cipherBuffer.len); + env->SetByteArrayRegion(jResult, 0, cipherBuffer.len, (jbyte*)cipherBuffer.data); + return jResult; +} + +JNIEXPORT jobject JNICALL Java_com_webank_wedpr_sdk_jni_homo_NativeFloatingIhc_decrypt( + JNIEnv* env, jclass, jint mode, jbyteArray key, jbyteArray cipher) +{ + bcos::bytes cipherCBytes; + auto cipherBuffer = convertToInputBuffer(cipherCBytes, env, cipher); + bcos::bytes keyBytes; + auto keyBuffer = convertToInputBuffer(keyBytes, env, key); + + ppc::FloatingPointNumber resultFp; + ihc_floating_decrypt( + resultFp.value.bn().get(), &resultFp.exponent, mode, &keyBuffer, &cipherBuffer); + if (!last_call_success()) + { + THROW_JNI_EXCEPTION(env, get_last_error_msg()); + return nullptr; + } + // convert to FloatingPointNumber + jclass fpNumberClass = env->FindClass("com/webank/wedpr/sdk/jni/codec/FloatingPointNumber"); + // FloatingPointNumber(byte[] significantBytes, int exponent) + jmethodID initFunID = env->GetMethodID(fpNumberClass, "", "([BI)V"); + jbyteArray cipherBytes = BigNumToJavaBigIntegerBytes(env, resultFp.value.bn().get()); + jobject result = env->NewObject(fpNumberClass, initFunID, cipherBytes, resultFp.exponent); + // release the used jbyteArray + env->DeleteLocalRef(cipherBytes); + return result; +} + + +JNIEXPORT jbyteArray JNICALL Java_com_webank_wedpr_sdk_jni_homo_NativeFloatingIhc_add( + JNIEnv* env, jclass, jint mode, jbyteArray cipher1, jbyteArray cipher2) +{ + bcos::bytes cipherBytes1; + auto cipherBuffer1 = convertToInputBuffer(cipherBytes1, env, cipher1); + bcos::bytes cipherBytes2; + auto cipherBuffer2 = convertToInputBuffer(cipherBytes2, env, cipher2); + bcos::bytes cipherBytes(ihc_floating_cipher_bytes(mode)); + OutputBuffer resultBuffer{cipherBytes.data(), cipherBytes.size()}; + ihc_floating_add(&resultBuffer, mode, &cipherBuffer1, &cipherBuffer2); + + if (!last_call_success()) + { + THROW_JNI_EXCEPTION(env, get_last_error_msg()); + return nullptr; + } + + auto jResult = env->NewByteArray(resultBuffer.len); + env->SetByteArrayRegion(jResult, 0, resultBuffer.len, (jbyte*)resultBuffer.data); + return jResult; +} + + +JNIEXPORT jbyteArray JNICALL Java_com_webank_wedpr_sdk_jni_homo_NativeFloatingIhc_sub( + JNIEnv* env, jclass, jint mode, jbyteArray cipher1, jbyteArray cipher2) +{ + bcos::bytes cipherBytes1; + auto cipherBuffer1 = convertToInputBuffer(cipherBytes1, env, cipher1); + bcos::bytes cipherBytes2; + auto cipherBuffer2 = convertToInputBuffer(cipherBytes2, env, cipher2); + bcos::bytes cipherBytes(ihc_floating_cipher_bytes(mode)); + OutputBuffer cipherBuffer{cipherBytes.data(), cipherBytes.size()}; + ihc_floating_sub(&cipherBuffer, mode, &cipherBuffer1, &cipherBuffer2); + if (!last_call_success()) + { + THROW_JNI_EXCEPTION(env, get_last_error_msg()); + return nullptr; + } + + auto jResult = env->NewByteArray(cipherBuffer.len); + env->SetByteArrayRegion(jResult, 0, cipherBuffer.len, (jbyte*)cipherBuffer.data); + return jResult; +} + + +JNIEXPORT jbyteArray JNICALL Java_com_webank_wedpr_sdk_jni_homo_NativeFloatingIhc_scalaMul( + JNIEnv* env, jclass, jint mode, jbyteArray vSignificant, jint vExponent, jbyteArray cipher) +{ + bcos::bytes cipherBytes; + auto cipherBuffer = convertToInputBuffer(cipherBytes, env, cipher); + auto bigNumValue = JavaBigIntegerToBigNum(env, vSignificant); + bcos::bytes resultBytes(ihc_floating_cipher_bytes(mode)); + OutputBuffer resultBuffer{resultBytes.data(), resultBytes.size()}; + ihc_floating_scalaMul(&resultBuffer, mode, bigNumValue.bn().get(), vExponent, &cipherBuffer); + if (!last_call_success()) + { + THROW_JNI_EXCEPTION(env, get_last_error_msg()); + return nullptr; + } + auto jResult = env->NewByteArray(resultBuffer.len); + env->SetByteArrayRegion(jResult, 0, resultBuffer.len, (jbyte*)resultBuffer.data); + return jResult; +} \ No newline at end of file diff --git a/cpp/wedpr-crypto/sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_homo_NativeFloatingIhc.h b/cpp/wedpr-crypto/sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_homo_NativeFloatingIhc.h new file mode 100644 index 00000000..7780e9ca --- /dev/null +++ b/cpp/wedpr-crypto/sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_homo_NativeFloatingIhc.h @@ -0,0 +1,61 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class com_webank_wedpr_sdk_jni_homo_NativeFloatingIhc */ + +#ifndef _Included_com_webank_wedpr_sdk_jni_homo_NativeFloatingIhc +#define _Included_com_webank_wedpr_sdk_jni_homo_NativeFloatingIhc +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: com_webank_wedpr_sdk_jni_homo_NativeFloatingIhc + * Method: generateKey + * Signature: (I)[B + */ +JNIEXPORT jbyteArray JNICALL Java_com_webank_wedpr_sdk_jni_homo_NativeFloatingIhc_generateKey( + JNIEnv*, jclass, jint); + +/* + * Class: com_webank_wedpr_sdk_jni_homo_NativeFloatingIhc + * Method: encrypt + * Signature: (I[B[BI)[B + */ +JNIEXPORT jbyteArray JNICALL Java_com_webank_wedpr_sdk_jni_homo_NativeFloatingIhc_encrypt( + JNIEnv*, jclass, jint, jbyteArray, jbyteArray, jint); + +/* + * Class: com_webank_wedpr_sdk_jni_homo_NativeFloatingIhc + * Method: decrypt + * Signature: (I[B[B)Lcom/webank/wedpr/sdk/jni/codec/FloatingPointNumber; + */ +JNIEXPORT jobject JNICALL Java_com_webank_wedpr_sdk_jni_homo_NativeFloatingIhc_decrypt( + JNIEnv*, jclass, jint, jbyteArray, jbyteArray); + +/* + * Class: com_webank_wedpr_sdk_jni_homo_NativeFloatingIhc + * Method: add + * Signature: (I[B[B)[B + */ +JNIEXPORT jbyteArray JNICALL Java_com_webank_wedpr_sdk_jni_homo_NativeFloatingIhc_add( + JNIEnv*, jclass, jint, jbyteArray, jbyteArray); + +/* + * Class: com_webank_wedpr_sdk_jni_homo_NativeFloatingIhc + * Method: sub + * Signature: (I[B[B)[B + */ +JNIEXPORT jbyteArray JNICALL Java_com_webank_wedpr_sdk_jni_homo_NativeFloatingIhc_sub( + JNIEnv*, jclass, jint, jbyteArray, jbyteArray); + +/* + * Class: com_webank_wedpr_sdk_jni_homo_NativeFloatingIhc + * Method: scalaMul + * Signature: (I[B[BI)[B + */ +JNIEXPORT jbyteArray JNICALL Java_com_webank_wedpr_sdk_jni_homo_NativeFloatingIhc_scalaMul( + JNIEnv*, jclass, jint, jbyteArray, jint, jbyteArray); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/cpp/wedpr-crypto/sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_homo_NativeFloatingPointPaillier.cpp b/cpp/wedpr-crypto/sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_homo_NativeFloatingPointPaillier.cpp new file mode 100644 index 00000000..ac0907e3 --- /dev/null +++ b/cpp/wedpr-crypto/sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_homo_NativeFloatingPointPaillier.cpp @@ -0,0 +1,445 @@ +#include "com_webank_wedpr_sdk_jni_homo_NativeFloatingPointPaillier.h" +#include "Common.h" +#include "JNIException.h" +#include "ppc-crypto-c-sdk/floating_point_paillier.h" +#include "ppc-crypto-c-sdk/homo_paillier.h" +#include "ppc-crypto-c-sdk/utils/error.h" + +/* + * Class: com_webank_wedpr_sdk_jni_homo_NativeFloatingPointPaillier + * Method: maxCipherBytes + * Signature: (I)I + */ +JNIEXPORT jint JNICALL +Java_com_webank_wedpr_sdk_jni_homo_NativeFloatingPointPaillier_maxCipherBytes( + JNIEnv*, jclass, jint keyBits) +{ + return floating_point_paillier_cipher_bytes(keyBits); +} + +/* + * Class: com_webank_wedpr_sdk_jni_homo_NativeFloatingPointPaillier + * Method: encryptFast + * Signature: ([BIJ)[B + */ +JNIEXPORT jbyteArray JNICALL +Java_com_webank_wedpr_sdk_jni_homo_NativeFloatingPointPaillier_encryptFast( + JNIEnv* env, jclass, jbyteArray significantBytes, jint exponent, jlong jkeypair) +{ + auto significant = JavaBigIntegerToBigNum(env, significantBytes); + + auto keypair = reinterpret_cast(jkeypair); + auto keyBits = paillier_key_bits_from_keypair(keypair); + if (!last_call_success()) + { + THROW_JNI_EXCEPTION(env, get_last_error_msg()); + return nullptr; + } + + auto cipherLen = floating_point_paillier_cipher_bytes(keyBits); + if (!last_call_success()) + { + THROW_JNI_EXCEPTION(env, get_last_error_msg()); + return nullptr; + } + bcos::bytes cipherBytes(cipherLen); + OutputBuffer cipherBuffer{cipherBytes.data(), cipherBytes.size()}; + + floating_point_paillier_encrypt_fast(&cipherBuffer, significant.bn().get(), exponent, keypair); + + if (!last_call_success()) + { + THROW_JNI_EXCEPTION(env, get_last_error_msg()); + return nullptr; + } + // copy the result + auto jResult = env->NewByteArray(cipherBuffer.len); + env->SetByteArrayRegion(jResult, 0, cipherBuffer.len, (jbyte*)cipherBuffer.data); + return jResult; +} + +/* + * Class: com_webank_wedpr_sdk_jni_homo_NativeFloatingPointPaillier + * Method: encryptFastWithoutPrecompute + * Signature: ([BI[B[B)[B + */ +JNIEXPORT jbyteArray JNICALL +Java_com_webank_wedpr_sdk_jni_homo_NativeFloatingPointPaillier_encryptFastWithoutPrecompute( + JNIEnv* env, jclass, jbyteArray significantBytes, jint exponent, jbyteArray sk, jbyteArray pk) +{ + auto significant = JavaBigIntegerToBigNum(env, significantBytes); + + bcos::bytes skBytes; + auto skBuffer = convertToInputBuffer(skBytes, env, sk); + bcos::bytes pkBytes; + auto pkBuffer = convertToInputBuffer(pkBytes, env, pk); + auto cipherLen = floating_point_paillier_cipher_bytes(pkBuffer.len * 8); + if (!last_call_success()) + { + THROW_JNI_EXCEPTION(env, get_last_error_msg()); + return nullptr; + } + bcos::bytes cipherBytes(cipherLen); + OutputBuffer cipherBuffer{cipherBytes.data(), cipherBytes.size()}; + + floating_point_paillier_encrypt_fast_without_precompute( + &cipherBuffer, significant.bn().get(), exponent, &skBuffer, &pkBuffer); + + if (!last_call_success()) + { + THROW_JNI_EXCEPTION(env, get_last_error_msg()); + return nullptr; + } + // copy the result + auto jResult = env->NewByteArray(cipherBuffer.len); + env->SetByteArrayRegion(jResult, 0, cipherBuffer.len, (jbyte*)cipherBuffer.data); + return jResult; +} + +/* + * Class: com_webank_wedpr_sdk_jni_homo_NativeFloatingPointPaillier + * Method: encrypt + * Signature: ([BIJ)[B + */ +JNIEXPORT jbyteArray JNICALL Java_com_webank_wedpr_sdk_jni_homo_NativeFloatingPointPaillier_encrypt( + JNIEnv* env, jclass, jbyteArray significantBytes, jint exponent, jlong jpublicKey) +{ + auto significant = JavaBigIntegerToBigNum(env, significantBytes); + + auto pk = reinterpret_cast(jpublicKey); + auto keyBits = paillier_key_bits_from_public_key(pk); + if (!last_call_success()) + { + THROW_JNI_EXCEPTION(env, get_last_error_msg()); + return nullptr; + } + + auto cipherLen = floating_point_paillier_cipher_bytes(keyBits); + if (!last_call_success()) + { + THROW_JNI_EXCEPTION(env, get_last_error_msg()); + return nullptr; + } + + bcos::bytes cipherBytes(cipherLen); + OutputBuffer cipherBuffer{cipherBytes.data(), cipherBytes.size()}; + floating_point_paillier_encrypt(&cipherBuffer, significant.bn().get(), exponent, pk); + if (!last_call_success()) + { + THROW_JNI_EXCEPTION(env, get_last_error_msg()); + return nullptr; + } + // copy the result + auto jResult = env->NewByteArray(cipherBuffer.len); + env->SetByteArrayRegion(jResult, 0, cipherBuffer.len, (jbyte*)cipherBuffer.data); + return jResult; +} + +/* + * Class: com_webank_wedpr_sdk_jni_homo_NativeFloatingPointPaillier + * Method: encryptWithoutPrecompute + * Signature: ([BI[B)[B + */ +JNIEXPORT jbyteArray JNICALL +Java_com_webank_wedpr_sdk_jni_homo_NativeFloatingPointPaillier_encryptWithoutPrecompute( + JNIEnv* env, jclass, jbyteArray significantBytes, jint exponent, jbyteArray pkBytes) +{ + auto significant = JavaBigIntegerToBigNum(env, significantBytes); + + bcos::bytes pkCBytes; + auto pkBuffer = convertToInputBuffer(pkCBytes, env, pkBytes); + auto cipherLen = floating_point_paillier_cipher_bytes(pkBuffer.len * 8); + if (!last_call_success()) + { + THROW_JNI_EXCEPTION(env, get_last_error_msg()); + return nullptr; + } + + bcos::bytes cipherBytes(cipherLen); + OutputBuffer cipherBuffer{cipherBytes.data(), cipherBytes.size()}; + floating_point_paillier_encrypt_without_precompute( + &cipherBuffer, significant.bn().get(), exponent, &pkBuffer); + if (!last_call_success()) + { + THROW_JNI_EXCEPTION(env, get_last_error_msg()); + return nullptr; + } + // copy the result + auto jResult = env->NewByteArray(cipherBuffer.len); + env->SetByteArrayRegion(jResult, 0, cipherBuffer.len, (jbyte*)cipherBuffer.data); + return jResult; +} + +/* + * Class: com_webank_wedpr_sdk_jni_homo_NativeFloatingPointPaillier + * Method: decrypt + * Signature: ([BJ)Ljava/math/BigInteger; + */ +JNIEXPORT jobject JNICALL Java_com_webank_wedpr_sdk_jni_homo_NativeFloatingPointPaillier_decrypt( + JNIEnv* env, jclass, jbyteArray cipher, jlong jkeypair) +{ + ppc::crypto::BigNum decrypted_significant; + int16_t exponent; + bcos::bytes cipherBytes; + auto cipherBuffer = convertToInputBuffer(cipherBytes, env, cipher); + floating_point_paillier_decrypt(decrypted_significant.bn().get(), &exponent, &cipherBuffer, + reinterpret_cast(jkeypair)); + if (!last_call_success()) + { + THROW_JNI_EXCEPTION(env, get_last_error_msg()); + return nullptr; + } + // convert to FloatingPointNumber + jclass fpNumberClass = env->FindClass("com/webank/wedpr/sdk/jni/codec/FloatingPointNumber"); + // FloatingPointNumber(byte[] significantBytes, int exponent) + jmethodID initFunID = env->GetMethodID(fpNumberClass, "", "([BI)V"); + jbyteArray plainBytes = BigNumToJavaBigIntegerBytes(env, decrypted_significant.bn().get()); + jobject result = env->NewObject(fpNumberClass, initFunID, plainBytes, exponent); + env->DeleteLocalRef(plainBytes); + return result; +} + +/* + * Class: com_webank_wedpr_sdk_jni_homo_NativeFloatingPointPaillier + * Method: decryptWithoutPrecompute + * Signature: ([B[B[B)Lcom/webank/wedpr/sdk/jni/codec/FloatingPointNumber; + */ +JNIEXPORT jobject JNICALL +Java_com_webank_wedpr_sdk_jni_homo_NativeFloatingPointPaillier_decryptWithoutPrecompute( + JNIEnv* env, jclass, jbyteArray cipher, jbyteArray sk, jbyteArray pk) +{ + bcos::bytes skBytes; + auto skBuffer = convertToInputBuffer(skBytes, env, sk); + bcos::bytes pkBytes; + auto pkBuffer = convertToInputBuffer(pkBytes, env, pk); + ppc::crypto::BigNum decrypted_significant; + int16_t exponent; + bcos::bytes cipherCBytes; + auto cipherBuffer = convertToInputBuffer(cipherCBytes, env, cipher); + floating_point_paillier_decrypt_without_precompute( + decrypted_significant.bn().get(), &exponent, &cipherBuffer, &skBuffer, &pkBuffer); + if (!last_call_success()) + { + THROW_JNI_EXCEPTION(env, get_last_error_msg()); + return nullptr; + } + // convert to FloatingPointNumber + jclass fpNumberClass = env->FindClass("com/webank/wedpr/sdk/jni/codec/FloatingPointNumber"); + // FloatingPointNumber(byte[] significantBytes, int exponent) + jmethodID initFunID = env->GetMethodID(fpNumberClass, "", "([BI)V"); + jbyteArray plainBytes = BigNumToJavaBigIntegerBytes(env, decrypted_significant.bn().get()); + jobject result = env->NewObject(fpNumberClass, initFunID, plainBytes, exponent); + env->DeleteLocalRef(plainBytes); + return result; +} + +jbyteArray JNICALL Java_com_webank_wedpr_sdk_jni_homo_NativeFloatingPointPaillier_add_impl( + JNIEnv* env, jbyteArray c1, jbyteArray c2, jlong jpublic_key, bool add) +{ + auto pk = reinterpret_cast(jpublic_key); + auto keyBits = paillier_key_bits_from_public_key(pk); + if (!last_call_success()) + { + THROW_JNI_EXCEPTION(env, get_last_error_msg()); + return nullptr; + } + + auto cipherLen = floating_point_paillier_cipher_bytes(keyBits); + if (!last_call_success()) + { + THROW_JNI_EXCEPTION(env, get_last_error_msg()); + return nullptr; + } + + bcos::bytes cipherBytes(cipherLen); + OutputBuffer cipherBuffer{cipherBytes.data(), cipherBytes.size()}; + + bcos::bytes c1CBytes; + auto c1Buffer = convertToInputBuffer(c1CBytes, env, c1); + bcos::bytes c2CBytes; + auto c2Buffer = convertToInputBuffer(c2CBytes, env, c2); + if (add) + { + floating_point_paillier_add(&cipherBuffer, &c1Buffer, &c2Buffer, pk); + } + else + { + floating_point_paillier_sub(&cipherBuffer, &c1Buffer, &c2Buffer, pk); + } + if (!last_call_success()) + { + THROW_JNI_EXCEPTION(env, get_last_error_msg()); + return nullptr; + } + auto jResult = env->NewByteArray(cipherBuffer.len); + env->SetByteArrayRegion(jResult, 0, cipherBuffer.len, (jbyte*)cipherBuffer.data); + return jResult; +} + +/* + * Class: com_webank_wedpr_sdk_jni_homo_NativeFloatingPointPaillier + * Method: add + * Signature: ([B[BJ)[B + */ +JNIEXPORT jbyteArray JNICALL Java_com_webank_wedpr_sdk_jni_homo_NativeFloatingPointPaillier_add( + JNIEnv* env, jclass, jbyteArray c1, jbyteArray c2, jlong jpublic_key) +{ + return Java_com_webank_wedpr_sdk_jni_homo_NativeFloatingPointPaillier_add_impl( + env, c1, c2, jpublic_key, true); +} + + +/* + * Class: com_webank_wedpr_sdk_jni_homo_NativeFloatingPointPaillier + * Method: sub + * Signature: ([B[BJ)[B + */ +JNIEXPORT jbyteArray JNICALL Java_com_webank_wedpr_sdk_jni_homo_NativeFloatingPointPaillier_sub( + JNIEnv* env, jclass, jbyteArray c1, jbyteArray c2, jlong jpublic_key) +{ + return Java_com_webank_wedpr_sdk_jni_homo_NativeFloatingPointPaillier_add_impl( + env, c1, c2, jpublic_key, false); +} + +jbyteArray JNICALL +Java_com_webank_wedpr_sdk_jni_homo_NativeFloatingPointPaillier_add_without_precompute_impl( + JNIEnv* env, jbyteArray c1, jbyteArray c2, jbyteArray pkBytes, bool add) +{ + bcos::bytes pkCBytes; + auto pkBuffer = convertToInputBuffer(pkCBytes, env, pkBytes); + auto cipherLen = floating_point_paillier_cipher_bytes(pkBuffer.len * 8); + if (!last_call_success()) + { + THROW_JNI_EXCEPTION(env, get_last_error_msg()); + return nullptr; + } + bcos::bytes cipherBytes(cipherLen); + OutputBuffer cipherBuffer{cipherBytes.data(), cipherBytes.size()}; + bcos::bytes c1Bytes; + auto c1Buffer = convertToInputBuffer(c1Bytes, env, c1); + bcos::bytes c2Bytes; + auto c2Buffer = convertToInputBuffer(c2Bytes, env, c2); + if (add) + { + floating_point_paillier_add_without_precompute( + &cipherBuffer, &c1Buffer, &c2Buffer, &pkBuffer); + } + else + { + floating_point_paillier_sub_without_precompute( + &cipherBuffer, &c1Buffer, &c2Buffer, &pkBuffer); + } + if (!last_call_success()) + { + THROW_JNI_EXCEPTION(env, get_last_error_msg()); + return nullptr; + } + auto jResult = env->NewByteArray(cipherBuffer.len); + env->SetByteArrayRegion(jResult, 0, cipherBuffer.len, (jbyte*)cipherBuffer.data); + return jResult; +} + +/* + * Class: com_webank_wedpr_sdk_jni_homo_NativeFloatingPointPaillier + * Method: decryptWithoutPrecompute + * Signature: ([B[B[B)Lcom/webank/wedpr/sdk/jni/codec/FloatingPointNumber; + */ +JNIEXPORT jbyteArray JNICALL +Java_com_webank_wedpr_sdk_jni_homo_NativeFloatingPointPaillier_addWithoutPrecompute( + JNIEnv* env, jclass, jbyteArray c1, jbyteArray c2, jbyteArray pkBytes) +{ + return Java_com_webank_wedpr_sdk_jni_homo_NativeFloatingPointPaillier_add_without_precompute_impl( + env, c1, c2, pkBytes, true); +} +/* + * Class: com_webank_wedpr_sdk_jni_homo_NativeFloatingPointPaillier + * Method: addWithoutPrecompute + * Signature: ([B[B[B)[B + */ +JNIEXPORT jbyteArray JNICALL +Java_com_webank_wedpr_sdk_jni_homo_NativeFloatingPointPaillier_subWithoutPrecompute( + JNIEnv* env, jclass, jbyteArray c1, jbyteArray c2, jbyteArray pkBytes) +{ + return Java_com_webank_wedpr_sdk_jni_homo_NativeFloatingPointPaillier_add_without_precompute_impl( + env, c1, c2, pkBytes, false); +} + +/* + * Class: com_webank_wedpr_sdk_jni_homo_NativeFloatingPointPaillier + * Method: scalaMul + * Signature: ([BI[BJ)[B + */ +JNIEXPORT jbyteArray JNICALL +Java_com_webank_wedpr_sdk_jni_homo_NativeFloatingPointPaillier_scalaMul(JNIEnv* env, jclass, + jbyteArray significantBytes, jint exponent, jbyteArray cipherBytes, jlong jpublic_key) +{ + auto significant = JavaBigIntegerToBigNum(env, significantBytes); + + auto pk = reinterpret_cast(jpublic_key); + auto keyBits = paillier_key_bits_from_public_key(pk); + if (!last_call_success()) + { + THROW_JNI_EXCEPTION(env, get_last_error_msg()); + return nullptr; + } + + auto cipherLen = floating_point_paillier_cipher_bytes(keyBits); + if (!last_call_success()) + { + THROW_JNI_EXCEPTION(env, get_last_error_msg()); + return nullptr; + } + bcos::bytes cipherResult(cipherLen); + OutputBuffer cipherResultBuffer{cipherResult.data(), cipherResult.size()}; + // get the cipher buffer + bcos::bytes cipherCBytes; + auto cipher = convertToInputBuffer(cipherCBytes, env, cipherBytes); + + floating_point_paillier_scalaMul( + &cipherResultBuffer, significant.bn().get(), exponent, &cipher, pk); + if (!last_call_success()) + { + THROW_JNI_EXCEPTION(env, get_last_error_msg()); + return nullptr; + } + auto jResult = env->NewByteArray(cipherResultBuffer.len); + env->SetByteArrayRegion(jResult, 0, cipherResultBuffer.len, (jbyte*)cipherResultBuffer.data); + return jResult; +} + +/* + * Class: com_webank_wedpr_sdk_jni_homo_NativeFloatingPointPaillier + * Method: scalaMulWithoutPrecompute + * Signature: ([BI[B[B)[B + */ +JNIEXPORT jbyteArray JNICALL +Java_com_webank_wedpr_sdk_jni_homo_NativeFloatingPointPaillier_scalaMulWithoutPrecompute( + JNIEnv* env, jclass, jbyteArray significantBytes, jint exponent, jbyteArray cipherBytes, + jbyteArray pkBytes) +{ + auto significant = JavaBigIntegerToBigNum(env, significantBytes); + bcos::bytes pkCBytes; + auto pkBuffer = convertToInputBuffer(pkCBytes, env, pkBytes); + auto cipherLen = floating_point_paillier_cipher_bytes(pkBuffer.len * 8); + if (!last_call_success()) + { + THROW_JNI_EXCEPTION(env, get_last_error_msg()); + return nullptr; + } + bcos::bytes cipherResult(cipherLen); + OutputBuffer cipherResultBuffer{cipherResult.data(), cipherResult.size()}; + // get the cipher buffer + bcos::bytes cipherCBytes; + auto cipher = convertToInputBuffer(cipherCBytes, env, cipherBytes); + + floating_point_paillier_scalaMul_without_precompute( + &cipherResultBuffer, significant.bn().get(), exponent, &cipher, &pkBuffer); + if (!last_call_success()) + { + THROW_JNI_EXCEPTION(env, get_last_error_msg()); + return nullptr; + } + auto jResult = env->NewByteArray(cipherResultBuffer.len); + env->SetByteArrayRegion(jResult, 0, cipherResultBuffer.len, (jbyte*)cipherResultBuffer.data); + return jResult; +} \ No newline at end of file diff --git a/cpp/wedpr-crypto/sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_homo_NativeFloatingPointPaillier.h b/cpp/wedpr-crypto/sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_homo_NativeFloatingPointPaillier.h new file mode 100644 index 00000000..015d8043 --- /dev/null +++ b/cpp/wedpr-crypto/sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_homo_NativeFloatingPointPaillier.h @@ -0,0 +1,126 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class com_webank_wedpr_sdk_jni_homo_NativeFloatingPointPaillier */ + +#ifndef _Included_com_webank_wedpr_sdk_jni_homo_NativeFloatingPointPaillier +#define _Included_com_webank_wedpr_sdk_jni_homo_NativeFloatingPointPaillier +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: com_webank_wedpr_sdk_jni_homo_NativeFloatingPointPaillier + * Method: maxCipherBytes + * Signature: (I)I + */ +JNIEXPORT jint JNICALL +Java_com_webank_wedpr_sdk_jni_homo_NativeFloatingPointPaillier_maxCipherBytes( + JNIEnv*, jclass, jint); + +/* + * Class: com_webank_wedpr_sdk_jni_homo_NativeFloatingPointPaillier + * Method: encryptFast + * Signature: ([BIJ)[B + */ +JNIEXPORT jbyteArray JNICALL +Java_com_webank_wedpr_sdk_jni_homo_NativeFloatingPointPaillier_encryptFast( + JNIEnv*, jclass, jbyteArray, jint, jlong); + +/* + * Class: com_webank_wedpr_sdk_jni_homo_NativeFloatingPointPaillier + * Method: encryptFastWithoutPrecompute + * Signature: ([BI[B[B)[B + */ +JNIEXPORT jbyteArray JNICALL +Java_com_webank_wedpr_sdk_jni_homo_NativeFloatingPointPaillier_encryptFastWithoutPrecompute( + JNIEnv*, jclass, jbyteArray, jint, jbyteArray, jbyteArray); + +/* + * Class: com_webank_wedpr_sdk_jni_homo_NativeFloatingPointPaillier + * Method: encrypt + * Signature: ([BIJ)[B + */ +JNIEXPORT jbyteArray JNICALL Java_com_webank_wedpr_sdk_jni_homo_NativeFloatingPointPaillier_encrypt( + JNIEnv*, jclass, jbyteArray, jint, jlong); + +/* + * Class: com_webank_wedpr_sdk_jni_homo_NativeFloatingPointPaillier + * Method: encryptWithoutPrecompute + * Signature: ([BI[B)[B + */ +JNIEXPORT jbyteArray JNICALL +Java_com_webank_wedpr_sdk_jni_homo_NativeFloatingPointPaillier_encryptWithoutPrecompute( + JNIEnv*, jclass, jbyteArray, jint, jbyteArray); + +/* + * Class: com_webank_wedpr_sdk_jni_homo_NativeFloatingPointPaillier + * Method: decrypt + * Signature: ([BJ)Lcom/webank/wedpr/sdk/jni/codec/FloatingPointNumber; + */ +JNIEXPORT jobject JNICALL Java_com_webank_wedpr_sdk_jni_homo_NativeFloatingPointPaillier_decrypt( + JNIEnv*, jclass, jbyteArray, jlong); + +/* + * Class: com_webank_wedpr_sdk_jni_homo_NativeFloatingPointPaillier + * Method: decryptWithoutPrecompute + * Signature: ([B[B[B)Lcom/webank/wedpr/sdk/jni/codec/FloatingPointNumber; + */ +JNIEXPORT jobject JNICALL +Java_com_webank_wedpr_sdk_jni_homo_NativeFloatingPointPaillier_decryptWithoutPrecompute( + JNIEnv*, jclass, jbyteArray, jbyteArray, jbyteArray); + +/* + * Class: com_webank_wedpr_sdk_jni_homo_NativeFloatingPointPaillier + * Method: add + * Signature: ([B[BJ)[B + */ +JNIEXPORT jbyteArray JNICALL Java_com_webank_wedpr_sdk_jni_homo_NativeFloatingPointPaillier_add( + JNIEnv*, jclass, jbyteArray, jbyteArray, jlong); + +/* + * Class: com_webank_wedpr_sdk_jni_homo_NativeFloatingPointPaillier + * Method: addWithoutPrecompute + * Signature: ([B[B[B)[B + */ +JNIEXPORT jbyteArray JNICALL +Java_com_webank_wedpr_sdk_jni_homo_NativeFloatingPointPaillier_addWithoutPrecompute( + JNIEnv*, jclass, jbyteArray, jbyteArray, jbyteArray); + +/* + * Class: com_webank_wedpr_sdk_jni_homo_NativeFloatingPointPaillier + * Method: sub + * Signature: ([B[BJ)[B + */ +JNIEXPORT jbyteArray JNICALL Java_com_webank_wedpr_sdk_jni_homo_NativeFloatingPointPaillier_sub( + JNIEnv*, jclass, jbyteArray, jbyteArray, jlong); + +/* + * Class: com_webank_wedpr_sdk_jni_homo_NativeFloatingPointPaillier + * Method: subWithoutPrecompute + * Signature: ([B[B[B)[B + */ +JNIEXPORT jbyteArray JNICALL +Java_com_webank_wedpr_sdk_jni_homo_NativeFloatingPointPaillier_subWithoutPrecompute( + JNIEnv*, jclass, jbyteArray, jbyteArray, jbyteArray); + +/* + * Class: com_webank_wedpr_sdk_jni_homo_NativeFloatingPointPaillier + * Method: scalaMul + * Signature: ([BI[BJ)[B + */ +JNIEXPORT jbyteArray JNICALL +Java_com_webank_wedpr_sdk_jni_homo_NativeFloatingPointPaillier_scalaMul( + JNIEnv*, jclass, jbyteArray, jint, jbyteArray, jlong); + +/* + * Class: com_webank_wedpr_sdk_jni_homo_NativeFloatingPointPaillier + * Method: scalaMulWithoutPrecompute + * Signature: ([BI[B[B)[B + */ +JNIEXPORT jbyteArray JNICALL +Java_com_webank_wedpr_sdk_jni_homo_NativeFloatingPointPaillier_scalaMulWithoutPrecompute( + JNIEnv*, jclass, jbyteArray, jint, jbyteArray, jbyteArray); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/cpp/wedpr-crypto/sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_homo_NativeIhc.h b/cpp/wedpr-crypto/sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_homo_NativeIhc.h new file mode 100644 index 00000000..fa254ce0 --- /dev/null +++ b/cpp/wedpr-crypto/sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_homo_NativeIhc.h @@ -0,0 +1,61 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class com_webank_wedpr_sdk_jni_homo_NativeIhc */ + +#ifndef _Included_com_webank_wedpr_sdk_jni_homo_NativeIhc +#define _Included_com_webank_wedpr_sdk_jni_homo_NativeIhc +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: com_webank_wedpr_sdk_jni_homo_NativeIhc + * Method: generateKey + * Signature: (I)[B + */ +JNIEXPORT jbyteArray JNICALL Java_com_webank_wedpr_sdk_jni_homo_NativeIhc_generateKey( + JNIEnv*, jclass, jint); + +/* + * Class: com_webank_wedpr_sdk_jni_homo_NativeIhc + * Method: encrypt + * Signature: ([B[BII)[B + */ +JNIEXPORT jbyteArray JNICALL Java_com_webank_wedpr_sdk_jni_homo_NativeIhc_encrypt( + JNIEnv*, jclass, jbyteArray, jbyteArray, jint, jint); + +/* + * Class: com_webank_wedpr_sdk_jni_homo_NativeIhc + * Method: decrypt + * Signature: ([B[BII)[B + */ +JNIEXPORT jbyteArray JNICALL Java_com_webank_wedpr_sdk_jni_homo_NativeIhc_decrypt( + JNIEnv*, jclass, jbyteArray, jbyteArray, jint, jint); + +/* + * Class: com_webank_wedpr_sdk_jni_homo_NativeIhc + * Method: add + * Signature: ([B[BI)[B + */ +JNIEXPORT jbyteArray JNICALL Java_com_webank_wedpr_sdk_jni_homo_NativeIhc_add( + JNIEnv*, jclass, jbyteArray, jbyteArray, jint); + +/* + * Class: com_webank_wedpr_sdk_jni_homo_NativeIhc + * Method: sub + * Signature: ([B[BI)[B + */ +JNIEXPORT jbyteArray JNICALL Java_com_webank_wedpr_sdk_jni_homo_NativeIhc_sub( + JNIEnv*, jclass, jbyteArray, jbyteArray, jint); + +/* + * Class: com_webank_wedpr_sdk_jni_homo_NativeIhc + * Method: scalaMul + * Signature: ([B[BI)[B + */ +JNIEXPORT jbyteArray JNICALL Java_com_webank_wedpr_sdk_jni_homo_NativeIhc_scalaMul( + JNIEnv*, jclass, jbyteArray, jbyteArray, jint); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/cpp/wedpr-crypto/sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_homo_NativePaillier.cpp b/cpp/wedpr-crypto/sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_homo_NativePaillier.cpp new file mode 100644 index 00000000..c5973629 --- /dev/null +++ b/cpp/wedpr-crypto/sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_homo_NativePaillier.cpp @@ -0,0 +1,629 @@ +#include "com_webank_wedpr_sdk_jni_homo_NativePaillier.h" +#include "Common.h" +#include "JNIException.h" +#include "ppc-crypto-c-sdk/homo_paillier.h" +#include "ppc-crypto-c-sdk/utils/error.h" +#include +/* + * Class: com_webank_wedpr_sdk_jni_homo_NativePaillier + * Method: maxPublicKeyBytes + * Signature: (I)I + */ +JNIEXPORT jint JNICALL Java_com_webank_wedpr_sdk_jni_homo_NativePaillier_maxPublicKeyBytes( + JNIEnv*, jclass, jint keyBits) +{ + return paillier_max_public_key_bytes(keyBits); +} + +/* + * Class: com_webank_wedpr_sdk_jni_homo_NativePaillier + * Method: maxPrivateKeyBytes + * Signature: (I)I + */ +JNIEXPORT jint JNICALL Java_com_webank_wedpr_sdk_jni_homo_NativePaillier_maxPrivateKeyBytes( + JNIEnv*, jclass, jint keyBits) +{ + return paillier_max_private_key_bytes(keyBits); +} + +/* + * Class: com_webank_wedpr_sdk_jni_homo_NativePaillier + * Method: maxCipherBytes + * Signature: (I)I + */ +JNIEXPORT jint JNICALL Java_com_webank_wedpr_sdk_jni_homo_NativePaillier_maxCipherBytes( + JNIEnv*, jclass, jint keyBits) +{ + return paillier_max_cipher_bytes(keyBits); +} + +/* + * Class: com_webank_wedpr_sdk_jni_homo_NativePaillier + * Method: keyBitsFromKeyPair + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_com_webank_wedpr_sdk_jni_homo_NativePaillier_keyBitsFromKeyPair( + JNIEnv*, jclass, jlong keypair) +{ + return paillier_key_bits_from_keypair(reinterpret_cast(keypair)); +} + +/* + * Class: com_webank_wedpr_sdk_jni_homo_NativePaillier + * Method: keyBitsFromPublicKey + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_com_webank_wedpr_sdk_jni_homo_NativePaillier_keyBitsFromPublicKey( + JNIEnv*, jclass, jlong public_key) +{ + return paillier_key_bits_from_public_key(reinterpret_cast(public_key)); +} +/* + * Class: com_webank_wedpr_sdk_jni_homo_NativePaillier + * Method: generateKeyPair + * Signature: (I)J + */ +JNIEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_homo_NativePaillier_generateKeyPair( + JNIEnv* env, jclass, jint keyBits) +{ + auto keyPair = paillier_generate_keypair(keyBits); + if (!last_call_success()) + { + THROW_JNI_EXCEPTION(env, get_last_error_msg()); + return 0; + } + return reinterpret_cast(keyPair); +} + +/* + * Class: com_webank_wedpr_sdk_jni_homo_NativePaillier + * Method: loadKeyPair + * Signature: ([B[B)J + */ +JNIEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_homo_NativePaillier_loadKeyPair( + JNIEnv* env, jclass, jbyteArray privateKey, jbyteArray publicKey) +{ + // load key-pair from given private key and public key + bcos::bytes skBytes; + auto privateKeyBuffer = convertToInputBuffer(skBytes, env, privateKey); + bcos::bytes pkBytes; + auto publicKeyBuffer = convertToInputBuffer(pkBytes, env, publicKey); + auto keyPair = paillier_load_keypair(&privateKeyBuffer, &publicKeyBuffer); + if (!last_call_success()) + { + THROW_JNI_EXCEPTION(env, get_last_error_msg()); + return 0; + } + return reinterpret_cast(keyPair); +} + +/* + * Class: com_webank_wedpr_sdk_jni_homo_NativePaillier + * Method: freeKeyPair + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_homo_NativePaillier_freeKeyPair( + JNIEnv*, jclass, jlong key_pair) +{ + paillier_free_key_pair(reinterpret_cast(key_pair)); +} + +/* + * Class: com_webank_wedpr_sdk_jni_homo_NativePaillier + * Method: loadPublicKey + * Signature: ([B)J + */ +JNIEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_homo_NativePaillier_loadPublicKey( + JNIEnv* env, jclass, jbyteArray publicKeyBytes) +{ + bcos::bytes pkBytes; + auto publicKeyBuffer = convertToInputBuffer(pkBytes, env, publicKeyBytes); + auto publicKeyObj = paillier_load_public_key(&publicKeyBuffer); + if (!last_call_success()) + { + THROW_JNI_EXCEPTION(env, get_last_error_msg()); + return 0; + } + return reinterpret_cast(publicKeyObj); +} + +/* + * Class: com_webank_wedpr_sdk_jni_homo_NativePaillier + * Method: freePublicKey + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_homo_NativePaillier_freePublicKey( + JNIEnv*, jclass, jlong public_key) +{ + paillier_free_public_key(reinterpret_cast(public_key)); +} + +/* + * Class: com_webank_wedpr_sdk_jni_homo_NativePaillier + * Method: getPublicKeyJniObject + * Signature: (J)J + */ +JNIEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_homo_NativePaillier_getPublicKeyJniObject( + JNIEnv*, jclass, jlong jkeyPair) +{ + auto keyPair = reinterpret_cast(jkeyPair); + return reinterpret_cast(paillier_get_public_key(keyPair)); +} + +/* + * Class: com_webank_wedpr_sdk_jni_homo_NativePaillier + * Method: freePrivateKey + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_homo_NativePaillier_freePrivateKey( + JNIEnv*, jclass, jlong private_key) +{ + paillier_free_public_key(reinterpret_cast(private_key)); +} + +/* + * Class: com_webank_wedpr_sdk_jni_homo_NativePaillier + * Method: getPublicKeyBytesFromKeyPair + * Signature: (J)[B + */ +JNIEXPORT jbyteArray JNICALL +Java_com_webank_wedpr_sdk_jni_homo_NativePaillier_getPublicKeyBytesFromKeyPair( + JNIEnv* env, jclass, jlong keypair) +{ + auto publicKeyBuffer = + paillier_get_public_key_bytes_from_keyPair(reinterpret_cast(keypair)); + if (!last_call_success()) + { + THROW_JNI_EXCEPTION(env, get_last_error_msg()); + return nullptr; + } + // copy the result to jResult + auto jResult = env->NewByteArray(publicKeyBuffer.len); + env->SetByteArrayRegion(jResult, 0, publicKeyBuffer.len, (jbyte*)publicKeyBuffer.data); + // release the allocated buffer + free(publicKeyBuffer.data); + return jResult; +} + +/* + * Class: com_webank_wedpr_sdk_jni_homo_NativePaillier + * Method: getPrivateKeyBytesFromKeyPair + * Signature: (J)[B + */ +JNIEXPORT jbyteArray JNICALL +Java_com_webank_wedpr_sdk_jni_homo_NativePaillier_getPrivateKeyBytesFromKeyPair( + JNIEnv* env, jclass, jlong keypair) +{ + auto skBuffer = paillier_get_private_key_bytes_from_keypair(reinterpret_cast(keypair)); + if (!last_call_success()) + { + THROW_JNI_EXCEPTION(env, get_last_error_msg()); + return nullptr; + } + // copy the result to jResult + auto jResult = env->NewByteArray(skBuffer.len); + env->SetByteArrayRegion(jResult, 0, skBuffer.len, (jbyte*)skBuffer.data); + // release the allocated buffer + free(skBuffer.data); + return jResult; +} + +/* + * Class: com_webank_wedpr_sdk_jni_homo_NativePaillier + * Method: encryptFast + * Signature: ([BJ)[B + */ +JNIEXPORT jbyteArray JNICALL Java_com_webank_wedpr_sdk_jni_homo_NativePaillier_encryptFast( + JNIEnv* env, jclass, jbyteArray value, jlong jkeypair) +{ + auto bigNumValue = JavaBigIntegerToBigNum(env, value); + auto keypair = reinterpret_cast(jkeypair); + // get the keyBits + auto keyBits = paillier_key_bits_from_keypair(keypair); + if (!last_call_success()) + { + THROW_JNI_EXCEPTION(env, get_last_error_msg()); + return nullptr; + } + + // encrypt + auto cipherLen = paillier_max_cipher_bytes(keyBits); + if (!last_call_success()) + { + THROW_JNI_EXCEPTION(env, get_last_error_msg()); + return nullptr; + } + bcos::bytes cipherBytes(cipherLen); + OutputBuffer cipherBuffer{cipherBytes.data(), cipherBytes.size()}; + paillier_encryt_fast(&cipherBuffer, nullptr, bigNumValue.bn().get(), keypair); + // copy the cipher into jbyteArray + if (!last_call_success()) + { + THROW_JNI_EXCEPTION(env, get_last_error_msg()); + return nullptr; + } + // copy the result to jResult + auto jResult = env->NewByteArray(cipherBuffer.len); + env->SetByteArrayRegion(jResult, 0, cipherBuffer.len, (jbyte*)cipherBuffer.data); + return jResult; +} + +/* + * Class: com_webank_wedpr_sdk_jni_homo_NativePaillier + * Method: encryptFast + * Signature: ([B[B[B)[B + */ +JNIEXPORT jbyteArray JNICALL +Java_com_webank_wedpr_sdk_jni_homo_NativePaillier_encryptFastWithoutPrecompute( + JNIEnv* env, jclass, jbyteArray value, jbyteArray sk, jbyteArray pk) +{ + auto bigNumValue = JavaBigIntegerToBigNum(env, value); + bcos::bytes skBytes; + auto skBuffer = convertToInputBuffer(skBytes, env, sk); + bcos::bytes pkBytes; + auto pkBuffer = convertToInputBuffer(pkBytes, env, pk); + // Note: pkBuffer.len is not the real keyBytes + auto cipherLen = paillier_max_cipher_bytes(pkBuffer.len * 8); + if (!last_call_success()) + { + THROW_JNI_EXCEPTION(env, get_last_error_msg()); + return nullptr; + } + bcos::bytes cipherBytes(cipherLen); + OutputBuffer cipherBuffer{cipherBytes.data(), cipherBytes.size()}; + paillier_encryt_fast_without_precompute( + &cipherBuffer, nullptr, bigNumValue.bn().get(), &skBuffer, &pkBuffer); + + if (!last_call_success()) + { + THROW_JNI_EXCEPTION(env, get_last_error_msg()); + return nullptr; + } + // copy the result to jResult + auto jResult = env->NewByteArray(cipherBuffer.len); + env->SetByteArrayRegion(jResult, 0, cipherBuffer.len, (jbyte*)cipherBuffer.data); + return jResult; +} + +/* + * Class: com_webank_wedpr_sdk_jni_homo_NativePaillier + * Method: encrypt + * Signature: ([BJ)[B + */ +JNIEXPORT jbyteArray JNICALL Java_com_webank_wedpr_sdk_jni_homo_NativePaillier_encrypt( + JNIEnv* env, jclass, jbyteArray value, jlong public_key) +{ + auto bigNumValue = JavaBigIntegerToBigNum(env, value); + auto pk = reinterpret_cast(public_key); + // get the keyBits + auto keyBits = paillier_key_bits_from_public_key(pk); + if (!last_call_success()) + { + THROW_JNI_EXCEPTION(env, get_last_error_msg()); + return nullptr; + } + // encrypt + auto cipherLen = paillier_max_cipher_bytes(keyBits); + if (!last_call_success()) + { + THROW_JNI_EXCEPTION(env, get_last_error_msg()); + return nullptr; + } + + bcos::bytes cipherBytes(cipherLen); + OutputBuffer cipherBuffer{cipherBytes.data(), cipherBytes.size()}; + paillier_encryt(&cipherBuffer, nullptr, bigNumValue.bn().get(), pk); + + if (!last_call_success()) + { + THROW_JNI_EXCEPTION(env, get_last_error_msg()); + return nullptr; + } + // copy the result to jResult + auto jResult = env->NewByteArray(cipherBuffer.len); + env->SetByteArrayRegion(jResult, 0, cipherBuffer.len, (jbyte*)cipherBuffer.data); + return jResult; +} + +/* + * Class: com_webank_wedpr_sdk_jni_homo_NativePaillier + * Method: encrypt + * Signature: ([B[B)[B + */ +JNIEXPORT jbyteArray JNICALL +Java_com_webank_wedpr_sdk_jni_homo_NativePaillier_encryptWithoutPrecompute( + JNIEnv* env, jclass, jbyteArray value, jbyteArray pk) +{ + auto bigNumValue = JavaBigIntegerToBigNum(env, value); + bcos::bytes pkBytes; + auto pkBuffer = convertToInputBuffer(pkBytes, env, pk); + // Note: pkBuffer.len is not the real keyBytes + auto cipherLen = paillier_max_cipher_bytes(pkBuffer.len * 8); + if (!last_call_success()) + { + THROW_JNI_EXCEPTION(env, get_last_error_msg()); + return nullptr; + } + bcos::bytes cipherBytes(cipherLen); + OutputBuffer cipherBuffer{cipherBytes.data(), cipherBytes.size()}; + paillier_encryt_without_precompute(&cipherBuffer, nullptr, bigNumValue.bn().get(), &pkBuffer); + if (!last_call_success()) + { + THROW_JNI_EXCEPTION(env, get_last_error_msg()); + return nullptr; + } + // copy the result to jResult + auto jResult = env->NewByteArray(cipherBuffer.len); + env->SetByteArrayRegion(jResult, 0, cipherBuffer.len, (jbyte*)cipherBuffer.data); + return jResult; +} + +/* + * Class: com_webank_wedpr_sdk_jni_homo_NativePaillier + * Method: decrypt + * Signature: ([BJ)[B + */ +JNIEXPORT jbyteArray JNICALL Java_com_webank_wedpr_sdk_jni_homo_NativePaillier_decrypt( + JNIEnv* env, jclass, jbyteArray cipher, jlong keypair) +{ + bcos::bytes cipherBytes; + auto cipherBuffer = convertToInputBuffer(cipherBytes, env, cipher); + auto result = paillier_decrypt(&cipherBuffer, reinterpret_cast(keypair)); + if (!last_call_success()) + { + THROW_JNI_EXCEPTION(env, get_last_error_msg()); + return nullptr; + } + auto bigIntegerBytes = BigNumToJavaBigIntegerBytes(env, result); + + if (result) + { + BN_clear_free(result); + } + return bigIntegerBytes; +} + +/* + * Class: com_webank_wedpr_sdk_jni_homo_NativePaillier + * Method: decrypt + * Signature: ([B[B[B)[B + */ +JNIEXPORT jbyteArray JNICALL +Java_com_webank_wedpr_sdk_jni_homo_NativePaillier_decryptWithoutPrecompute( + JNIEnv* env, jclass, jbyteArray cipher, jbyteArray sk, jbyteArray pk) +{ + bcos::bytes cipherBytes; + auto cipherBuffer = convertToInputBuffer(cipherBytes, env, cipher); + bcos::bytes skBytes; + auto skBuffer = convertToInputBuffer(skBytes, env, sk); + bcos::bytes pkBytes; + auto pkBuffer = convertToInputBuffer(pkBytes, env, pk); + auto result = paillier_decrypt_without_precompute(&cipherBuffer, &skBuffer, &pkBuffer); + + if (!last_call_success()) + { + THROW_JNI_EXCEPTION(env, get_last_error_msg()); + return nullptr; + } + auto bigIntegerBytes = BigNumToJavaBigIntegerBytes(env, result); + if (result) + { + BN_clear_free(result); + } + return bigIntegerBytes; +} + + +jbyteArray Java_com_webank_wedpr_sdk_jni_homo_NativePaillier_sub_or_add_impl( + JNIEnv* env, jbyteArray cipher1, jbyteArray cipher2, jlong public_key, bool add) +{ + bcos::bytes c1Bytes; + auto cipher1Buffer = convertToInputBuffer(c1Bytes, env, cipher1); + bcos::bytes c2Bytes; + auto cipher2Buffer = convertToInputBuffer(c2Bytes, env, cipher2); + auto pk = reinterpret_cast(public_key); + + auto cipherLen = paillier_max_cipher_bytes(paillier_key_bits_from_public_key(pk)); + if (!last_call_success()) + { + THROW_JNI_EXCEPTION(env, get_last_error_msg()); + return nullptr; + } + bcos::bytes resultBytes(cipherLen); + OutputBuffer resultBuffer{resultBytes.data(), resultBytes.size()}; + if (add) + { + paillier_add(&resultBuffer, &cipher1Buffer, &cipher2Buffer, pk); + } + else + { + paillier_sub(&resultBuffer, &cipher1Buffer, &cipher2Buffer, pk); + } + + // call error + if (!last_call_success()) + { + THROW_JNI_EXCEPTION(env, get_last_error_msg()); + return nullptr; + } + // copy the result to jResult + auto jResult = env->NewByteArray(resultBuffer.len); + env->SetByteArrayRegion(jResult, 0, resultBuffer.len, (jbyte*)resultBuffer.data); + return jResult; +} + +/* + * Class: com_webank_wedpr_sdk_jni_homo_NativePaillier + * Method: add + * Signature: ([B[BJ)[B + */ +JNIEXPORT jbyteArray JNICALL Java_com_webank_wedpr_sdk_jni_homo_NativePaillier_add( + JNIEnv* env, jclass, jbyteArray cipher1, jbyteArray cipher2, jlong public_key) +{ + return Java_com_webank_wedpr_sdk_jni_homo_NativePaillier_sub_or_add_impl( + env, cipher1, cipher2, public_key, true); +} + +/* + * Class: com_webank_wedpr_sdk_jni_homo_NativePaillier + * Method: sub + * Signature: ([B[BJ)[B + */ +JNIEXPORT jbyteArray JNICALL Java_com_webank_wedpr_sdk_jni_homo_NativePaillier_sub( + JNIEnv* env, jclass, jbyteArray cipher1, jbyteArray cipher2, jlong public_key) +{ + return Java_com_webank_wedpr_sdk_jni_homo_NativePaillier_sub_or_add_impl( + env, cipher1, cipher2, public_key, false); +} + + +jbyteArray Java_com_webank_wedpr_sdk_jni_homo_NativePaillier_sub_or_add_without_precompute_impl( + JNIEnv* env, jbyteArray cipher1, jbyteArray cipher2, jbyteArray public_key, bool add) +{ + bcos::bytes c1Bytes; + auto cipher1Buffer = convertToInputBuffer(c1Bytes, env, cipher1); + bcos::bytes c2Bytes; + auto cipher2Buffer = convertToInputBuffer(c2Bytes, env, cipher2); + bcos::bytes pkBytes; + auto pkBuffer = convertToInputBuffer(pkBytes, env, public_key); + auto cipherLen = paillier_max_cipher_bytes(pkBuffer.len * 8); + if (!last_call_success()) + { + THROW_JNI_EXCEPTION(env, get_last_error_msg()); + return nullptr; + } + bcos::bytes resultBytes(cipherLen); + OutputBuffer resultBuffer{resultBytes.data(), resultBytes.size()}; + if (add) + { + paillier_add_without_precompute(&resultBuffer, &cipher1Buffer, &cipher2Buffer, &pkBuffer); + } + else + { + paillier_add_without_precompute(&resultBuffer, &cipher1Buffer, &cipher2Buffer, &pkBuffer); + } + // call error + if (!last_call_success()) + { + THROW_JNI_EXCEPTION(env, get_last_error_msg()); + return nullptr; + } + // copy the result to jResult + auto jResult = env->NewByteArray(resultBuffer.len); + env->SetByteArrayRegion(jResult, 0, resultBuffer.len, (jbyte*)resultBuffer.data); + return jResult; +} + +/* + * Class: com_webank_wedpr_sdk_jni_homo_NativePaillier + * Method: add + * Signature: ([B[B[B[B)[B + */ +JNIEXPORT jbyteArray JNICALL Java_com_webank_wedpr_sdk_jni_homo_NativePaillier_addWithoutPrecompute( + JNIEnv* env, jclass, jbyteArray cipher1, jbyteArray cipher2, jbyteArray pkBytes) +{ + return Java_com_webank_wedpr_sdk_jni_homo_NativePaillier_sub_or_add_without_precompute_impl( + env, cipher1, cipher2, pkBytes, true); +} + +/* + * Class: com_webank_wedpr_sdk_jni_homo_NativePaillier + * Method: sub + * Signature: ([B[B[B)[B + */ +JNIEXPORT jbyteArray JNICALL Java_com_webank_wedpr_sdk_jni_homo_NativePaillier_subWithoutPrecompute( + JNIEnv* env, jclass, jbyteArray cipher1, jbyteArray cipher2, jbyteArray pkBytes) +{ + return Java_com_webank_wedpr_sdk_jni_homo_NativePaillier_sub_or_add_without_precompute_impl( + env, cipher1, cipher2, pkBytes, false); +} + +/* + * Class: com_webank_wedpr_sdk_jni_homo_NativePaillier + * Method: scalaMul + * Signature: ([B[BJ)[B + */ +JNIEXPORT jbyteArray JNICALL Java_com_webank_wedpr_sdk_jni_homo_NativePaillier_scalaMul( + JNIEnv* env, jclass, jbyteArray value, jbyteArray cipherBytes, jlong public_key) +{ + auto v = JavaBigIntegerToBigNum(env, value); + bcos::bytes cipherCBytes; + auto cipherBuffer = convertToInputBuffer(cipherCBytes, env, cipherBytes); + auto pk = reinterpret_cast(public_key); + + // allocate the result buffer + auto cipherLen = paillier_max_cipher_bytes(paillier_key_bits_from_public_key(pk)); + if (!last_call_success()) + { + THROW_JNI_EXCEPTION(env, get_last_error_msg()); + return nullptr; + } + bcos::bytes resultBytes(cipherLen); + OutputBuffer resultBuffer{resultBytes.data(), resultBytes.size()}; + // paillier scala_mul + paillier_scala_mul(&resultBuffer, v.bn().get(), &cipherBuffer, pk); + if (!last_call_success()) + { + THROW_JNI_EXCEPTION(env, get_last_error_msg()); + return nullptr; + } + // copy the result + auto jResult = env->NewByteArray(resultBuffer.len); + env->SetByteArrayRegion(jResult, 0, resultBuffer.len, (jbyte*)resultBuffer.data); + return jResult; +} + +/* + * Class: com_webank_wedpr_sdk_jni_homo_NativePaillier + * Method: scalMul + * Signature: ([B[B[B)[B + */ +JNIEXPORT jbyteArray JNICALL +Java_com_webank_wedpr_sdk_jni_homo_NativePaillier_scalaMulWithoutPrecompute( + JNIEnv* env, jclass, jbyteArray value, jbyteArray cipherBytes, jbyteArray pkBytes) +{ + auto v = JavaBigIntegerToBigNum(env, value); + bcos::bytes cipherCBytes; + auto cipherBuffer = convertToInputBuffer(cipherCBytes, env, cipherBytes); + bcos::bytes pkCBytes; + auto pkBuffer = convertToInputBuffer(pkCBytes, env, pkBytes); + auto cipherLen = paillier_max_cipher_bytes(pkBuffer.len * 8); + if (!last_call_success()) + { + THROW_JNI_EXCEPTION(env, get_last_error_msg()); + return nullptr; + } + bcos::bytes resultBytes(cipherLen); + OutputBuffer resultBuffer{resultBytes.data(), resultBytes.size()}; + // paillier scala_mul + paillier_scala_mul_without_precompute(&resultBuffer, v.bn().get(), &cipherBuffer, &pkBuffer); + + if (!last_call_success()) + { + THROW_JNI_EXCEPTION(env, get_last_error_msg()); + return nullptr; + } + // copy the result + auto jResult = env->NewByteArray(resultBuffer.len); + env->SetByteArrayRegion(jResult, 0, resultBuffer.len, (jbyte*)resultBuffer.data); + return jResult; +} + +/* + * Class: com_webank_wedpr_sdk_jni_homo_NativePaillier + * Method: loadPrivateKey + * Signature: ([B)J + */ +JNIEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_homo_NativePaillier_loadPrivateKey( + JNIEnv* env, jclass, jbyteArray privateBytes) +{ + bcos::bytes skBytes; + auto privateKeyBuffer = convertToInputBuffer(skBytes, env, privateBytes); + jlong result = reinterpret_cast(paillier_load_private_key(&privateKeyBuffer)); + if (!last_call_success()) + { + THROW_JNI_EXCEPTION(env, get_last_error_msg()); + return -1; + } + return result; +} \ No newline at end of file diff --git a/cpp/wedpr-crypto/sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_homo_NativePaillier.h b/cpp/wedpr-crypto/sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_homo_NativePaillier.h new file mode 100644 index 00000000..ebb82aa0 --- /dev/null +++ b/cpp/wedpr-crypto/sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_homo_NativePaillier.h @@ -0,0 +1,235 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class com_webank_wedpr_sdk_jni_homo_NativePaillier */ + +#ifndef _Included_com_webank_wedpr_sdk_jni_homo_NativePaillier +#define _Included_com_webank_wedpr_sdk_jni_homo_NativePaillier +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: com_webank_wedpr_sdk_jni_homo_NativePaillier + * Method: maxPublicKeyBytes + * Signature: (I)I + */ +JNIEXPORT jint JNICALL Java_com_webank_wedpr_sdk_jni_homo_NativePaillier_maxPublicKeyBytes( + JNIEnv*, jclass, jint); + +/* + * Class: com_webank_wedpr_sdk_jni_homo_NativePaillier + * Method: maxPrivateKeyBytes + * Signature: (I)I + */ +JNIEXPORT jint JNICALL Java_com_webank_wedpr_sdk_jni_homo_NativePaillier_maxPrivateKeyBytes( + JNIEnv*, jclass, jint); + +/* + * Class: com_webank_wedpr_sdk_jni_homo_NativePaillier + * Method: maxCipherBytes + * Signature: (I)I + */ +JNIEXPORT jint JNICALL Java_com_webank_wedpr_sdk_jni_homo_NativePaillier_maxCipherBytes( + JNIEnv*, jclass, jint); + +/* + * Class: com_webank_wedpr_sdk_jni_homo_NativePaillier + * Method: keyBitsFromKeyPair + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_com_webank_wedpr_sdk_jni_homo_NativePaillier_keyBitsFromKeyPair( + JNIEnv*, jclass, jlong); + +/* + * Class: com_webank_wedpr_sdk_jni_homo_NativePaillier + * Method: keyBitsFromPublicKey + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_com_webank_wedpr_sdk_jni_homo_NativePaillier_keyBitsFromPublicKey( + JNIEnv*, jclass, jlong); + +/* + * Class: com_webank_wedpr_sdk_jni_homo_NativePaillier + * Method: generateKeyPair + * Signature: (I)J + */ +JNIEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_homo_NativePaillier_generateKeyPair( + JNIEnv*, jclass, jint); + +/* + * Class: com_webank_wedpr_sdk_jni_homo_NativePaillier + * Method: loadKeyPair + * Signature: ([B[B)J + */ +JNIEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_homo_NativePaillier_loadKeyPair( + JNIEnv*, jclass, jbyteArray, jbyteArray); + +/* + * Class: com_webank_wedpr_sdk_jni_homo_NativePaillier + * Method: freeKeyPair + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_homo_NativePaillier_freeKeyPair( + JNIEnv*, jclass, jlong); + +/* + * Class: com_webank_wedpr_sdk_jni_homo_NativePaillier + * Method: loadPublicKey + * Signature: ([B)J + */ +JNIEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_homo_NativePaillier_loadPublicKey( + JNIEnv*, jclass, jbyteArray); + +/* + * Class: com_webank_wedpr_sdk_jni_homo_NativePaillier + * Method: freePublicKey + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_homo_NativePaillier_freePublicKey( + JNIEnv*, jclass, jlong); + +/* + * Class: com_webank_wedpr_sdk_jni_homo_NativePaillier + * Method: loadPrivateKey + * Signature: ([B)J + */ +JNIEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_homo_NativePaillier_loadPrivateKey( + JNIEnv*, jclass, jbyteArray); + +/* + * Class: com_webank_wedpr_sdk_jni_homo_NativePaillier + * Method: freePrivateKey + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_homo_NativePaillier_freePrivateKey( + JNIEnv*, jclass, jlong); + +/* + * Class: com_webank_wedpr_sdk_jni_homo_NativePaillier + * Method: getPublicKeyJniObject + * Signature: (J)J + */ +JNIEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_homo_NativePaillier_getPublicKeyJniObject( + JNIEnv*, jclass, jlong); + +/* + * Class: com_webank_wedpr_sdk_jni_homo_NativePaillier + * Method: getPublicKeyBytesFromKeyPair + * Signature: (J)[B + */ +JNIEXPORT jbyteArray JNICALL +Java_com_webank_wedpr_sdk_jni_homo_NativePaillier_getPublicKeyBytesFromKeyPair( + JNIEnv*, jclass, jlong); + +/* + * Class: com_webank_wedpr_sdk_jni_homo_NativePaillier + * Method: getPrivateKeyBytesFromKeyPair + * Signature: (J)[B + */ +JNIEXPORT jbyteArray JNICALL +Java_com_webank_wedpr_sdk_jni_homo_NativePaillier_getPrivateKeyBytesFromKeyPair( + JNIEnv*, jclass, jlong); + +/* + * Class: com_webank_wedpr_sdk_jni_homo_NativePaillier + * Method: encryptFast + * Signature: ([BJ)[B + */ +JNIEXPORT jbyteArray JNICALL Java_com_webank_wedpr_sdk_jni_homo_NativePaillier_encryptFast( + JNIEnv*, jclass, jbyteArray, jlong); + +/* + * Class: com_webank_wedpr_sdk_jni_homo_NativePaillier + * Method: encryptFastWithoutPrecompute + * Signature: ([B[B[B)[B + */ +JNIEXPORT jbyteArray JNICALL +Java_com_webank_wedpr_sdk_jni_homo_NativePaillier_encryptFastWithoutPrecompute( + JNIEnv*, jclass, jbyteArray, jbyteArray, jbyteArray); + +/* + * Class: com_webank_wedpr_sdk_jni_homo_NativePaillier + * Method: encrypt + * Signature: ([BJ)[B + */ +JNIEXPORT jbyteArray JNICALL Java_com_webank_wedpr_sdk_jni_homo_NativePaillier_encrypt( + JNIEnv*, jclass, jbyteArray, jlong); + +/* + * Class: com_webank_wedpr_sdk_jni_homo_NativePaillier + * Method: encryptWithoutPrecompute + * Signature: ([B[B)[B + */ +JNIEXPORT jbyteArray JNICALL +Java_com_webank_wedpr_sdk_jni_homo_NativePaillier_encryptWithoutPrecompute( + JNIEnv*, jclass, jbyteArray, jbyteArray); + +/* + * Class: com_webank_wedpr_sdk_jni_homo_NativePaillier + * Method: decrypt + * Signature: ([BJ)[B + */ +JNIEXPORT jbyteArray JNICALL Java_com_webank_wedpr_sdk_jni_homo_NativePaillier_decrypt( + JNIEnv*, jclass, jbyteArray, jlong); + +/* + * Class: com_webank_wedpr_sdk_jni_homo_NativePaillier + * Method: decryptWithoutPrecompute + * Signature: ([B[B[B)[B + */ +JNIEXPORT jbyteArray JNICALL +Java_com_webank_wedpr_sdk_jni_homo_NativePaillier_decryptWithoutPrecompute( + JNIEnv*, jclass, jbyteArray, jbyteArray, jbyteArray); + +/* + * Class: com_webank_wedpr_sdk_jni_homo_NativePaillier + * Method: add + * Signature: ([B[BJ)[B + */ +JNIEXPORT jbyteArray JNICALL Java_com_webank_wedpr_sdk_jni_homo_NativePaillier_add( + JNIEnv*, jclass, jbyteArray, jbyteArray, jlong); + +/* + * Class: com_webank_wedpr_sdk_jni_homo_NativePaillier + * Method: addWithoutPrecompute + * Signature: ([B[B[B)[B + */ +JNIEXPORT jbyteArray JNICALL Java_com_webank_wedpr_sdk_jni_homo_NativePaillier_addWithoutPrecompute( + JNIEnv*, jclass, jbyteArray, jbyteArray, jbyteArray); + +/* + * Class: com_webank_wedpr_sdk_jni_homo_NativePaillier + * Method: sub + * Signature: ([B[BJ)[B + */ +JNIEXPORT jbyteArray JNICALL Java_com_webank_wedpr_sdk_jni_homo_NativePaillier_sub( + JNIEnv*, jclass, jbyteArray, jbyteArray, jlong); + +/* + * Class: com_webank_wedpr_sdk_jni_homo_NativePaillier + * Method: subWithoutPrecompute + * Signature: ([B[B[B)[B + */ +JNIEXPORT jbyteArray JNICALL Java_com_webank_wedpr_sdk_jni_homo_NativePaillier_subWithoutPrecompute( + JNIEnv*, jclass, jbyteArray, jbyteArray, jbyteArray); + +/* + * Class: com_webank_wedpr_sdk_jni_homo_NativePaillier + * Method: scalaMul + * Signature: ([B[BJ)[B + */ +JNIEXPORT jbyteArray JNICALL Java_com_webank_wedpr_sdk_jni_homo_NativePaillier_scalaMul( + JNIEnv*, jclass, jbyteArray, jbyteArray, jlong); + +/* + * Class: com_webank_wedpr_sdk_jni_homo_NativePaillier + * Method: scalMulWithoutPrecompute + * Signature: ([B[B[B)[B + */ +JNIEXPORT jbyteArray JNICALL +Java_com_webank_wedpr_sdk_jni_homo_NativePaillier_scalaMulWithoutPrecompute( + JNIEnv*, jclass, jbyteArray, jbyteArray, jbyteArray); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/cpp/wedpr-crypto/sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/demo/GenerateKeys.java b/cpp/wedpr-crypto/sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/demo/GenerateKeys.java new file mode 100644 index 00000000..ef18128d --- /dev/null +++ b/cpp/wedpr-crypto/sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/demo/GenerateKeys.java @@ -0,0 +1,64 @@ +/** + * Copyright 2023 [wedpr] + * + *

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. + */ +package com.webank.wedpr.sdk.demo; + +import com.webank.wedpr.sdk.jni.common.JniException; +import com.webank.wedpr.sdk.jni.common.Utilities; +import com.webank.wedpr.sdk.jni.crypto.FastOre; +import com.webank.wedpr.sdk.jni.crypto.SymmetricEncryption; +import com.webank.wedpr.sdk.jni.homo.NativeFloatingIhc; +import com.webank.wedpr.sdk.jni.homo.NativePaillier; + +public class GenerateKeys { + public static void main(String[] args) throws JniException { + // AES-128-CBC + System.out.println("Generate key for AES-128-CBC:"); + byte[] sk = + SymmetricEncryption.generateKey( + SymmetricEncryption.AlgorithmType.AES_128.ordinal(), + SymmetricEncryption.OperationMode.CBC.ordinal()); + System.out.println(Utilities.bytesToHex(sk)); + // AES-256-CBC + System.out.println("Generate key for AES-256-CBC:"); + sk = + SymmetricEncryption.generateKey( + SymmetricEncryption.AlgorithmType.AES_256.ordinal(), + SymmetricEncryption.OperationMode.CBC.ordinal()); + System.out.println(Utilities.bytesToHex(sk)); + // ore + System.out.println("Generate key for ORE:"); + sk = FastOre.generateKey(); + System.out.println(Utilities.bytesToHex(sk)); + // ihc-128 + System.out.println("Generate key for IHC-128:"); + sk = NativeFloatingIhc.generateKey(NativeFloatingIhc.mode.IHC_128.ordinal()); + System.out.println(Utilities.bytesToHex(sk)); + // ihc-256 + System.out.println("Generate key for IHC-256:"); + sk = NativeFloatingIhc.generateKey(NativeFloatingIhc.mode.IHC_256.ordinal()); + System.out.println(Utilities.bytesToHex(sk)); + // paillier + System.out.println("Generate key for paillier-2048:"); + long keyPair = NativePaillier.generateKeyPair(2048); + System.out.println( + "sk: " + + Utilities.bytesToHex( + NativePaillier.getPrivateKeyBytesFromKeyPair(keyPair))); + System.out.println( + "pk: " + + Utilities.bytesToHex( + NativePaillier.getPublicKeyBytesFromKeyPair(keyPair))); + NativePaillier.freeKeyPair(keyPair); + } +} diff --git a/cpp/wedpr-crypto/sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/codec/FloatingPointNumber.java b/cpp/wedpr-crypto/sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/codec/FloatingPointNumber.java new file mode 100644 index 00000000..8df71e0c --- /dev/null +++ b/cpp/wedpr-crypto/sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/codec/FloatingPointNumber.java @@ -0,0 +1,111 @@ +/** + * Copyright 2023 [wedpr] + * + *

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. + */ +package com.webank.wedpr.sdk.jni.codec; + +import java.math.BigInteger; +import java.util.Objects; + +// the floating-point-value +public class FloatingPointNumber { + private final BigInteger significant; + private final int exponent; + + FloatingPointNumber(byte[] significantBytes, int exponent) { + this.significant = new BigInteger(significantBytes); + this.exponent = exponent; + } + + public FloatingPointNumber(BigInteger significant, int exponent) { + this.significant = significant; + this.exponent = exponent; + } + + public BigInteger getSignificant() { + return significant; + } + + public byte[] getSignificantBytes() { + return significant.toByteArray(); + } + + public int getExponent() { + return exponent; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + FloatingPointNumber that = (FloatingPointNumber) o; + return exponent == that.exponent && Objects.equals(significant, that.significant); + } + + // @Override + public FloatingPointNumber add(FloatingPointNumber other) { + if (this.exponent == other.exponent) { + return new FloatingPointNumber( + this.getSignificant().add(other.getSignificant()), this.exponent); + } + if (this.exponent < other.exponent) { + int diffExp = other.exponent - this.exponent; + BigInteger baseC = BigInteger.valueOf(10).pow(diffExp); + FloatingPointNumber otherNew = + new FloatingPointNumber(other.getSignificant().multiply(baseC), this.exponent); + return new FloatingPointNumber( + otherNew.getSignificant().add(this.getSignificant()), otherNew.exponent); + } + int diffExp = this.exponent - other.exponent; + BigInteger baseC = BigInteger.valueOf(10).pow(diffExp); + FloatingPointNumber thisNew = + new FloatingPointNumber(this.getSignificant().multiply(baseC), other.exponent); + return new FloatingPointNumber( + thisNew.getSignificant().add(other.getSignificant()), thisNew.exponent); + } + + public FloatingPointNumber sub(FloatingPointNumber other) { + if (this.exponent == other.exponent) { + return new FloatingPointNumber( + this.getSignificant().add(other.getSignificant()), this.exponent); + } + if (this.exponent < other.exponent) { + int diffExp = other.exponent - this.exponent; + BigInteger baseC = BigInteger.valueOf(10).pow(diffExp); + FloatingPointNumber otherNew = + new FloatingPointNumber(other.getSignificant().multiply(baseC), this.exponent); + return new FloatingPointNumber( + otherNew.getSignificant().subtract(this.getSignificant()), otherNew.exponent); + } + int diffExp = this.exponent - other.exponent; + BigInteger baseC = BigInteger.valueOf(10).pow(diffExp); + FloatingPointNumber thisNew = + new FloatingPointNumber(this.getSignificant().multiply(baseC), other.exponent); + return new FloatingPointNumber( + thisNew.getSignificant().subtract(other.getSignificant()), thisNew.exponent); + } + + @Override + public int hashCode() { + return Objects.hash(significant, exponent); + } + + @Override + public String toString() { + return "FloatingPointNumber{" + + "significant=" + + significant + + ", exponent=" + + exponent + + '}'; + } +} diff --git a/cpp/wedpr-crypto/sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/codec/NumberCodec.java b/cpp/wedpr-crypto/sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/codec/NumberCodec.java new file mode 100644 index 00000000..6f7388e7 --- /dev/null +++ b/cpp/wedpr-crypto/sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/codec/NumberCodec.java @@ -0,0 +1,43 @@ +/** + * Copyright 2023 [wedpr] + * + *

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. + */ +package com.webank.wedpr.sdk.jni.codec; + +import java.math.BigDecimal; +import java.math.BigInteger; + +public interface NumberCodec { + FloatingPointNumber encode(BigInteger value) throws NumberCodecException; + + FloatingPointNumber encode(long value) throws NumberCodecException; + + FloatingPointNumber encode(double value) throws NumberCodecException; + + FloatingPointNumber encode(BigDecimal value) throws NumberCodecException; + + BigInteger decodeBigInteger(FloatingPointNumber encodedValue) throws NumberCodecException; + + long decodeLong(FloatingPointNumber encodedValue) throws NumberCodecException; + + double decodeDouble(FloatingPointNumber encodedValue) throws NumberCodecException; + + BigDecimal decodeBigDecimal(FloatingPointNumber encodedValue) throws NumberCodecException; + + public byte[] toBytes(BigDecimal value); + + public byte[] toBytes(Double value); + + double toDouble(byte[] value); + + BigDecimal toBigDecimal(byte[] value); +} diff --git a/cpp/wedpr-crypto/sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/codec/NumberCodecException.java b/cpp/wedpr-crypto/sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/codec/NumberCodecException.java new file mode 100644 index 00000000..a288901d --- /dev/null +++ b/cpp/wedpr-crypto/sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/codec/NumberCodecException.java @@ -0,0 +1,21 @@ +/** + * Copyright 2023 [wedpr] + * + *

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. + */ +package com.webank.wedpr.sdk.jni.codec; + +public class NumberCodecException extends Exception { + + public NumberCodecException(String message) { + super(message); + } +} diff --git a/cpp/wedpr-crypto/sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/codec/NumberCodecImpl.java b/cpp/wedpr-crypto/sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/codec/NumberCodecImpl.java new file mode 100644 index 00000000..f1841709 --- /dev/null +++ b/cpp/wedpr-crypto/sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/codec/NumberCodecImpl.java @@ -0,0 +1,149 @@ +/** + * Copyright 2023 [wedpr] + * + *

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. + */ +package com.webank.wedpr.sdk.jni.codec; + +import java.math.BigDecimal; +import java.math.BigInteger; + +public class NumberCodecImpl implements NumberCodec { + private static final int BASE = 10; + /** + * encode the given BigInteger into EncodedValue + * + * @param value + * @return + */ + public FloatingPointNumber encode(BigInteger value) throws NumberCodecException { + if (value == null) { + throw new NumberCodecException("Not support encode null BigInteger!"); + } + return new FloatingPointNumber(value, 0); + } + + /** + * encode the given long value into EncodedValue + * + * @param value + * @return + * @throws NumberCodecException + */ + public FloatingPointNumber encode(long value) throws NumberCodecException { + return encode(BigInteger.valueOf(value)); + } + + /** + * encode the given big-decimal into EncodedValue + * + * @param value + * @return + * @throws NumberCodecException + */ + public FloatingPointNumber encode(BigDecimal value) throws NumberCodecException { + if (value == null) { + throw new NumberCodecException("Not support encode null BigDecimal!"); + } + BigInteger significant; + int exp = -value.scale(); + if (value.scale() > 0) { + significant = value.scaleByPowerOfTen(value.scale()).toBigInteger(); + } else { + significant = value.unscaledValue(); + } + return new FloatingPointNumber(significant, exp); + } + + public FloatingPointNumber encode(double value) throws NumberCodecException { + if (Double.isInfinite(value) || Double.isNaN(value)) { + throw new NumberCodecException("Not support encode null/infinite double!"); + } + // convert double to BigDecimal + BigDecimal decimalValue = BigDecimal.valueOf(value); + return encode(decimalValue); + } + + /** + * decode the encodedValue into BigInteger + * + * @param encodedValue + * @return + * @throws NumberCodecException + */ + public BigInteger decodeBigInteger(FloatingPointNumber encodedValue) + throws NumberCodecException { + return encodedValue.getSignificant(); + } + + /** + * decode the encodedValue into long + * + * @param encodedValue + * @return + * @throws NumberCodecException + */ + public long decodeLong(FloatingPointNumber encodedValue) throws NumberCodecException { + BigInteger value = decodeBigInteger(encodedValue); + // check overflow or not + if (value.compareTo(BigInteger.valueOf(Long.MIN_VALUE)) < 0 + || value.compareTo(BigInteger.valueOf(Long.MAX_VALUE)) > 0) { + throw new NumberCodecException( + "the Decoded value can't be represented as long, decoded value: " + + value.toString()); + } + return value.longValue(); + } + + /** + * decode the given encodedValue into BigDecimal + * + * @param encodedValue + * @return + * @throws NumberCodecException + */ + public BigDecimal decodeBigDecimal(FloatingPointNumber encodedValue) + throws NumberCodecException { + BigInteger significant = encodedValue.getSignificant(); + return new BigDecimal(significant, -encodedValue.getExponent()); + } + + /** + * decode the encodedValue into double + * + * @param encodedValue + * @return + * @throws NumberCodecException + */ + public double decodeDouble(FloatingPointNumber encodedValue) throws NumberCodecException { + return decodeBigDecimal(encodedValue).doubleValue(); + } + + @Override + public byte[] toBytes(BigDecimal value) { + return value.toPlainString().getBytes(); + } + + @Override + public byte[] toBytes(Double value) { + return String.valueOf(value).getBytes(); + } + + @Override + public double toDouble(byte[] value) { + return Double.parseDouble(new String(value)); + } + + @Override + public BigDecimal toBigDecimal(byte[] value) { + return new BigDecimal(new String(value)); + } +} diff --git a/cpp/wedpr-crypto/sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/common/JniException.java b/cpp/wedpr-crypto/sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/common/JniException.java new file mode 100644 index 00000000..2bf87ce9 --- /dev/null +++ b/cpp/wedpr-crypto/sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/common/JniException.java @@ -0,0 +1,20 @@ +/** + * Copyright 2023 [wedpr] + * + *

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. + */ +package com.webank.wedpr.sdk.jni.common; + +public class JniException extends Exception { + public JniException(String message) { + super(message); + } +} diff --git a/cpp/wedpr-crypto/sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/common/JniLibLoader.java b/cpp/wedpr-crypto/sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/common/JniLibLoader.java new file mode 100644 index 00000000..e2e7cf55 --- /dev/null +++ b/cpp/wedpr-crypto/sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/common/JniLibLoader.java @@ -0,0 +1,278 @@ +/** + * Copyright 2023 [wedpr] + * + *

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. + */ +package com.webank.wedpr.sdk.jni.common; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.Field; +import java.nio.file.Files; +import java.nio.file.StandardCopyOption; +import java.util.Objects; +import java.util.Scanner; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Helper class to load ppc-crypto-sdk jni resources. + * + * @author octopus + */ +public final class JniLibLoader { + private static final Logger logger = LoggerFactory.getLogger(JniLibLoader.class); + + public static final String LINUX = "linux"; + public static final String MAC = "mac"; + public static final String WIN = "win"; + + public static final String NATIVE_RESOURCE_LIB_NAME = "ppc-crypto-sdk-jni"; + public static final String NATIVE_RESOURCE_HOME = "/META-INF/native"; + public static final String NATIVE_WIN_DEPS_DIR = NATIVE_RESOURCE_HOME + "/win/"; + public static final String WIN_DEPS_FILE_LIST = "file.list"; + + public static final String OS_NAME = getOs(); + public static final String ARCH_NAME = getArch(); + + private static File WORKDIR; + + static { + // 1. initialize workdir + + // -Dcom.webank.wedpr.workdir + String workdir = System.getProperty("com.webank.wedpr.workdir"); + if (workdir != null) { + try { + File f = new File(workdir); + f.mkdirs(); + WORKDIR = f; + logger.info("initialize workdir, -Dcom.webank.wedpr.workdir: {}", WORKDIR); + } catch (Exception e) { + logger.debug("initialize workdir, cannot mkdir workdir: {}, e: ", workdir, e); + workdir = null; + } + } + + // default -Djava.io.tmpdir + if (workdir == null) { + workdir = System.getProperty("java.io.tmpdir"); + File f = new File(workdir); + f.mkdirs(); + WORKDIR = f; + + logger.info("initialize workdir, -Djava.io.tmpdirs: {}", WORKDIR); + } + } + + public static String getArch() { + String archName = System.getProperty("os.arch", ""); + if (archName.contains("aarch64") || archName.contains("arm64")) { + return "arm"; + } else { + return ""; + } + } + + public static String getLibName(String baseName) { + String osName = OS_NAME; + String archName = ARCH_NAME; + + logger.debug("osName: {}, archName: {}", osName, archName); + + if (osName.contains(WIN)) { + return baseName + ".dll"; + } else if (osName.contains(LINUX)) { + String arch = getArch(); + if ("arm".equals(arch)) { + return "lib" + baseName + "-aarch64" + ".so"; + } + return "lib" + baseName + ".so"; + } else if (osName.contains(MAC)) { + String arch = getArch(); + if ("arm".equals(arch)) { + return "lib" + baseName + "-aarch64" + ".dylib"; + } + return "lib" + baseName + ".dylib"; + } else { + throw new RuntimeException("unrecognized OS: " + osName); + } + } + + public static String getOs() { + String osName = System.getProperty("os.name").toLowerCase(); + if (osName.contains(WIN)) { + return WIN; + } else if (osName.contains(LINUX)) { + return LINUX; + } else if (osName.contains(MAC)) { + return MAC; + } else { + throw new RuntimeException("unrecognized OS: " + osName); + } + } + + public static void loadJniLibrary() { + String libPath = null; + boolean loadLibFromFsOk = false; + try { + // 1. try to load library from filesystem + // -Dcom.webank.wedpr.jni.library.path + libPath = System.getProperty("com.webank.wedpr.jni.library.path"); + if (libPath != null) { + logger.info( + "try to load library -Dcom.webank.wedpr.jni.library.path, libPath: {}", + libPath); + // try to load library from filesystem first + loadLibraryFromFs( + libPath, NATIVE_RESOURCE_LIB_NAME, new File(libPath).isAbsolute()); + loadLibFromFsOk = true; + } + } catch (Exception e0) { + logger.error("unable to load library from fs, libDir: {}, e: ", libPath, e0); + } + + // 2. try to load library from jar + if (!loadLibFromFsOk) { + try { + logger.info("try to load library from jar"); + if (Objects.equals(getOs(), WIN)) { + loadWinDepsLibraryFromJar(); + } + loadLibraryFromJar(NATIVE_RESOURCE_LIB_NAME); + } catch (Exception e1) { + logger.error("unable to load library from fs, e: ", e1); + throw new UnsatisfiedLinkError(e1.toString()); + } + } + } + + public static void loadLibrary(String lib, boolean absolute) { + if (absolute) { + System.load(lib); + } else { + System.loadLibrary(lib); + } + } + + public static void addLibraryDir(String libraryPath) + throws NoSuchFieldException, IllegalAccessException { + Field userPathsField = ClassLoader.class.getDeclaredField("usr_paths"); + userPathsField.setAccessible(true); + String[] paths = (String[]) userPathsField.get(null); + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < paths.length; i++) { + if (libraryPath.equals(paths[i])) { + continue; + } + sb.append(paths[i]).append(File.pathSeparator); + } + sb.append(libraryPath); + System.setProperty("java.library.path", sb.toString()); + logger.info("modify, java.library.path: " + sb.toString()); + final Field sysPathsField = ClassLoader.class.getDeclaredField("sys_paths"); + sysPathsField.setAccessible(true); + sysPathsField.set(null, null); + } + + public static void loadLibraryFromFs(String dir, String libName, boolean absolute) { + String resource = dir + "/" + getLibName(libName); + loadLibrary(resource, absolute); + } + + public static void loadLibraryFromJar(String baseName) + throws IOException, NoSuchFieldException, IllegalAccessException { + String libName = getLibName(baseName); + File tempDir = new File(WORKDIR, String.valueOf(System.nanoTime())); + // create temp dir + tempDir.mkdirs(); + File tempFile = new File(tempDir, libName); + logger.info("tempDir: {}, tempFile: {}", tempDir, tempFile); + + String resource = NATIVE_RESOURCE_HOME + "/" + libName; + try (InputStream is = JniLibLoader.class.getResourceAsStream(resource)) { + Files.copy(is, tempFile.toPath(), StandardCopyOption.REPLACE_EXISTING); + } catch (IOException e) { + try { + tempFile.delete(); + } catch (Exception e0) { + logger.debug("delete temp file error, e: ", e0); + } + logger.error("copy dynamic lib from jar failed, resource: {}, e: ", resource, e); + throw e; + } catch (NullPointerException e) { + throw new FileNotFoundException("Cannot found " + resource + " inside the JAR."); + } + + try { + loadLibrary(tempFile.getAbsolutePath(), true); + } catch (Exception e) { + logger.error("loadLibrary error, resource: {}, e: ", resource, e); + throw e; + } finally { + try { + tempFile.delete(); + tempDir.delete(); + logger.debug("remove temp dir and temp file, dir: {}, file: {}", tempDir, tempFile); + } catch (Exception ignored) { + } + } + } + + public static void loadWinDepsLibraryFromJar() throws IOException, NoSuchFieldException { + File tempDir = new File(WORKDIR, String.valueOf(System.nanoTime())); + tempDir.mkdirs(); + + try (InputStream is = + JniLibLoader.class.getResourceAsStream(NATIVE_WIN_DEPS_DIR + WIN_DEPS_FILE_LIST)) { + if (is == null) { + throw new FileNotFoundException( + "Cannot found " + WIN_DEPS_FILE_LIST + " inside the JAR."); + } + try (Scanner scanner = new Scanner(is)) { + while (scanner.hasNext()) { + String lib = scanner.next(); + File targetFile = new File(tempDir, lib); + logger.info( + "loadWinDepsLibraryFromJar tempDir: {}, targetFile: {}", + tempDir, + targetFile); + try (InputStream fis = + JniLibLoader.class.getResourceAsStream(NATIVE_WIN_DEPS_DIR + lib)) { + if (fis == null) { + throw new FileNotFoundException( + "Cannot found " + lib + " inside the JAR."); + } + Files.copy(fis, targetFile.toPath(), StandardCopyOption.REPLACE_EXISTING); + loadLibrary(targetFile.getAbsolutePath(), true); + } catch (IOException e) { + targetFile.delete(); + } catch (Exception e) { + logger.error( + "loadLibrary error, resource: {}, e: ", + targetFile.getAbsolutePath(), + e); + throw e; + } finally { + try { + targetFile.delete(); + tempDir.delete(); + logger.debug("remove temp dir and temp file, {}", targetFile); + } catch (Exception ignored) { + } + } + } + } + } + } +} diff --git a/cpp/wedpr-crypto/sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/common/Utilities.java b/cpp/wedpr-crypto/sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/common/Utilities.java new file mode 100644 index 00000000..75ef1695 --- /dev/null +++ b/cpp/wedpr-crypto/sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/common/Utilities.java @@ -0,0 +1,28 @@ +/** + * Copyright 2023 [wedpr] + * + *

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. + */ +package com.webank.wedpr.sdk.jni.common; + +public class Utilities { + private static final char[] HEX_ARRAY = "0123456789ABCDEF".toCharArray(); + + public static String bytesToHex(byte[] bytes) { + char[] hexChars = new char[bytes.length * 2]; + for (int j = 0; j < bytes.length; j++) { + int v = bytes[j] & 0xFF; + hexChars[j * 2] = HEX_ARRAY[v >>> 4]; + hexChars[j * 2 + 1] = HEX_ARRAY[v & 0x0F]; + } + return new String(hexChars); + } +} diff --git a/cpp/wedpr-crypto/sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/crypto/FastOre.java b/cpp/wedpr-crypto/sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/crypto/FastOre.java new file mode 100644 index 00000000..72bb9239 --- /dev/null +++ b/cpp/wedpr-crypto/sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/crypto/FastOre.java @@ -0,0 +1,51 @@ +/** + * Copyright 2023 [wedpr] + * + *

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. + */ +package com.webank.wedpr.sdk.jni.crypto; + +import com.webank.wedpr.sdk.jni.common.JniException; +import com.webank.wedpr.sdk.jni.common.JniLibLoader; + +public class FastOre { + static { + JniLibLoader.loadJniLibrary(); + } + + public static native int keyBytes() throws JniException; + + public static native long cipherSize(long plainDataSize, boolean hex) throws JniException; + + public static native long plainSize(long cipherDataSize, boolean hex) throws JniException; + + public static native byte[] generateKey() throws JniException; + + public static native byte[] encrypt4String(byte[] sk, byte[] plainData, boolean hexEncode) + throws JniException; + + public static native byte[] decrypt4String(byte[] sk, byte[] cipherData, boolean hexEncode) + throws JniException; + + public static native byte[] encrypt4Integer(byte[] sk, long plain, boolean hexEncode) + throws JniException; + + public static native long decrypt4Integer(byte[] sk, byte[] cipherData, boolean hexEncode) + throws JniException; + + public static native byte[] encrypt4Float(byte[] sk, byte[] plainData, boolean hexEncode) + throws JniException; + + public static native byte[] decrypt4Float(byte[] sk, byte[] cipherData, boolean hexEncode) + throws JniException; + + public static native int compare(byte[] cipher1, byte[] cipher2) throws JniException; +} diff --git a/cpp/wedpr-crypto/sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/crypto/SymmetricEncryption.java b/cpp/wedpr-crypto/sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/crypto/SymmetricEncryption.java new file mode 100644 index 00000000..614a7bfb --- /dev/null +++ b/cpp/wedpr-crypto/sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/crypto/SymmetricEncryption.java @@ -0,0 +1,49 @@ +/** + * Copyright 2023 [wedpr] + * + *

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. + */ +package com.webank.wedpr.sdk.jni.crypto; + +import com.webank.wedpr.sdk.jni.common.JniException; +import com.webank.wedpr.sdk.jni.common.JniLibLoader; + +public class SymmetricEncryption { + static { + JniLibLoader.loadJniLibrary(); + } + + public enum AlgorithmType { + AES_128, + AES_192, + AES_256, + TrippleDES, + SM4 + } + + public enum OperationMode { + ECB, + CBC, + CFB, + OFB, + CTR + } + + public static native int keyBytes(int algorithmType, int mode) throws JniException; + + public static native byte[] generateKey(int algorithmType, int mode) throws JniException; + + public static native byte[] encrypt( + int algorithmType, int mode, byte[] sk, byte[] iv, byte[] plain) throws JniException; + + public static native byte[] decrypt( + int algorithmType, int mode, byte[] sk, byte[] iv, byte[] cipher) throws JniException; +} diff --git a/cpp/wedpr-crypto/sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/homo/NativeFloatingIhc.java b/cpp/wedpr-crypto/sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/homo/NativeFloatingIhc.java new file mode 100644 index 00000000..c6f5c9c3 --- /dev/null +++ b/cpp/wedpr-crypto/sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/homo/NativeFloatingIhc.java @@ -0,0 +1,31 @@ +package com.webank.wedpr.sdk.jni.homo; + +import com.webank.wedpr.sdk.jni.codec.FloatingPointNumber; +import com.webank.wedpr.sdk.jni.common.JniException; +import com.webank.wedpr.sdk.jni.common.JniLibLoader; + +public class NativeFloatingIhc { + public enum mode { + IHC_128, + IHC_256 + } + + static { + JniLibLoader.loadJniLibrary(); + } + + public static native byte[] generateKey(int mode) throws JniException; + + public static native byte[] encrypt(int mode, byte[] key, byte[] significant, int exponent) + throws JniException; + + public static native FloatingPointNumber decrypt(int mode, byte[] key, byte[] cipher) + throws JniException; + + public static native byte[] add(int mode, byte[] cipher1, byte[] cipher2) throws JniException; + + public static native byte[] sub(int mode, byte[] cipher1, byte[] cipher2) throws JniException; + + public static native byte[] scalaMul(int mode, byte[] significant, int exponent, byte[] cipher) + throws JniException; +} diff --git a/cpp/wedpr-crypto/sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/homo/NativeFloatingPointPaillier.java b/cpp/wedpr-crypto/sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/homo/NativeFloatingPointPaillier.java new file mode 100644 index 00000000..4b002980 --- /dev/null +++ b/cpp/wedpr-crypto/sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/homo/NativeFloatingPointPaillier.java @@ -0,0 +1,60 @@ +/** + * Copyright 2023 [wedpr] + * + *

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. + */ +package com.webank.wedpr.sdk.jni.homo; + +import com.webank.wedpr.sdk.jni.codec.FloatingPointNumber; +import com.webank.wedpr.sdk.jni.common.JniException; +import com.webank.wedpr.sdk.jni.common.JniLibLoader; + +public class NativeFloatingPointPaillier { + static { + JniLibLoader.loadJniLibrary(); + } + + public static native int maxCipherBytes(int keyBits) throws JniException; + + public static native byte[] encryptFast(byte[] significant, int exponent, long keyPair) + throws JniException; + + public static native byte[] encryptFastWithoutPrecompute( + byte[] significant, int exponent, byte[] sk, byte[] pk) throws JniException; + + public static native byte[] encrypt(byte[] significant, int exponent, long publicKey) + throws JniException; + + public static native byte[] encryptWithoutPrecompute( + byte[] significant, int exponent, byte[] pk) throws JniException; + + public static native FloatingPointNumber decrypt(byte[] cipher, long keyPair) + throws JniException; + + public static native FloatingPointNumber decryptWithoutPrecompute( + byte[] cipher, byte[] sk, byte[] pk) throws JniException; + + public static native byte[] add(byte[] c1, byte[] c2, long publicKey) throws JniException; + + public static native byte[] addWithoutPrecompute(byte[] c1, byte[] c2, byte[] pk) + throws JniException; + + public static native byte[] sub(byte[] c1, byte[] c2, long publicKey) throws JniException; + + public static native byte[] subWithoutPrecompute(byte[] c1, byte[] c2, byte[] pkBytes) + throws JniException; + + public static native byte[] scalaMul( + byte[] significant, int exponent, byte[] cipher, long publicKey) throws JniException; + + public static native byte[] scalaMulWithoutPrecompute( + byte[] significant, int exponent, byte[] cipher, byte[] pkBytes) throws JniException; +} diff --git a/cpp/wedpr-crypto/sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/homo/NativePaillier.java b/cpp/wedpr-crypto/sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/homo/NativePaillier.java new file mode 100644 index 00000000..25877e6e --- /dev/null +++ b/cpp/wedpr-crypto/sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/homo/NativePaillier.java @@ -0,0 +1,241 @@ +/** + * Copyright 2023 [wedpr] + * + *

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. + */ +package com.webank.wedpr.sdk.jni.homo; + +import com.webank.wedpr.sdk.jni.common.JniException; +import com.webank.wedpr.sdk.jni.common.JniLibLoader; + +public class NativePaillier { + static { + JniLibLoader.loadJniLibrary(); + } + + /** + * get the max length of the public key with given keyBits + * + * @param keyBits the keyBits, e.g. 1024/2048 + * @return the max length of the public key + * @throws JniException + */ + public static native int maxPublicKeyBytes(int keyBits) throws JniException; + + /** + * get the max length of the private key with given keyBits + * + * @param keyBits the keyBits, e.g. 1024/2048 + * @return the max length of the private key + * @throws JniException + */ + public static native int maxPrivateKeyBytes(int keyBits) throws JniException; + + /** + * get the max length of the cipher with given keyBits + * + * @param keyBits the keyBits, e.g. 1024/2048 + * @return the max length of the cipher + * @throws JniException + */ + public static native int maxCipherBytes(int keyBits) throws JniException; + + /** + * get the keyBits according to the given keyPair + * + * @param keyPair + * @return + * @throws JniException + */ + public static native int keyBitsFromKeyPair(long keyPair) throws JniException; + + /** + * get the keyBits according to the given public key + * + * @param publicKey + * @return + * @throws JniException + */ + public static native int keyBitsFromPublicKey(long publicKey) throws JniException; + + /** + * generate the paillier KeyPair + * + * @param keyBits the keyLength + * @return pointer to the generated paillier key-pair + * @throws JniException + */ + public static native long generateKeyPair(int keyBits) throws JniException; + + /** + * load the encoded privateKey and publicKey into key-pair object + * + * @param privateKeyBytes the encoded privateKey + * @param publicKeyBytes the encoded publicKey + * @return + * @throws JniException + */ + public static native long loadKeyPair(byte[] privateKeyBytes, byte[] publicKeyBytes) + throws JniException; + + /** + * free the allocated keypair + * + * @param keyPairPointer + * @return + */ + public static native void freeKeyPair(long keyPairPointer) throws JniException; + + /** + * load the publicKey object from the encoded publicKey + * + * @param publicKeyBytes the encoded publicKey + * @return the pointer to the publicKey object + * @throws JniException + */ + public static native long loadPublicKey(byte[] publicKeyBytes) throws JniException; + + /** + * free the public key object + * + * @param publicKey + * @throws JniException + */ + public static native void freePublicKey(long publicKey) throws JniException; + + /** + * load the private key object from the encoded privateKey + * + * @param privateKeyBytes + * @return + * @throws JniException + */ + public static native long loadPrivateKey(byte[] privateKeyBytes) throws JniException; + + /** + * free the private key object + * + * @param privateKey + * @throws JniException + */ + public static native void freePrivateKey(long privateKey) throws JniException; + + /** + * get the public key jni object according to the keypair + * + * @param keypair the keypair jni object + * @return the public key jni object + * @throws JniException + */ + public static native long getPublicKeyJniObject(long keypair) throws JniException; + + /** + * get the encoded publicKey from given keyPair object + * + * @param keyPair the pointer to the keyPair object + * @return + * @throws JniException + */ + public static native byte[] getPublicKeyBytesFromKeyPair(long keyPair) throws JniException; + + /** + * get the encoded privateKey from the given keyPair object + * + * @param keyPair the pointer to the keyPair object + * @return + * @throws JniException + */ + public static native byte[] getPrivateKeyBytesFromKeyPair(long keyPair) throws JniException; + + /** + * encrypt the value into paillier cipher using given keyPair(using CRT optimization) + * + * @param value the value to be encrypted + * @param keyPair the keyPair used to encrypt + * @return the cipher + * @throws JniException + */ + public static native byte[] encryptFast(byte[] value, long keyPair) throws JniException; + + public static native byte[] encryptFastWithoutPrecompute( + byte[] value, byte[] privateKey, byte[] publicKey) throws JniException; + + /** + * encrypt the value into paillier cipher using given keyPair(without CRT optimization) + * + * @param value the value to be encrypted + * @param publicKey the publicKey used to encrypt + * @return the cipher + * @throws JniException + */ + public static native byte[] encrypt(byte[] value, long publicKey) throws JniException; + + public static native byte[] encryptWithoutPrecompute(byte[] value, byte[] publicKey) + throws JniException; + + /** + * decrypt the cipher using given keyPair + * + * @param cipher the cipher to be decrypted + * @param keyPair the keyPair used to decrypt + * @return the decrypted result + * @throws JniException + */ + public static native byte[] decrypt(byte[] cipher, long keyPair) throws JniException; + + public static native byte[] decryptWithoutPrecompute(byte[] cipher, byte[] sk, byte[] pk) + throws JniException; + + /** + * ciphertext space addition, namely: cipher1 + cipher2 + * + * @param cipher1 + * @param cipher2 + * @param publicKey + * @return the addition result + * @throws JniException + */ + public static native byte[] add(byte[] cipher1, byte[] cipher2, long publicKey) + throws JniException; + + public static native byte[] addWithoutPrecompute(byte[] cipher1, byte[] cipher2, byte[] pk) + throws JniException; + + /** + * ciphertext space subtraction, namely: cipher1 - cipher2 + * + * @param cipher1 + * @param cipher2 + * @param publicKey + * @return the subtraction result + * @throws JniException + */ + public static native byte[] sub(byte[] cipher1, byte[] cipher2, long publicKey) + throws JniException; + + public static native byte[] subWithoutPrecompute(byte[] cipher1, byte[] cipher2, byte[] pk) + throws JniException; + + /** + * ciphertext space scala-multiply, namely: v * cipher + * + * @param v the scala-number + * @param cipher + * @param publicKey + * @return the scala-multiply result + * @throws JniException + */ + public static native byte[] scalaMul(byte[] v, byte[] cipher, long publicKey) + throws JniException; + + public static native byte[] scalaMulWithoutPrecompute(byte[] v, byte[] cipher, byte[] pk) + throws JniException; +} diff --git a/cpp/wedpr-crypto/sdk/bindings/java/src/main/resources/META-INF/native/win/file.list b/cpp/wedpr-crypto/sdk/bindings/java/src/main/resources/META-INF/native/win/file.list new file mode 100644 index 00000000..2fe00a0f --- /dev/null +++ b/cpp/wedpr-crypto/sdk/bindings/java/src/main/resources/META-INF/native/win/file.list @@ -0,0 +1,7 @@ +api-ms-win-crt-heap-l1-1-0.dll +api-ms-win-crt-stdio-l1-1-0.dll +api-ms-win-crt-utility-l1-1-0.dll +api-ms-win-crt-environment-l1-1-0.dll +api-ms-win-crt-filesystem-l1-1-0.dll +api-ms-win-crt-convert-l1-1-0.dll +vcruntime140_1.dll \ No newline at end of file diff --git a/cpp/wedpr-crypto/sdk/bindings/java/src/test/java/com/webank/wedpr/sdk/jni/test/NativeFloatingIhcTest.java b/cpp/wedpr-crypto/sdk/bindings/java/src/test/java/com/webank/wedpr/sdk/jni/test/NativeFloatingIhcTest.java new file mode 100644 index 00000000..272fb1d0 --- /dev/null +++ b/cpp/wedpr-crypto/sdk/bindings/java/src/test/java/com/webank/wedpr/sdk/jni/test/NativeFloatingIhcTest.java @@ -0,0 +1,86 @@ +/** + * Copyright 2023 [wedpr] + * + *

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. + */ +package com.webank.wedpr.sdk.jni.test; + +import com.webank.wedpr.sdk.jni.codec.NumberCodec; +import com.webank.wedpr.sdk.jni.codec.NumberCodecException; +import com.webank.wedpr.sdk.jni.codec.NumberCodecImpl; +import com.webank.wedpr.sdk.jni.common.JniException; +import com.webank.wedpr.sdk.jni.homo.NativeFloatingIhc; +import org.junit.Assert; +import org.junit.Test; +import com.webank.wedpr.sdk.jni.codec.FloatingPointNumber; + + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.Arrays; + +public class NativeFloatingIhcTest +{ + private void testFloatingIhcBigDecimalCase(int mode, BigDecimal m1, BigDecimal m2, BigDecimal v) throws JniException, NumberCodecException { + NativeFloatingIhc ihc = new NativeFloatingIhc(); + // generate key + byte[] key = ihc.generateKey(mode); + NumberCodec codec = new NumberCodecImpl(); + FloatingPointNumber fp1 = codec.encode(m1); + FloatingPointNumber fp2 = codec.encode(m2); + FloatingPointNumber fv = codec.encode(v); + // encrypt + byte[] c1 = ihc.encrypt(mode, key, fp1.getSignificantBytes(),fp1.getExponent()); + // decrypt + FloatingPointNumber resultValue = ihc.decrypt(mode, key, c1); + System.out.println("###### resultValue: " + resultValue.getSignificant()); + System.out.println("###### resultValue exp: " + resultValue.getExponent()); + Assert.assertTrue(codec.decodeBigDecimal(resultValue).equals(m1)); + // encrypt c2 + byte[] c2 = ihc.encrypt(mode, key, fp2.getSignificantBytes(),fp2.getExponent()); + + /////// c1 + c2 + byte[] addResult = ihc.add(mode, c1, c2); + // decrypt and check + resultValue = ihc.decrypt(mode, key, addResult); + BigDecimal expectedAddResult = m1.add(m2); + Assert.assertTrue(expectedAddResult.equals(codec.decodeBigDecimal(resultValue))); + + /////// c1 - c2 + byte[] subResult = ihc.sub(mode, c1, c2); + // decrypt and check + resultValue = ihc.decrypt(mode, key, subResult); + BigDecimal expectedSubResult = m1.subtract(m2); + Assert.assertTrue(expectedSubResult.equals(codec.decodeBigDecimal(resultValue))); + + //// v * c1 + byte[] mulResult = ihc.scalaMul(mode, fv.getSignificantBytes(), fv.getExponent(), c1); + // decrypt and check + resultValue = ihc.decrypt(mode, key, mulResult); + BigDecimal expectedMulResult = v.multiply(m1); + System.out.println("###### "); + Assert.assertTrue(expectedMulResult.equals(codec.decodeBigDecimal(resultValue))); + + // invalid case + String invalidCipher = "invalidCipher"; + Assert.assertThrows(JniException.class, ()->ihc.decrypt(mode, key, invalidCipher.getBytes())); + } + +@Test +public void testFloatingIhc() throws JniException, NumberCodecException { + System.out.println("##### testFloatingIhc: "); + + BigDecimal m1 = BigDecimal.valueOf(234324.02343243423432434); + BigDecimal m2 = BigDecimal.valueOf(-324234.0000123423432); + BigDecimal v = BigDecimal.valueOf(-1232.000000234); + testFloatingIhcBigDecimalCase(NativeFloatingIhc.mode.IHC_128.ordinal(), m1, m2, v); +} +} \ No newline at end of file diff --git a/cpp/wedpr-crypto/sdk/bindings/java/src/test/java/com/webank/wedpr/sdk/jni/test/NativeFloatingPointPaillierTest.java b/cpp/wedpr-crypto/sdk/bindings/java/src/test/java/com/webank/wedpr/sdk/jni/test/NativeFloatingPointPaillierTest.java new file mode 100644 index 00000000..08ef13de --- /dev/null +++ b/cpp/wedpr-crypto/sdk/bindings/java/src/test/java/com/webank/wedpr/sdk/jni/test/NativeFloatingPointPaillierTest.java @@ -0,0 +1,237 @@ +/** + * Copyright 2023 [wedpr] + * + *

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. + */ +package com.webank.wedpr.sdk.jni.test; + +import com.webank.wedpr.sdk.jni.codec.FloatingPointNumber; +import com.webank.wedpr.sdk.jni.codec.NumberCodec; +import com.webank.wedpr.sdk.jni.codec.NumberCodecException; +import com.webank.wedpr.sdk.jni.codec.NumberCodecImpl; +import com.webank.wedpr.sdk.jni.common.JniException; +import com.webank.wedpr.sdk.jni.homo.NativeFloatingPointPaillier; +import com.webank.wedpr.sdk.jni.homo.NativePaillier; +import org.junit.Assert; +import org.junit.Test; + +import java.math.BigDecimal; +import java.math.BigInteger; + +public class NativeFloatingPointPaillierTest +{ + private NumberCodec codec = new NumberCodecImpl(); + private void intCase(BigInteger m1, BigInteger m2, BigInteger v, long keypair, long publicKey) throws NumberCodecException, JniException { + // encrypt + FloatingPointNumber m1Fp = codec.encode(m1); + byte[] c1 = NativeFloatingPointPaillier.encrypt(m1Fp.getSignificantBytes(), m1Fp.getExponent(), publicKey); + byte[] pkBytes = NativePaillier.getPublicKeyBytesFromKeyPair(keypair); + byte[] skBytes = NativePaillier.getPrivateKeyBytesFromKeyPair(keypair); + byte[] tmp = NativeFloatingPointPaillier.encryptWithoutPrecompute(m1Fp.getSignificantBytes(), m1Fp.getExponent(), pkBytes); + + FloatingPointNumber m2Fp = codec.encode(m2); + byte[] c2 = NativeFloatingPointPaillier.encryptFast(m2Fp.getSignificantBytes(), m2Fp.getExponent(), keypair); + // decrypt and check + FloatingPointNumber decryptedC1 = NativeFloatingPointPaillier.decrypt(c1, keypair); + FloatingPointNumber tmpResult = NativeFloatingPointPaillier.decryptWithoutPrecompute(tmp, skBytes, pkBytes); + Assert.assertTrue(codec.decodeBigInteger(decryptedC1).compareTo(m1) == 0); + Assert.assertTrue(codec.decodeBigInteger(tmpResult).compareTo(m1) == 0); + + FloatingPointNumber decryptedC2 = NativeFloatingPointPaillier.decrypt(c2, keypair); + Assert.assertTrue(codec.decodeBigInteger(decryptedC2).compareTo(m2) == 0); + + // add + byte[] addCipher = NativeFloatingPointPaillier.add(c1, c2, publicKey); + tmp = NativeFloatingPointPaillier.addWithoutPrecompute(c1, c2, pkBytes); + FloatingPointNumber addResult = NativeFloatingPointPaillier.decrypt(addCipher, keypair); + tmpResult = NativeFloatingPointPaillier.decryptWithoutPrecompute(tmp, skBytes, pkBytes); + + BigInteger expectedAddResult = m1.add(m2); + Assert.assertTrue(codec.decodeBigInteger(addResult).compareTo(expectedAddResult) == 0); + Assert.assertTrue(codec.decodeBigInteger(tmpResult).compareTo(expectedAddResult) == 0); + + // sub + byte[] subCipher = NativeFloatingPointPaillier.sub(c1, c2, publicKey); + tmp = NativeFloatingPointPaillier.subWithoutPrecompute(c1, c2, pkBytes); + FloatingPointNumber subResult = NativeFloatingPointPaillier.decrypt(subCipher, keypair); + tmpResult = NativeFloatingPointPaillier.decryptWithoutPrecompute(subCipher, skBytes, pkBytes); + BigInteger expectedSubResult = m1.subtract(m2); + Assert.assertTrue(codec.decodeBigInteger(subResult).compareTo(expectedSubResult) == 0); + Assert.assertTrue(codec.decodeBigInteger(tmpResult).compareTo(expectedSubResult) == 0); + + // scalaMul + FloatingPointNumber vFp = codec.encode(v); + byte[] mulCipher = NativeFloatingPointPaillier.scalaMul(vFp.getSignificantBytes(), vFp.getExponent(), c1, publicKey); + tmp = NativeFloatingPointPaillier.scalaMulWithoutPrecompute(vFp.getSignificantBytes(), vFp.getExponent(), c1, pkBytes); + FloatingPointNumber mulResult = NativeFloatingPointPaillier.decrypt(mulCipher, keypair); + tmpResult = NativeFloatingPointPaillier.decryptWithoutPrecompute(mulCipher, skBytes, pkBytes); + BigInteger expectedMulResult = v.multiply(m1); + Assert.assertTrue(codec.decodeBigInteger(mulResult).compareTo(expectedMulResult) == 0); + Assert.assertTrue(codec.decodeBigInteger(tmpResult).compareTo(expectedMulResult) == 0); + } + + private void doubleCase(double m1, double m2, double v, long keypair, long publicKey) throws NumberCodecException, JniException { + // encrypt + FloatingPointNumber m1Fp = codec.encode(m1); + System.out.println("#### m1Fp: " + m1Fp.toString()); + byte[] c1 = NativeFloatingPointPaillier.encrypt(m1Fp.getSignificantBytes(), m1Fp.getExponent(), publicKey); + + FloatingPointNumber m2Fp = codec.encode(m2); + System.out.println("#### m2Fp: " + m2Fp.toString()); + byte[] c2 = NativeFloatingPointPaillier.encryptFast(m2Fp.getSignificantBytes(), m2Fp.getExponent(), keypair); + // decrypt and check + FloatingPointNumber decryptedC1 = NativeFloatingPointPaillier.decrypt(c1, keypair); + Assert.assertTrue(Double.compare(codec.decodeDouble(decryptedC1), m1) == 0); + + FloatingPointNumber decryptedC2 = NativeFloatingPointPaillier.decrypt(c2, keypair); + System.out.println("#### m2: " + m2); + System.out.println("#### decryptedC2: " + codec.decodeDouble(decryptedC2)); + Assert.assertTrue(Double.compare(codec.decodeDouble(decryptedC2), m2) == 0); + + // add + byte[] addCipher = NativeFloatingPointPaillier.add(c1, c2, publicKey); + FloatingPointNumber addResult = NativeFloatingPointPaillier.decrypt(addCipher, keypair); + BigDecimal expectedAddResult = BigDecimal.valueOf(m1).add(BigDecimal.valueOf(m2)); + System.out.println("#### addResult: " + addResult.toString()); + System.out.println("#### expectedAddResult: " + expectedAddResult); + System.out.println("m1: " + m1); + System.out.println("m2: " + m2); + Assert.assertTrue(expectedAddResult.compareTo(BigDecimal.valueOf(codec.decodeDouble(addResult))) == 0); + + // sub + byte[] subCipher = NativeFloatingPointPaillier.sub(c1, c2, publicKey); + FloatingPointNumber subResult = NativeFloatingPointPaillier.decrypt(subCipher, keypair); + BigDecimal expectedSubResult = BigDecimal.valueOf(m1).subtract(BigDecimal.valueOf(m2)); + Assert.assertTrue(expectedSubResult.compareTo(BigDecimal.valueOf(codec.decodeDouble(subResult))) == 0); + + // scalaMul + FloatingPointNumber vFp = codec.encode(v); + byte[] mulCipher = NativeFloatingPointPaillier.scalaMul(vFp.getSignificantBytes(), vFp.getExponent(), c1, publicKey); + FloatingPointNumber mulResult = NativeFloatingPointPaillier.decrypt(mulCipher, keypair); + BigDecimal expectedMulResult = BigDecimal.valueOf(v).multiply(BigDecimal.valueOf(m1)); + // Note: BigDecimal not loss the precision + Assert.assertTrue(expectedMulResult.compareTo(codec.decodeBigDecimal(mulResult)) == 0); + } + + private void decimalCase(BigDecimal m1, BigDecimal m2, BigDecimal v, long keypair, long publicKey) throws NumberCodecException, JniException { + // encrypt + FloatingPointNumber m1Fp = codec.encode(m1); + byte[] c1 = NativeFloatingPointPaillier.encrypt(m1Fp.getSignificantBytes(), m1Fp.getExponent(), publicKey); + + FloatingPointNumber m2Fp = codec.encode(m2); + byte[] c2 = NativeFloatingPointPaillier.encryptFast(m2Fp.getSignificantBytes(), m2Fp.getExponent(), keypair); + // decrypt and check + FloatingPointNumber decryptedC1 = NativeFloatingPointPaillier.decrypt(c1, keypair); + Assert.assertTrue(codec.decodeBigDecimal(decryptedC1).compareTo(m1) == 0); + + FloatingPointNumber decryptedC2 = NativeFloatingPointPaillier.decrypt(c2, keypair); + Assert.assertTrue(codec.decodeBigDecimal(decryptedC2).compareTo(m2) == 0); + + // add + byte[] addCipher = NativeFloatingPointPaillier.add(c1, c2, publicKey); + FloatingPointNumber addResult = NativeFloatingPointPaillier.decrypt(addCipher, keypair); + BigDecimal expectedAddResult = m1.add(m2); + Assert.assertTrue(codec.decodeBigDecimal(addResult).compareTo(expectedAddResult) == 0); + + // sub + byte[] subCipher = NativeFloatingPointPaillier.sub(c1, c2, publicKey); + FloatingPointNumber subResult = NativeFloatingPointPaillier.decrypt(subCipher, keypair); + BigDecimal expectedSubResult = m1.subtract(m2); + Assert.assertTrue(codec.decodeBigDecimal(subResult).compareTo(expectedSubResult) == 0); + + // scalaMul + FloatingPointNumber vFp = codec.encode(v); + byte[] mulCipher = NativeFloatingPointPaillier.scalaMul(vFp.getSignificantBytes(), vFp.getExponent(), c1, publicKey); + FloatingPointNumber mulResult = NativeFloatingPointPaillier.decrypt(mulCipher, keypair); + BigDecimal expectedMulResult = v.multiply(m1); + Assert.assertTrue(codec.decodeBigDecimal(mulResult).compareTo(expectedMulResult) == 0); + } + + @Test + public void testIntCase() throws JniException, NumberCodecException { + /// the int case + BigInteger m1 = BigInteger.valueOf(234234234); + BigInteger m2 = BigInteger.valueOf(456566423); + BigInteger v = BigInteger.valueOf(123); + int keyBits = 2048; + long keypair = NativePaillier.generateKeyPair(keyBits); + long publicKey = NativePaillier.getPublicKeyJniObject(keypair); + + // the positive case + intCase(m1, m2, v, keypair, publicKey); + // the negative case + m2 = BigInteger.valueOf(-456566423); + intCase(m1, m2, v, keypair, publicKey); + m1 = BigInteger.valueOf(-234234234); + intCase(m1, m2, v, keypair,publicKey); + + // zero caase + m1 = BigInteger.valueOf(0); + m2 = BigInteger.valueOf(0); + intCase(m1, m2, v, keypair,publicKey); + } + + @Test + public void testDoubleCase() throws JniException, NumberCodecException { + int keyBits = 2048; + long keypair = NativePaillier.generateKeyPair(keyBits); + long publicKey = NativePaillier.getPublicKeyJniObject(keypair); + + /// positive case + double m1 = 45646.00; + double m2 = 0.454354; + double v = 2.00; + doubleCase(m1, m2, v, keypair, publicKey); + + // negative case + m1 = -234324.0234324; + m2 = -0.34543; + v = -23432.001; + doubleCase(m1, m2, v, keypair, publicKey); + + // zero case + //m1 = 0.000; + m2 = 0.00; + doubleCase(m1, m2, v, keypair, publicKey); + } + + @Test + public void testBigDecimalCase() throws JniException, NumberCodecException { + int keyBits = 2048; + long keypair = NativePaillier.generateKeyPair(keyBits); + long publicKey = NativePaillier.getPublicKeyJniObject(keypair); + + BigDecimal m1 = BigDecimal.valueOf(12321231.2342343); + BigDecimal m2 = BigDecimal.valueOf(0.0023434); + BigDecimal v = BigDecimal.valueOf(123.3); + decimalCase(m1, m2, v, keypair, publicKey); + m1 = new BigDecimal("2343243223423423423423.798034320080"); + m2 = new BigDecimal("956456547424236462412342345.0023423"); + decimalCase(m1, m2, v, keypair, publicKey); + + // the negative case + m1 = BigDecimal.valueOf(234324.023432434); + m2 = BigDecimal.valueOf(-324234.00001); + v = BigDecimal.valueOf(-1232.00); + decimalCase(m1, m2, v, keypair, publicKey); + v = BigDecimal.valueOf(0.23434); + m1 = BigDecimal.valueOf(-43543.000); + decimalCase(m1, m2, v, keypair, publicKey); + m2 = BigDecimal.valueOf(-2343.00); + decimalCase(m1, m2, v, keypair, publicKey); + + // zero case + m1 = BigDecimal.valueOf(0); + m2 = BigDecimal.valueOf(0); + decimalCase(m1, m2, v, keypair, publicKey); + } + +} \ No newline at end of file diff --git a/cpp/wedpr-crypto/sdk/bindings/java/src/test/java/com/webank/wedpr/sdk/jni/test/NativePaillierTest.java b/cpp/wedpr-crypto/sdk/bindings/java/src/test/java/com/webank/wedpr/sdk/jni/test/NativePaillierTest.java new file mode 100644 index 00000000..08248877 --- /dev/null +++ b/cpp/wedpr-crypto/sdk/bindings/java/src/test/java/com/webank/wedpr/sdk/jni/test/NativePaillierTest.java @@ -0,0 +1,144 @@ +/** + * Copyright 2023 [wedpr] + * + *

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. + */ +package com.webank.wedpr.sdk.jni.test; + +import com.webank.wedpr.sdk.jni.common.JniException; +import com.webank.wedpr.sdk.jni.common.Utilities; +import com.webank.wedpr.sdk.jni.homo.NativePaillier; +import org.junit.Assert; +import org.junit.Test; + +import java.math.BigInteger; +import java.util.Arrays; + +public class NativePaillierTest +{ + private void testPaillierImpl(int keyBits, BigInteger m1, BigInteger m2, BigInteger v) throws JniException { + NativePaillier paillier = new NativePaillier(); + // generate keypair + long keyPair = paillier.generateKeyPair(keyBits); + // get the public key from keyPair + byte[] pk = paillier.getPublicKeyBytesFromKeyPair(keyPair); + byte[] sk = paillier.getPrivateKeyBytesFromKeyPair(keyPair); + System.out.println("#### pk: " + Utilities.bytesToHex(pk)); + System.out.println("##### sk: " + Utilities.bytesToHex(sk)); + + // load the public key + long keyPair2 = paillier.loadKeyPair(sk, pk); + + // encrypt + byte[] m1Bytes = m1.toByteArray(); + System.out.println("###### m1: " + Arrays.toString(m1Bytes)); + byte[] c1 = paillier.encryptFast(m1Bytes, keyPair); + // encryptFastWithoutPrecompute + byte[] tmp = paillier.encryptFastWithoutPrecompute(m1Bytes, sk, pk); + byte[] tmpResult = paillier.decryptWithoutPrecompute(tmp, sk, pk); + + // decrypt + byte[] resultValue = paillier.decrypt(c1, keyPair); + BigInteger resultV = new BigInteger(resultValue); + Assert.assertTrue(Arrays.equals(tmpResult, resultValue)); + tmpResult = paillier.decryptWithoutPrecompute(c1, sk, pk); + Assert.assertTrue(Arrays.equals(tmpResult, resultValue)); + + System.out.println("#### resultValue len: " + resultValue.length + ", resultValue: " + Arrays.toString(resultValue)); + System.out.println("### resultValue: " + resultV); + System.out.println("#### m1: " + m1); + + + byte[] c2 = paillier.encryptFast(m2.toByteArray(), keyPair2); + System.out.println("#### c1 len: " + c1.length + ", array: " + Arrays.toString(c1)); + System.out.println("#### c2 len: " + c2.length + ", array: " + Arrays.toString(c2)); + + /////// c1 + c2 + long pkObj = paillier.loadPublicKey(pk); + long pkObj2 = paillier.getPublicKeyJniObject(keyPair); + + byte[] result = paillier.add(c1, c2, pkObj); + tmp = paillier.addWithoutPrecompute(c1, c2, pk); + System.out.println("#### result len: " + result.length + ", result: " + Arrays.toString(result)); + // decrypt and check + resultValue = paillier.decrypt(result, keyPair); + tmpResult = paillier.decryptWithoutPrecompute(tmp, sk, pk); + Assert.assertTrue(Arrays.equals(resultValue, tmpResult)); + System.out.println("#### resultValue len: " + resultValue.length + ", resultValue: " + Arrays.toString(resultValue)); + BigInteger addResult = new BigInteger(resultValue); + BigInteger expectedAddResult = m1.add(m2); + System.out.println("####### m1: " + m1); + System.out.println("####### m2: " + m2); + System.out.println("####### expectedAddResult: " + expectedAddResult.toString()); + System.out.println("####### addResult: " + addResult.toString()); + Assert.assertTrue(expectedAddResult.equals(addResult)); + + /////// c1 - c2 + result = paillier.sub(c1, c2, pkObj2); + tmp = paillier.subWithoutPrecompute(c1, c2, pk); + // decrypt and check + resultValue = paillier.decrypt(result, keyPair); + tmpResult = paillier.decryptWithoutPrecompute(result, sk, pk); + Assert.assertTrue(Arrays.equals(resultValue, tmpResult)); + BigInteger subResult = new BigInteger(resultValue); + BigInteger expectedSubResult = m1.subtract(m2); + Assert.assertTrue(expectedSubResult.equals(subResult)); + + //// v * c1 + result = paillier.scalaMul(v.toByteArray(), c1, pkObj); + tmp = paillier.scalaMulWithoutPrecompute(v.toByteArray(), c1, pk); + // decrypt and check + resultValue = paillier.decrypt(result, keyPair); + tmpResult = paillier.decryptWithoutPrecompute(tmp, sk, pk); + Assert.assertTrue(Arrays.equals(resultValue, tmpResult)); + BigInteger mulResult = new BigInteger(resultValue); + BigInteger expectedMulResult = v.multiply(m1); + Assert.assertTrue(mulResult.equals(expectedMulResult)); + + /// exception case: + try { + c1[1] += 90; + result = paillier.add(c1, c2, pkObj); + resultValue = paillier.decrypt(result, keyPair); + addResult = new BigInteger(resultValue); + Assert.assertFalse(expectedAddResult.equals(addResult)); + }catch(Exception e) + { + System.out.println("#### exception case: " + e.getMessage()); + } + + // call loadPrivateKey + long skObj = paillier.loadPrivateKey(sk); + long skObj2 = paillier.loadPrivateKey(sk); + + NativePaillier.freeKeyPair(keyPair); + NativePaillier.freeKeyPair(keyPair2); + + // Note: pkObj2 is loaded from keypair, it has been released after keypair has been released + NativePaillier.freePublicKey(pkObj); + + NativePaillier.freePrivateKey(skObj); + NativePaillier.freePrivateKey(skObj2); + } + +@Test +public void testPaillier() throws JniException { + // the positive case + BigInteger m1 = BigInteger.valueOf(34234234); + BigInteger m2 = BigInteger.valueOf(23423423); + BigInteger v = BigInteger.valueOf(23423); + testPaillierImpl(2048, m1, m2, v); + + // the negative case + m1 = BigInteger.valueOf(-34234234); + testPaillierImpl(2048, m1, m2, v); +} +} \ No newline at end of file diff --git a/cpp/wedpr-crypto/sdk/bindings/java/src/test/java/com/webank/wedpr/sdk/jni/test/NumberCodecTest.java b/cpp/wedpr-crypto/sdk/bindings/java/src/test/java/com/webank/wedpr/sdk/jni/test/NumberCodecTest.java new file mode 100644 index 00000000..790c6a75 --- /dev/null +++ b/cpp/wedpr-crypto/sdk/bindings/java/src/test/java/com/webank/wedpr/sdk/jni/test/NumberCodecTest.java @@ -0,0 +1,86 @@ +/** + * Copyright 2023 [wedpr] + * + *

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. + */ +package com.webank.wedpr.sdk.jni.test; + +import com.webank.wedpr.sdk.jni.codec.FloatingPointNumber; +import com.webank.wedpr.sdk.jni.codec.NumberCodec; +import com.webank.wedpr.sdk.jni.codec.NumberCodecException; +import com.webank.wedpr.sdk.jni.codec.NumberCodecImpl; +import org.junit.Assert; +import org.junit.Test; + +import java.math.BigDecimal; +import java.math.BigInteger; + +public class NumberCodecTest +{ + private final NumberCodec codec = new NumberCodecImpl(); + + private void checkBigIntegerEncodeDecode(BigInteger value) throws NumberCodecException { + FloatingPointNumber encodedV = codec.encode(value); + BigInteger decodedV = codec.decodeBigInteger(encodedV); + Assert.assertTrue(decodedV.compareTo(value) == 0); + } + + private void checkLongEncodeDecode(long value) throws NumberCodecException { + FloatingPointNumber encodedV = codec.encode(value); + long decodedV = codec.decodeLong(encodedV); + Assert.assertTrue(decodedV == value); + } + + private void checkDoubleEncodeDecode(double value) throws NumberCodecException + { + FloatingPointNumber encodedV = codec.encode(value); + double decodedV = codec.decodeDouble(encodedV); + Assert.assertTrue(Double.compare(value, decodedV) == 0); + } + + private void checkBigDecimalEncodeDecode(BigDecimal value) throws NumberCodecException + { + FloatingPointNumber encodedV = codec.encode(value); + BigDecimal decodedV = codec.decodeBigDecimal(encodedV); + Assert.assertTrue(decodedV.compareTo(value) == 0); + } + + @Test + public void testNumberCodec() throws NumberCodecException { + + //// check BigInteger encode decode + BigInteger value = BigInteger.valueOf(123432432); + checkBigIntegerEncodeDecode(value); + // negative case + value = BigInteger.valueOf(-123432432); + checkBigIntegerEncodeDecode(value); + + /// check long encode/decode + long longV = 234232454; + checkLongEncodeDecode(longV); + /// the negative case + longV = -234232454; + checkLongEncodeDecode(longV); + + /// check double + double doubleV = 11341.234234234; + checkDoubleEncodeDecode(doubleV); + // negative case + doubleV = -1234.234234234; + checkDoubleEncodeDecode(doubleV); + + /// check BigDecimal + BigDecimal decimalV = new BigDecimal("2342343243243.2344235235"); + checkBigDecimalEncodeDecode(decimalV); + decimalV = new BigDecimal("-342343243243.2344235235"); + checkBigDecimalEncodeDecode(decimalV); + } +} \ No newline at end of file diff --git a/cpp/wedpr-crypto/sdk/bindings/java/src/test/java/com/webank/wedpr/sdk/jni/test/SymmetricEncryptionTest.java b/cpp/wedpr-crypto/sdk/bindings/java/src/test/java/com/webank/wedpr/sdk/jni/test/SymmetricEncryptionTest.java new file mode 100644 index 00000000..48c3ae61 --- /dev/null +++ b/cpp/wedpr-crypto/sdk/bindings/java/src/test/java/com/webank/wedpr/sdk/jni/test/SymmetricEncryptionTest.java @@ -0,0 +1,194 @@ +/** + * Copyright 2023 [wedpr] + * + *

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. + */ +package com.webank.wedpr.sdk.jni.test; +import com.webank.wedpr.sdk.jni.codec.NumberCodecException; +import com.webank.wedpr.sdk.jni.codec.NumberCodecImpl; +import com.webank.wedpr.sdk.jni.crypto.FastOre; +import com.webank.wedpr.sdk.jni.crypto.SymmetricEncryption; +import org.junit.Assert; +import org.junit.Test; +import com.webank.wedpr.sdk.jni.common.JniException; + +import java.io.UnsupportedEncodingException; +import java.math.BigDecimal; +import java.nio.charset.StandardCharsets; +import java.util.Arrays; + +public class SymmetricEncryptionTest +{ + private void checkEncDec(int algorithm, int mode, byte[] iv, byte[] plain) throws JniException + { + byte[] key = SymmetricEncryption.generateKey(algorithm, mode); + //System.out.println("key: "); + //String key = "123"; + // encrypt + byte[] cipher = SymmetricEncryption.encrypt(algorithm, mode, key, iv, plain); + byte[] decPlain = SymmetricEncryption.decrypt(algorithm, mode, key, iv, cipher); + // check + System.out.println("plain: " + new String(plain)); + System.out.println("decPlain: " + new String(decPlain)); + Assert.assertTrue(Arrays.toString(plain).equals(Arrays.toString(decPlain))); + } + private void testEncDecCases(int algorithm, int mode, byte[] iv) throws JniException + { + String plain = "231234324234"; + byte[] plainBytes = plain.getBytes(); + System.out.println("#### plainBytes: " + Arrays.toString(plainBytes)); + checkEncDec(algorithm, mode, iv, plain.getBytes()); + plain = "@3423sf12!"; + checkEncDec(algorithm, mode, iv, plain.getBytes()); + plain = "a1b2c3d4e5"; + + checkEncDec(algorithm, mode, iv, plain.getBytes()); + plain = "zhongwenzhongw中文"; + checkEncDec(algorithm, mode, iv, plain.getBytes()); + plain = "中文中文謇謇謇齉齉@#"; + checkEncDec(algorithm, mode, iv, plain.getBytes()); + plain = "鬱"; + checkEncDec(algorithm, mode, iv, plain.getBytes()); + plain = "齉"; + checkEncDec(algorithm, mode, iv, plain.getBytes()); + plain = "躞"; + checkEncDec(algorithm, mode, iv, plain.getBytes()); + plain = "....."; + checkEncDec(algorithm, mode, iv, plain.getBytes()); + plain = "测试特殊符号*&(……%¥ 123abc 1 12345678 #$%#&$#$*^&(#%$@#()_()"; + checkEncDec(algorithm, mode, iv, plain.getBytes()); + plain = "测试生僻字謇鬱齉躞*&(……%¥ 123abc 12345678 123456782345678 12345678 12345678 12345678 12345678 12345678 12345678 #$%#&$#$*^&(#%$@#()_()"; + checkEncDec(algorithm, mode, iv, plain.getBytes()); + } + + private void testEncDescImpl(byte[] iv) throws JniException + { + testEncDecCases(SymmetricEncryption.AlgorithmType.AES_128.ordinal(), SymmetricEncryption.OperationMode.ECB.ordinal(), iv); + testEncDecCases(SymmetricEncryption.AlgorithmType.AES_128.ordinal(), SymmetricEncryption.OperationMode.CBC.ordinal(), iv); + + testEncDecCases(SymmetricEncryption.AlgorithmType.AES_128.ordinal(), SymmetricEncryption.OperationMode.CFB.ordinal(), iv); + testEncDecCases(SymmetricEncryption.AlgorithmType.AES_128.ordinal(), SymmetricEncryption.OperationMode.OFB.ordinal(), iv); + testEncDecCases(SymmetricEncryption.AlgorithmType.AES_128.ordinal(), SymmetricEncryption.OperationMode.CTR.ordinal(), iv); + + testEncDecCases(SymmetricEncryption.AlgorithmType.AES_192.ordinal(), SymmetricEncryption.OperationMode.ECB.ordinal(), iv); + testEncDecCases(SymmetricEncryption.AlgorithmType.AES_192.ordinal(), SymmetricEncryption.OperationMode.CBC.ordinal(), iv); + testEncDecCases(SymmetricEncryption.AlgorithmType.AES_192.ordinal(), SymmetricEncryption.OperationMode.CFB.ordinal(), iv); + testEncDecCases(SymmetricEncryption.AlgorithmType.AES_192.ordinal(), SymmetricEncryption.OperationMode.OFB.ordinal(), iv); + testEncDecCases(SymmetricEncryption.AlgorithmType.AES_192.ordinal(), SymmetricEncryption.OperationMode.CTR.ordinal(), iv); + + testEncDecCases(SymmetricEncryption.AlgorithmType.AES_256.ordinal(), SymmetricEncryption.OperationMode.ECB.ordinal(), iv); + testEncDecCases(SymmetricEncryption.AlgorithmType.AES_256.ordinal(), SymmetricEncryption.OperationMode.CBC.ordinal(), iv); + testEncDecCases(SymmetricEncryption.AlgorithmType.AES_256.ordinal(), SymmetricEncryption.OperationMode.CFB.ordinal(), iv); + testEncDecCases(SymmetricEncryption.AlgorithmType.AES_256.ordinal(), SymmetricEncryption.OperationMode.OFB.ordinal(), iv); + testEncDecCases(SymmetricEncryption.AlgorithmType.AES_256.ordinal(), SymmetricEncryption.OperationMode.CTR.ordinal(), iv); + + testEncDecCases(SymmetricEncryption.AlgorithmType.TrippleDES.ordinal(), SymmetricEncryption.OperationMode.ECB.ordinal(), iv); + testEncDecCases(SymmetricEncryption.AlgorithmType.TrippleDES.ordinal(), SymmetricEncryption.OperationMode.CBC.ordinal(), iv); + testEncDecCases(SymmetricEncryption.AlgorithmType.TrippleDES.ordinal(), SymmetricEncryption.OperationMode.CFB.ordinal(), iv); + testEncDecCases(SymmetricEncryption.AlgorithmType.TrippleDES.ordinal(), SymmetricEncryption.OperationMode.OFB.ordinal(), iv); + + testEncDecCases(SymmetricEncryption.AlgorithmType.SM4.ordinal(), SymmetricEncryption.OperationMode.ECB.ordinal(), iv); + testEncDecCases(SymmetricEncryption.AlgorithmType.SM4.ordinal(), SymmetricEncryption.OperationMode.CBC.ordinal(), iv); + testEncDecCases(SymmetricEncryption.AlgorithmType.SM4.ordinal(), SymmetricEncryption.OperationMode.CFB.ordinal(), iv); + testEncDecCases(SymmetricEncryption.AlgorithmType.SM4.ordinal(), SymmetricEncryption.OperationMode.OFB.ordinal(), iv); + } + @Test + public void testSymmetricEncDec() throws JniException, UnsupportedEncodingException { + String iv = "123"; + testEncDescImpl(iv.getBytes(StandardCharsets.UTF_8)); + + iv = "234324234"; + testEncDescImpl(iv.getBytes(StandardCharsets.UTF_8)); + } + + private void testFastOre4StringImpl(String plain, boolean hex)throws JniException, UnsupportedEncodingException + { + byte[] sk = FastOre.generateKey(); + // encrypt + byte[] cipher = FastOre.encrypt4String(sk, plain.getBytes(), hex); + // decrypt + byte[] decryptedValue = FastOre.decrypt4String(sk, cipher, hex); + Assert.assertEquals(plain, new String(decryptedValue)); + } + + private void testFastOre4NumberImpl(long plain, boolean hex)throws JniException, UnsupportedEncodingException + { + byte[] sk = FastOre.generateKey(); + // encrypt + byte[] cipher = FastOre.encrypt4Integer(sk, plain, hex); + // decrypt + long decryptedValue = FastOre.decrypt4Integer(sk, cipher, hex); + Assert.assertEquals(plain, decryptedValue); + } + + private void testFastOre4Double(double plain, boolean hex) throws JniException, NumberCodecException { + NumberCodecImpl numberCodec = new NumberCodecImpl(); + byte[] sk = FastOre.generateKey(); + // encrypt + byte[] cipher = FastOre.encrypt4Float(sk, numberCodec.toBytes(plain), hex); + // decrypt + byte[] decryptedValue = FastOre.decrypt4Float(sk, cipher, hex); + + double EPSILON = 1e-10; + double decryptedPlain = numberCodec.toDouble(decryptedValue); + Assert.assertTrue(Math.abs(decryptedPlain - plain) < EPSILON); + } + + private void testFastOre4Decimal(BigDecimal plain, boolean hex) throws JniException, NumberCodecException { + NumberCodecImpl numberCodec = new NumberCodecImpl(); + byte[] sk = FastOre.generateKey(); + // encrypt + byte[] cipher = FastOre.encrypt4Float(sk, numberCodec.toBytes(plain), hex); + // decrypt + byte[] decryptedValue = FastOre.decrypt4Float(sk, cipher, hex); + Assert.assertEquals(0, numberCodec.toBigDecimal(decryptedValue).compareTo(plain)); + } + + @Test + public void testOre() throws JniException, UnsupportedEncodingException, NumberCodecException { + String plain = "abcdwer"; + testFastOre4StringImpl(plain, true); + testFastOre4StringImpl(plain, false); + plain = "中文中文"; + testFastOre4StringImpl(plain, true); + testFastOre4StringImpl(plain, false); + plain = "测试生僻字謇鬱齉躞*&(……%¥"; + testFastOre4StringImpl(plain, true); + testFastOre4StringImpl(plain, false); + + long number = 0; + testFastOre4NumberImpl(number, true); + testFastOre4NumberImpl(number, false); + + for(int i = 0; i < 10000; i++) + { + number = -234567; + testFastOre4NumberImpl(number * i, true); + testFastOre4NumberImpl(number * i, false); + number = 876543; + testFastOre4NumberImpl(number * i, true); + testFastOre4NumberImpl(number * i, false); + } + + BigDecimal bigDecimalValue = new BigDecimal("25347862354.00000000000000002345645645000000000000000234342"); + for(int i = 0; i < 10000; i++) + { + testFastOre4Double(13425.000001232345435000000012345678 * i, true); + testFastOre4Double(13425.12345678 * i, false); + testFastOre4Double(-13425.12345678 * i, true); + testFastOre4Double(-13425.12345678 * i, false); + testFastOre4Decimal(bigDecimalValue.multiply(BigDecimal.valueOf(i)), true); + testFastOre4Decimal(bigDecimalValue.multiply(BigDecimal.valueOf(i)), false); + testFastOre4Decimal(bigDecimalValue.multiply(BigDecimal.valueOf(-i)), true); + testFastOre4Decimal(bigDecimalValue.multiply(BigDecimal.valueOf(-i)), false); + } + } +} \ No newline at end of file diff --git a/cpp/wedpr-crypto/sdk/ppc-crypto-c-sdk/CMakeLists.txt b/cpp/wedpr-crypto/sdk/ppc-crypto-c-sdk/CMakeLists.txt new file mode 100644 index 00000000..61caffc7 --- /dev/null +++ b/cpp/wedpr-crypto/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/wedpr-crypto/sdk/ppc-crypto-c-sdk/fast_ore.cpp b/cpp/wedpr-crypto/sdk/ppc-crypto-c-sdk/fast_ore.cpp new file mode 100644 index 00000000..eb4ccbe9 --- /dev/null +++ b/cpp/wedpr-crypto/sdk/ppc-crypto-c-sdk/fast_ore.cpp @@ -0,0 +1,348 @@ +/** + * 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 fast_ore.cpp + * @author: yujiechen + * @date 2023-09-12 + */ +#include "fast_ore.h" +#include "ppc-crypto-core/src/ore/FastOre.h" +#include "utils/error.h" +#include "utils/utilities.h" +#include +#include + +using namespace ppc; +using namespace ppc::crypto; + +thread_local FastOre::Ptr g_ore_impl = std::make_shared(); + +int fast_ore_key_bytes() +{ + clear_last_error(); + try + { + return g_ore_impl->keyBytes(); + } + catch (std::exception const& e) + { + auto errorMsg = boost::diagnostic_information(e); + set_last_error_msg(-1, errorMsg.c_str()); + } + return -1; +} + +uint64_t fast_ore_get_cipher_size(uint64_t plainSize, bool hex) +{ + clear_last_error(); + return g_ore_impl->estimatedCipherSize(plainSize, hex); +} + +uint64_t fast_ore_get_float_cipher_size(uint64_t _plainSize, bool hex) +{ + clear_last_error(); + return g_ore_impl->estimatedFloatCipherSize(_plainSize, hex); +} + +uint64_t fast_ore_get_plain_size(uint64_t cipherSize, bool hex) +{ + clear_last_error(); + return g_ore_impl->estimatedPlainSize(cipherSize, hex); +} +/** + * @brief generate key for the fastORE + * + * @param key the generated key + */ +void fast_ore_generate_key(OutputBuffer* key) +{ + clear_last_error(); + try + { + g_ore_impl->generateKey(key); + } + catch (std::exception const& e) + { + auto errorMsg = boost::diagnostic_information(e); + set_last_error_msg(-1, errorMsg.c_str()); + } +} + +/** + * @brief encrypt the plain data into cipher data using given key + * + * @param cipher the encrypted data + * @param key the key used to encrypt + * @param plain the plain-data + */ +void string_fast_ore_encrypt( + OutputBuffer* cipher, InputBuffer const* key, InputBuffer const* plain, bool hexEncode) +{ + clear_last_error(); + try + { + auto refPlain = bcos::bytesConstRef((bcos::byte*)plain->data, plain->len); + if (!hexEncode) + { + g_ore_impl->encrypt4String( + cipher, bcos::bytesConstRef((bcos::byte*)key->data, key->len), refPlain); + return; + } + auto hexedBufferSize = g_ore_impl->estimatedCipherSize(refPlain.size(), true); + if (cipher->len < hexedBufferSize) + { + auto errorMsg = "string_fast_ore_encrypt error for unenough cipher buffer, at least: " + + std::to_string(hexedBufferSize); + set_last_error_msg(-1, errorMsg.c_str()); + return; + } + bcos::bytes bytesResult(g_ore_impl->estimatedCipherSize(refPlain.size(), false)); + OutputBuffer bytesResultBuffer{bytesResult.data(), bytesResult.size()}; + g_ore_impl->encrypt4String( + &bytesResultBuffer, bcos::bytesConstRef((bcos::byte*)key->data, key->len), refPlain); + InputBuffer buffer{bytesResultBuffer.data, bytesResultBuffer.len}; + to_hex(cipher, &buffer); + } + catch (std::exception const& e) + { + auto errorMsg = boost::diagnostic_information(e); + set_last_error_msg(-1, errorMsg.c_str()); + } +} + +/** + * @brief decrypt the cipher data into plain data using given key + * + * @param plain the decrypted plain data + * @param key the key used to decrypt + * @param cipher the cipher + */ +void string_fast_ore_decrypt( + OutputBuffer* plain, InputBuffer const* key, InputBuffer const* cipher, bool hexEncode) +{ + clear_last_error(); + try + { + if (!hexEncode) + { + return g_ore_impl->decrypt4String(plain, + bcos::bytesConstRef((bcos::byte*)key->data, key->len), + bcos::bytesConstRef((bcos::byte*)cipher->data, cipher->len)); + } + // convert the cipher from hex to binary + bcos::bytes binaryCipher((cipher->len) / 2); + OutputBuffer binaryBuffer{binaryCipher.data(), binaryCipher.size()}; + from_hex(&binaryBuffer, cipher); + return g_ore_impl->decrypt4String(plain, + bcos::bytesConstRef((bcos::byte*)key->data, key->len), + bcos::bytesConstRef((bcos::byte*)binaryBuffer.data, binaryBuffer.len)); + } + catch (std::exception const& e) + { + auto errorMsg = boost::diagnostic_information(e); + set_last_error_msg(-1, errorMsg.c_str()); + } +} + +/** + * @brief encrypt the plain data into cipher data using given key + * + * @param cipher the encrypted data + * @param key the key used to encrypt + * @param plain the plain-data + */ +void integer_fast_ore_encrypt( + OutputBuffer* cipher, InputBuffer const* key, int64_t const& plain, bool hexEncode) +{ + clear_last_error(); + try + { + if (!hexEncode) + { + g_ore_impl->encrypt4Integer( + cipher, bcos::bytesConstRef((bcos::byte*)key->data, key->len), plain); + return; + } + + auto hexedBufferSize = g_ore_impl->estimatedCipherSize(sizeof(plain), true); + if (cipher->len < hexedBufferSize) + { + auto errorMsg = + "integer_fast_ore_encrypt error for unenough cipher buffer, at least: " + + std::to_string(hexedBufferSize); + set_last_error_msg(-1, errorMsg.c_str()); + return; + } + + bcos::bytes bytesResult(g_ore_impl->estimatedCipherSize(sizeof(plain), false)); + OutputBuffer bytesResultBuffer{bytesResult.data(), bytesResult.size()}; + g_ore_impl->encrypt4Integer( + &bytesResultBuffer, bcos::bytesConstRef((bcos::byte*)key->data, key->len), plain); + InputBuffer buffer{bytesResultBuffer.data, bytesResultBuffer.len}; + to_hex(cipher, &buffer); + } + catch (std::exception const& e) + { + auto errorMsg = boost::diagnostic_information(e); + set_last_error_msg(-1, errorMsg.c_str()); + } +} + +/** + * @brief decrypt the cipher data into plain data using given key + * + * @param plain the decrypted plain data + * @param key the key used to decrypt + * @param cipher the cipher + */ +void integer_fast_ore_decrypt( + int64_t* plain, InputBuffer const* key, InputBuffer const* cipher, bool hexEncode) +{ + clear_last_error(); + try + { + if (!hexEncode) + { + return g_ore_impl->decrypt4Integer(plain, + bcos::bytesConstRef((bcos::byte*)key->data, key->len), + bcos::bytesConstRef((bcos::byte*)cipher->data, cipher->len)); + } + + bcos::bytes binaryCipher((cipher->len) / 2); + OutputBuffer binaryBuffer{binaryCipher.data(), binaryCipher.size()}; + from_hex(&binaryBuffer, cipher); + return g_ore_impl->decrypt4Integer(plain, + bcos::bytesConstRef((bcos::byte*)key->data, key->len), + bcos::bytesConstRef((bcos::byte*)binaryBuffer.data, binaryBuffer.len)); + } + catch (std::exception const& e) + { + auto errorMsg = boost::diagnostic_information(e); + set_last_error_msg(-1, errorMsg.c_str()); + } +} + +/** + * @brief encrypt the plain data into cipher data using given key + * + * @param cipher the encrypted data + * @param key the key used to encrypt + * @param plain the plain-data + */ +void float_fast_ore_encrypt( + OutputBuffer* cipher, InputBuffer const* key, InputBuffer const* plain, bool hexEncode) +{ + clear_last_error(); + try + { + if (!hexEncode) + { + g_ore_impl->encrypt4Float(cipher, bcos::bytesConstRef((bcos::byte*)key->data, key->len), + float50{std::string(plain->data, plain->data + plain->len)}); + return; + } + + auto hexedBufferSize = g_ore_impl->estimatedFloatCipherSize(plain->len, true); + if (cipher->len < hexedBufferSize) + { + auto errorMsg = + "integer_fast_ore_encrypt error for unenough cipher buffer, at least: " + + std::to_string(hexedBufferSize); + set_last_error_msg(-1, errorMsg.c_str()); + return; + } + + bcos::bytes bytesResult(g_ore_impl->estimatedFloatCipherSize(plain->len, false)); + OutputBuffer bytesResultBuffer{bytesResult.data(), bytesResult.size()}; + g_ore_impl->encrypt4Float(&bytesResultBuffer, + bcos::bytesConstRef((bcos::byte*)key->data, key->len), + float50{std::string(plain->data, plain->data + plain->len)}); + InputBuffer buffer{bytesResultBuffer.data, bytesResultBuffer.len}; + to_hex(cipher, &buffer); + } + catch (std::exception const& e) + { + auto errorMsg = boost::diagnostic_information(e); + set_last_error_msg(-1, errorMsg.c_str()); + } +} + +/** + * @brief decrypt the cipher data into plain data using given key + * + * @param plain the decrypted plain data + * @param key the key used to decrypt + * @param cipher the cipher + */ +void float_fast_ore_decrypt( + OutputBuffer* plain, InputBuffer const* key, InputBuffer const* cipher, bool hexEncode) +{ + clear_last_error(); + try + { + float50 res; + if (!hexEncode) + { + res = g_ore_impl->decrypt4Float(bcos::bytesConstRef((bcos::byte*)key->data, key->len), + bcos::bytesConstRef((bcos::byte*)cipher->data, cipher->len)); + } + else + { + bcos::bytes binaryCipher((cipher->len) / 2); + OutputBuffer binaryBuffer{binaryCipher.data(), binaryCipher.size()}; + from_hex(&binaryBuffer, cipher); + res = g_ore_impl->decrypt4Float(bcos::bytesConstRef((bcos::byte*)key->data, key->len), + bcos::bytesConstRef((bcos::byte*)binaryBuffer.data, binaryBuffer.len)); + } + + auto plainStr = res.str(); + if (plain->len < plainStr.size()) + { + auto errorMsg = "float_fast_ore_decrypt error for unenough plain buffer, at least: " + + std::to_string(plainStr.size()); + set_last_error_msg(-1, errorMsg.c_str()); + return; + } + plain->len = plainStr.size(); + std::copy(plainStr.begin(), plainStr.end(), plain->data); + } + catch (std::exception const& e) + { + auto errorMsg = boost::diagnostic_information(e); + set_last_error_msg(-1, errorMsg.c_str()); + } +} + +/** + * @brief compare between cipher1 and cipher2 + * + * @param cipher1 + * @param cipher2 + * @return int + */ +int fast_ore_compare(InputBuffer const* cipher1, InputBuffer const* cipher2) +{ + clear_last_error(); + try + { + return g_ore_impl->compare(cipher1, cipher2); + } + catch (std::exception const& e) + { + auto errorMsg = boost::diagnostic_information(e); + set_last_error_msg(-1, errorMsg.c_str()); + } + return -1; +} \ No newline at end of file diff --git a/cpp/wedpr-crypto/sdk/ppc-crypto-c-sdk/fast_ore.h b/cpp/wedpr-crypto/sdk/ppc-crypto-c-sdk/fast_ore.h new file mode 100644 index 00000000..062f34c6 --- /dev/null +++ b/cpp/wedpr-crypto/sdk/ppc-crypto-c-sdk/fast_ore.h @@ -0,0 +1,113 @@ +/** + * 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 fast_ore.h + * @author: yujiechen + * @date 2023-08-25 + */ +#ifndef __FAST_ORE_H__ +#define __FAST_ORE_H__ + +#include "ppc-framework/libwrapper/Buffer.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int fast_ore_key_bytes(); + +uint64_t fast_ore_get_cipher_size(uint64_t plainSize, bool hex); +uint64_t fast_ore_get_float_cipher_size(uint64_t plainSize, bool hex); +uint64_t fast_ore_get_plain_size(uint64_t cipherSize, bool hex); + +/** + * @brief generate key for the fastORE + * + * @param key the generated key + */ +void fast_ore_generate_key(OutputBuffer* key); + +/** + * @brief encrypt the plain data into cipher data using given key + * + * @param cipher the encrypted data + * @param key the key used to encrypt + * @param plain the plain-data + */ +void string_fast_ore_encrypt( + OutputBuffer* cipher, InputBuffer const* key, InputBuffer const* plain, bool hexEncode); + +/** + * @brief decrypt the cipher data into plain data using given key + * + * @param plain the decrypted plain data + * @param key the key used to decrypt + * @param cipher the cipher + */ +void string_fast_ore_decrypt( + OutputBuffer* plain, InputBuffer const* key, InputBuffer const* cipher, bool hexEncode); + +/** + * @brief encrypt the plain data into cipher data using given key + * + * @param cipher the encrypted data + * @param key the key used to encrypt + * @param plain the plain-data + */ +void integer_fast_ore_encrypt( + OutputBuffer* cipher, InputBuffer const* key, int64_t const& plain, bool hexEncode); + +/** + * @brief decrypt the cipher data into plain data using given key + * + * @param plain the decrypted plain data + * @param key the key used to decrypt + * @param cipher the cipher + */ +void integer_fast_ore_decrypt( + int64_t* plain, InputBuffer const* key, InputBuffer const* cipher, bool hexEncode); + +/** + * @brief encrypt the plain data into cipher data using given key + * + * @param cipher the encrypted data + * @param key the key used to encrypt + * @param plain the plain-data + */ +void float_fast_ore_encrypt( + OutputBuffer* cipher, InputBuffer const* key, InputBuffer const* plain, bool hexEncode); + +/** + * @brief decrypt the cipher data into plain data using given key + * + * @param plain the decrypted plain data + * @param key the key used to decrypt + * @param cipher the cipher + */ +void float_fast_ore_decrypt( + OutputBuffer* plain, InputBuffer const* key, InputBuffer const* cipher, bool hexEncode); + +/** + * @brief compare between cipher1 and cipher2 + * + * @param cipher1 + * @param cipher2 + * @return int + */ +int fast_ore_compare(InputBuffer const* cipher1, InputBuffer const* cipher2); +#ifdef __cplusplus +} +#endif +#endif \ No newline at end of file diff --git a/cpp/wedpr-crypto/sdk/ppc-crypto-c-sdk/floating_point_ihc.cpp b/cpp/wedpr-crypto/sdk/ppc-crypto-c-sdk/floating_point_ihc.cpp new file mode 100644 index 00000000..baa55a27 --- /dev/null +++ b/cpp/wedpr-crypto/sdk/ppc-crypto-c-sdk/floating_point_ihc.cpp @@ -0,0 +1,172 @@ +/** + * 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 floating_point_ihc.cpp + * @author: asherli + * @date 2023-11-28 + */ +#include "floating_point_ihc.h" +#include "ppc-framework/libwrapper/FloatingPointNumber.h" +#include "ppc-homo/ihc/FloatingPointIhc.h" +#include "utils/error.h" + +using namespace ppc; +using namespace ppc::homo; +using namespace ppc::crypto; +using namespace bcos; + +FloatingPointIhc::Ptr g_fp_ihc_128 = + std::make_shared(std::make_shared((int)Ihc::IhcMode::IHC_128, 16)); +FloatingPointIhc::Ptr g_fp_ihc_256 = + std::make_shared(std::make_shared((int)Ihc::IhcMode::IHC_256, 16)); + +FloatingPointIhc::Ptr obtainFpIhcInstance(int mode) +{ + switch (mode) + { + case (int)Ihc::IhcMode::IHC_128: + return g_fp_ihc_128; + case (int)Ihc::IhcMode::IHC_256: + return g_fp_ihc_256; + default: + { + std::string errorMsg = "Unsupported ihc mode!"; + set_last_error_msg(-1, errorMsg.c_str()); + } + } + return nullptr; +} + +uint64_t ihc_floating_cipher_bytes(int mode) +{ + clear_last_error(); + auto pIhc = obtainFpIhcInstance(mode); + if (!pIhc) + { + return 0; + } + return pIhc->cipherBytes(); +} + +void ihc_floating_encrypt(OutputBuffer* cipherBytes, int mode, InputBuffer const* _key, + BIGNUM const* value, int16_t _exponent) +{ + clear_last_error(); + try + { + auto pIhc = obtainFpIhcInstance(mode); + if (!pIhc) + { + return; + } + BigNum v; + BN_copy(v.bn().get(), value); + FloatingPointNumber ffpNumber(std::move(v), _exponent); + pIhc->encrypt( + cipherBytes, bcos::bytesConstRef((bcos::byte const*)_key->data, _key->len), ffpNumber); + } + catch (std::exception const& e) + { + auto errorMsg = boost::diagnostic_information(e); + set_last_error_msg(-1, errorMsg.c_str()); + } +} + +void ihc_floating_decrypt( + BIGNUM* value, int16_t* exponent, int mode, InputBuffer const* key, InputBuffer const* cipher) +{ + clear_last_error(); + try + { + auto pIhc = obtainFpIhcInstance(mode); + if (!pIhc) + { + return; + } + auto result = pIhc->decrypt(bcos::bytesConstRef((bcos::byte const*)key->data, key->len), + bcos::bytesConstRef((bcos::byte const*)cipher->data, cipher->len)); + result.value.swap(value); + *exponent = result.exponent; + } + catch (std::exception const& e) + { + auto errorMsg = boost::diagnostic_information(e); + set_last_error_msg(-1, errorMsg.c_str()); + } +} +void ihc_floating_add( + OutputBuffer* cipherBytes, int mode, InputBuffer const* cipher1, InputBuffer const* cipher2) +{ + clear_last_error(); + try + { + auto pIhc = obtainFpIhcInstance(mode); + if (!pIhc) + { + return; + } + pIhc->add(cipherBytes, bcos::bytesConstRef((bcos::byte const*)cipher1->data, cipher1->len), + bcos::bytesConstRef((bcos::byte const*)cipher2->data, cipher2->len)); + } + catch (std::exception const& e) + { + auto errorMsg = boost::diagnostic_information(e); + set_last_error_msg(-1, errorMsg.c_str()); + } +} +void ihc_floating_sub( + OutputBuffer* cipherBytes, int mode, InputBuffer const* cipher1, InputBuffer const* cipher2) +{ + clear_last_error(); + try + { + auto pIhc = obtainFpIhcInstance(mode); + if (!pIhc) + { + return; + } + pIhc->sub(cipherBytes, bcos::bytesConstRef((bcos::byte const*)cipher1->data, cipher1->len), + bcos::bytesConstRef((bcos::byte const*)cipher2->data, cipher2->len)); + } + catch (std::exception const& e) + { + auto errorMsg = boost::diagnostic_information(e); + set_last_error_msg(-1, errorMsg.c_str()); + } +} + +void ihc_floating_scalaMul(OutputBuffer* cipherBytes, int mode, BIGNUM const* v, int16_t exponent, + InputBuffer const* cipher) +{ + clear_last_error(); + try + { + auto pIhc = obtainFpIhcInstance(mode); + if (!pIhc) + { + return; + } + BigNum value; + BN_copy(value.bn().get(), v); + FloatingPointNumber vFpNumber(std::move(value), exponent); + pIhc->scalaMul(cipherBytes, vFpNumber, + bcos::bytesConstRef((bcos::byte const*)cipher->data, cipher->len)); + } + catch (std::exception const& e) + { + auto errorMsg = boost::diagnostic_information(e); + set_last_error_msg(-1, errorMsg.c_str()); + } +} \ No newline at end of file diff --git a/cpp/wedpr-crypto/sdk/ppc-crypto-c-sdk/floating_point_ihc.h b/cpp/wedpr-crypto/sdk/ppc-crypto-c-sdk/floating_point_ihc.h new file mode 100644 index 00000000..f310faae --- /dev/null +++ b/cpp/wedpr-crypto/sdk/ppc-crypto-c-sdk/floating_point_ihc.h @@ -0,0 +1,45 @@ +/** + * 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 floating_point_ihc.h + * @author: asherli + * @date 2023-11-28 + */ + +#ifndef __FLOATING_POINT_IHC_H__ +#define __FLOATING_POINT_IHC_H__ +#include "openssl/bn.h" +#include "ppc-framework/libwrapper/Buffer.h" + +#ifdef __cplusplus +extern "C" { +#endif +void ihc_floating_encrypt(OutputBuffer* cipherBytes, int mode, InputBuffer const* _key, + BIGNUM const* value, int16_t _exponent); +void ihc_floating_decrypt( + BIGNUM* value, int16_t* exponent, int mode, InputBuffer const* key, InputBuffer const* cipher); +void ihc_floating_add( + OutputBuffer* cipherBytes, int mode, InputBuffer const* cipher1, InputBuffer const* cipher2); +void ihc_floating_sub( + OutputBuffer* cipherBytes, int mode, InputBuffer const* cipher1, InputBuffer const* cipher2); +void ihc_floating_scalaMul(OutputBuffer* cipherBytes, int mode, BIGNUM const* v, int16_t exponent, + InputBuffer const* cipher); + +uint64_t ihc_floating_cipher_bytes(int mode); + +#ifdef __cplusplus +} +#endif +#endif \ No newline at end of file diff --git a/cpp/wedpr-crypto/sdk/ppc-crypto-c-sdk/floating_point_paillier.cpp b/cpp/wedpr-crypto/sdk/ppc-crypto-c-sdk/floating_point_paillier.cpp new file mode 100644 index 00000000..419411ad --- /dev/null +++ b/cpp/wedpr-crypto/sdk/ppc-crypto-c-sdk/floating_point_paillier.cpp @@ -0,0 +1,264 @@ +/** + * 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 floating_point_paillier.cpp + * @author: yujiechen + * @date 2023-08-20 + */ +#include "floating_point_paillier.h" +#include "homo_paillier.h" +#include "ppc-homo/paillier/FloatingPointPaillier.h" +#include "ppc-homo/paillier/OpenSSLPaillier.h" +#include "utils/error.h" + +using namespace ppc; +using namespace ppc::homo; +using namespace ppc::crypto; +using namespace bcos; + +OpenSSLPaillier::Ptr g_paillier_ptr = std::make_shared(); +thread_local FloatingPointPaillier::Ptr g_floating_point_paillier = + std::make_shared(g_paillier_ptr); + +unsigned int floating_point_paillier_cipher_bytes(unsigned int keyBits) +{ + clear_last_error(); + return FloatingPointPaillier::maxCipherBytesLen(keyBits); +} +/** + * @brief encrypt {value*10^exponent} using paillier crt-optimization + * + * @param cipherBytes the encrypted result + * @param value the value to be encrypted + * @param exponent the exponent of the value to be encrypted + * @param keypair the keypair used to encrypt + */ +void floating_point_paillier_encrypt_fast( + OutputBuffer* cipherBytes, BIGNUM const* value, int16_t exponent, void* keypair) +{ + clear_last_error(); + try + { + BigNum v; + BN_copy(v.bn().get(), value); + FloatingPointNumber floatingPointV(std::move(v), exponent); + g_floating_point_paillier->encryptFast(cipherBytes, floatingPointV, keypair); + } + catch (std::exception const& e) + { + auto errorMsg = boost::diagnostic_information(e); + set_last_error_msg(-1, errorMsg.c_str()); + } +} + +void floating_point_paillier_encrypt_fast_without_precompute(OutputBuffer* cipherBytes, + BIGNUM const* value, int16_t exponent, InputBuffer const* sk, InputBuffer const* pkBytes) +{ + auto keyPair = paillier_load_keypair(sk, pkBytes); + if (!last_call_success()) + { + return; + } + floating_point_paillier_encrypt_fast(cipherBytes, value, exponent, keyPair); + paillier_free_key_pair(keyPair); +} + +/** + * @brief encrypt {value*10^exponent} withou using paillier crt-optimization + * + * @param cipherBytes the encrypted result + * @param value the value to be encrypted + * @param exponent the exponent of the value to be encrypted + * @param public_key the public_key used to encrypt + */ +void floating_point_paillier_encrypt( + OutputBuffer* cipherBytes, BIGNUM const* value, int16_t exponent, void* public_key) +{ + clear_last_error(); + try + { + BigNum v; + BN_copy(v.bn().get(), value); + FloatingPointNumber floatingPointV(std::move(v), exponent); + g_floating_point_paillier->encrypt(cipherBytes, floatingPointV, public_key); + } + catch (std::exception const& e) + { + auto errorMsg = boost::diagnostic_information(e); + set_last_error_msg(-1, errorMsg.c_str()); + } +} +void floating_point_paillier_encrypt_without_precompute( + OutputBuffer* cipherBytes, BIGNUM const* value, int16_t _exponent, InputBuffer const* pkBytes) +{ + auto pk = paillier_load_public_key(pkBytes); + if (!last_call_success()) + { + return; + } + floating_point_paillier_encrypt(cipherBytes, value, _exponent, pk); + paillier_free_public_key(pk); +} +/** + * @brief paillier decrypt + * + * @param value the decrypted value + * @param exponent the exponent of the decrypted value + * @param cipher the cipher to be decrypted + * @param keypair the keyPair used to decrypt + */ +void floating_point_paillier_decrypt( + BIGNUM* value, int16_t* exponent, InputBuffer const* cipher, void* keypair) +{ + clear_last_error(); + try + { + auto ret = g_floating_point_paillier->decrypt( + bcos::bytesConstRef(cipher->data, cipher->len), keypair); + // swap the result to value + ret.value.swap(value); + *exponent = ret.exponent; + } + catch (std::exception const& e) + { + auto errorMsg = boost::diagnostic_information(e); + set_last_error_msg(-1, errorMsg.c_str()); + } +} + +void floating_point_paillier_decrypt_without_precompute(BIGNUM* value, int16_t* exponent, + InputBuffer const* cipher, InputBuffer const* sk, InputBuffer const* pkBytes) +{ + auto keyPair = paillier_load_keypair(sk, pkBytes); + if (!last_call_success()) + { + return; + } + floating_point_paillier_decrypt(value, exponent, cipher, keyPair); + paillier_free_key_pair(keyPair); +} + +/** + * @brief paillier add + * + * @param cipherBytes the paillier cipher add result + * @param cipher1 + * @param cipher2 + * @param public_key + */ +void floating_point_paillier_add(OutputBuffer* cipherBytes, InputBuffer const* cipher1, + InputBuffer const* cipher2, void* public_key) +{ + clear_last_error(); + try + { + g_floating_point_paillier->add(cipherBytes, + bcos::bytesConstRef(cipher1->data, cipher1->len), + bcos::bytesConstRef(cipher2->data, cipher2->len), public_key); + } + catch (std::exception const& e) + { + auto errorMsg = boost::diagnostic_information(e); + set_last_error_msg(-1, errorMsg.c_str()); + } +} +void floating_point_paillier_add_without_precompute(OutputBuffer* cipherBytes, + InputBuffer const* cipher1, InputBuffer const* cipher2, InputBuffer const* pkBytes) +{ + auto pk = paillier_load_public_key(pkBytes); + if (!last_call_success()) + { + return; + } + floating_point_paillier_add(cipherBytes, cipher1, cipher2, pk); + paillier_free_public_key(pk); +} + +/** + * @brief paillier sub + * + * @param cipherBytes the paillier cipher sub result + * @param cipher1 + * @param cipher2 + * @param public_key + */ +void floating_point_paillier_sub(OutputBuffer* cipherBytes, InputBuffer const* cipher1, + InputBuffer const* cipher2, void* public_key) +{ + clear_last_error(); + try + { + g_floating_point_paillier->sub(cipherBytes, + bcos::bytesConstRef(cipher1->data, cipher1->len), + bcos::bytesConstRef(cipher2->data, cipher2->len), public_key); + } + catch (std::exception const& e) + { + auto errorMsg = boost::diagnostic_information(e); + set_last_error_msg(-1, errorMsg.c_str()); + } +} + +void floating_point_paillier_sub_without_precompute(OutputBuffer* cipherBytes, + InputBuffer const* cipher1, InputBuffer const* cipher2, InputBuffer const* pkBytes) +{ + auto pk = paillier_load_public_key(pkBytes); + if (!last_call_success()) + { + return; + } + floating_point_paillier_sub(cipherBytes, cipher1, cipher2, pk); + paillier_free_public_key(pk); +} + +/** + * @brief paillier-scalar-multipy + * + * @param cipherBytes the paillier cipher multipy result + * @param v the value + * @param exponent the exponent of the value + * @param cipher the cipher + * @param public_key + */ +void floating_point_paillier_scalaMul(OutputBuffer* cipherBytes, BIGNUM const* v, int16_t exponent, + InputBuffer const* cipher, void* public_key) +{ + clear_last_error(); + try + { + BigNum value; + BN_copy(value.bn().get(), v); + FloatingPointNumber floatingPointV(std::move(value), exponent); + g_floating_point_paillier->scalaMul(cipherBytes, floatingPointV, + bcos::bytesConstRef(cipher->data, cipher->len), public_key); + } + catch (std::exception const& e) + { + auto errorMsg = boost::diagnostic_information(e); + set_last_error_msg(-1, errorMsg.c_str()); + } +} + +void floating_point_paillier_scalaMul_without_precompute(OutputBuffer* cipherBytes, BIGNUM const* v, + int16_t exponent, InputBuffer const* cipher, InputBuffer const* pkBytes) +{ + auto pk = paillier_load_public_key(pkBytes); + if (!last_call_success()) + { + return; + } + floating_point_paillier_scalaMul(cipherBytes, v, exponent, cipher, pk); + paillier_free_public_key(pk); +} \ No newline at end of file diff --git a/cpp/wedpr-crypto/sdk/ppc-crypto-c-sdk/floating_point_paillier.h b/cpp/wedpr-crypto/sdk/ppc-crypto-c-sdk/floating_point_paillier.h new file mode 100644 index 00000000..8834c6bf --- /dev/null +++ b/cpp/wedpr-crypto/sdk/ppc-crypto-c-sdk/floating_point_paillier.h @@ -0,0 +1,111 @@ +/** + * 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 floating_point_paillier.h + * @author: yujiechen + * @date 2023-08-20 + */ +#ifndef __FLOATING_POINT_PAILLIER_H__ +#define __FLOATING_POINT_PAILLIER_H__ +#include "openssl/bn.h" +#include "ppc-framework/libwrapper/Buffer.h" +#ifdef __cplusplus +extern "C" { +#endif + +unsigned int floating_point_paillier_cipher_bytes(unsigned int keyBits); +/** + * @brief encrypt {value*10^exponent} using paillier crt-optimization + * + * @param cipherBytes the encrypted result + * @param value the value to be encrypted + * @param exponent the exponent of the value to be encrypted + * @param keypair the keypair used to encrypt + */ +void floating_point_paillier_encrypt_fast( + OutputBuffer* cipherBytes, BIGNUM const* value, int16_t exponent, void* keypair); + +void floating_point_paillier_encrypt_fast_without_precompute(OutputBuffer* cipherBytes, + BIGNUM const* value, int16_t exponent, InputBuffer const* sk, InputBuffer const* pk); + +/** + * @brief encrypt {value*10^exponent} withou using paillier crt-optimization + * + * @param cipherBytes the encrypted result + * @param value the value to be encrypted + * @param exponent the exponent of the value to be encrypted + * @param public_key the public_key used to encrypt + */ +void floating_point_paillier_encrypt( + OutputBuffer* cipherBytes, BIGNUM const* value, int16_t _exponent, void* public_key); +void floating_point_paillier_encrypt_without_precompute( + OutputBuffer* cipherBytes, BIGNUM const* value, int16_t _exponent, InputBuffer const* pkBytes); + +/** + * @brief paillier decrypt + * + * @param value the decrypted value + * @param exponent the exponent of the decrypted value + * @param cipher the cipher to be decrypted + * @param keypair the keyPair used to decrypt + */ +void floating_point_paillier_decrypt( + BIGNUM* value, int16_t* exponent, InputBuffer const* cipher, void* keypair); +void floating_point_paillier_decrypt_without_precompute(BIGNUM* value, int16_t* exponent, + InputBuffer const* cipher, InputBuffer const* sk, InputBuffer const* pk); + +/** + * @brief paillier add + * + * @param cipherBytes the paillier cipher add result + * @param cipher1 + * @param cipher2 + * @param public_key + */ +void floating_point_paillier_add(OutputBuffer* cipherBytes, InputBuffer const* cipher1, + InputBuffer const* cipher2, void* public_key); +void floating_point_paillier_add_without_precompute(OutputBuffer* cipherBytes, + InputBuffer const* cipher1, InputBuffer const* cipher2, InputBuffer const* pkBytes); + +/** + * @brief paillier sub + * + * @param cipherBytes the paillier cipher sub result + * @param cipher1 + * @param cipher2 + * @param public_key + */ +void floating_point_paillier_sub(OutputBuffer* cipherBytes, InputBuffer const* cipher1, + InputBuffer const* cipher2, void* public_key); +void floating_point_paillier_sub_without_precompute(OutputBuffer* cipherBytes, + InputBuffer const* cipher1, InputBuffer const* cipher2, InputBuffer const* pkBytes); + +/** + * @brief paillier-scalar-multipy + * + * @param cipherBytes the paillier cipher multipy result + * @param v the value + * @param exponent the exponent of the value + * @param cipher the cipher + * @param public_key + */ +void floating_point_paillier_scalaMul(OutputBuffer* cipherBytes, BIGNUM const* v, int16_t exponent, + InputBuffer const* cipher, void* public_key); +void floating_point_paillier_scalaMul_without_precompute(OutputBuffer* cipherBytes, BIGNUM const* v, + int16_t exponent, InputBuffer const* cipher, InputBuffer const* pkBytes); +#ifdef __cplusplus +} +#endif +#endif \ No newline at end of file diff --git a/cpp/wedpr-crypto/sdk/ppc-crypto-c-sdk/homo_ihc.cpp b/cpp/wedpr-crypto/sdk/ppc-crypto-c-sdk/homo_ihc.cpp new file mode 100644 index 00000000..3662de14 --- /dev/null +++ b/cpp/wedpr-crypto/sdk/ppc-crypto-c-sdk/homo_ihc.cpp @@ -0,0 +1,192 @@ +/** + * 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 homo_ihc.cpp + * @author: asherli + * @date 2023-11-28 + */ +#include "homo_ihc.h" +#include "ppc-homo/ihc/IhcImpl.h" +#include "utils/error.h" + +using namespace ppc; +using namespace ppc::homo; +using namespace ppc::crypto; +using namespace bcos; + +Ihc::Ptr g_ihc_128 = std::make_shared((int)Ihc::IhcMode::IHC_128, 16); +Ihc::Ptr g_ihc_256 = std::make_shared((int)Ihc::IhcMode::IHC_256, 16); + +Ihc::Ptr obtainIhcInstance(int mode) +{ + switch (mode) + { + case (int)Ihc::IhcMode::IHC_128: + return g_ihc_128; + case (int)Ihc::IhcMode::IHC_256: + return g_ihc_256; + default: + { + std::string errorMsg = "Unsupported ihc mode!"; + set_last_error_msg(-1, errorMsg.c_str()); + } + } + return nullptr; +} + +unsigned int ihc_key_bytes(int mode) +{ + clear_last_error(); + auto pIhc = obtainIhcInstance(mode); + if (!pIhc) + { + return 0; + } + return pIhc->keyBytes(); +} + +uint64_t ihc_cipher_bytes(int mode) +{ + clear_last_error(); + auto pIhc = obtainIhcInstance(mode); + if (!pIhc) + { + return 0; + } + return pIhc->cipherBytes(); +} + +void ihc_generate_key(OutputBuffer* key, int mode) +{ + clear_last_error(); + try + { + Ihc::Ptr pIhc = obtainIhcInstance(mode); + if (!pIhc) + { + return; + } + pIhc->generateKey(key); + } + catch (std::exception const& e) + { + auto errorMsg = boost::diagnostic_information(e); + set_last_error_msg(-1, errorMsg.c_str()); + } +} + +void ihc_encrypt( + OutputBuffer* cipherBytes, int _mode, InputBuffer const* _key, BIGNUM const* _plain) +{ + clear_last_error(); + try + { + auto pIhc = obtainIhcInstance(_mode); + if (!pIhc) + { + return; + } + pIhc->encrypt(cipherBytes, bcos::bytesConstRef((bcos::byte*)_key->data, _key->len), _plain); + } + catch (std::exception const& e) + { + auto errorMsg = boost::diagnostic_information(e); + set_last_error_msg(-1, errorMsg.c_str()); + } +} + +void ihc_decrypt(BIGNUM* _result, int _mode, InputBuffer const* _key, InputBuffer const* cipher) +{ + clear_last_error(); + try + { + auto pIhc = obtainIhcInstance(_mode); + if (!pIhc) + { + return; + } + auto decryptedV = pIhc->decrypt(bcos::bytesConstRef((bcos::byte*)_key->data, _key->len), + bcos::bytesConstRef((bcos::byte*)cipher->data, cipher->len)); + BN_print_fp(stdout, decryptedV.bn().get()); + decryptedV.swap(_result); + } + catch (std::exception const& e) + { + auto errorMsg = boost::diagnostic_information(e); + set_last_error_msg(-1, errorMsg.c_str()); + } +} + +void ihc_add( + OutputBuffer* cipherBytes, int mode, InputBuffer const* cipher1, InputBuffer const* cipher2) +{ + clear_last_error(); + try + { + auto pIhc = obtainIhcInstance(mode); + if (!pIhc) + { + return; + } + pIhc->add(cipherBytes, bcos::bytesConstRef((bcos::byte const*)cipher1->data, cipher1->len), + bcos::bytesConstRef((bcos::byte const*)cipher2->data, cipher2->len)); + } + catch (std::exception const& e) + { + auto errorMsg = boost::diagnostic_information(e); + set_last_error_msg(-1, errorMsg.c_str()); + } +} + +void ihc_sub( + OutputBuffer* cipherBytes, int mode, InputBuffer const* cipher1, InputBuffer const* cipher2) +{ + clear_last_error(); + try + { + auto pIhc = obtainIhcInstance(mode); + if (!pIhc) + { + return; + } + pIhc->sub(cipherBytes, bcos::bytesConstRef((bcos::byte const*)cipher1->data, cipher1->len), + bcos::bytesConstRef((bcos::byte const*)cipher2->data, cipher2->len)); + } + catch (std::exception const& e) + { + auto errorMsg = boost::diagnostic_information(e); + set_last_error_msg(-1, errorMsg.c_str()); + } +} + +void ihc_scalaMul(OutputBuffer* cipherBytes, int mode, BIGNUM const* v, InputBuffer const* cipher) +{ + clear_last_error(); + try + { + auto pIhc = obtainIhcInstance(mode); + if (!pIhc) + { + return; + } + pIhc->scalaMul( + cipherBytes, v, bcos::bytesConstRef((bcos::byte const*)cipher->data, cipher->len)); + } + catch (std::exception const& e) + { + auto errorMsg = boost::diagnostic_information(e); + set_last_error_msg(-1, errorMsg.c_str()); + } +} \ No newline at end of file diff --git a/cpp/wedpr-crypto/sdk/ppc-crypto-c-sdk/homo_ihc.h b/cpp/wedpr-crypto/sdk/ppc-crypto-c-sdk/homo_ihc.h new file mode 100644 index 00000000..734e822b --- /dev/null +++ b/cpp/wedpr-crypto/sdk/ppc-crypto-c-sdk/homo_ihc.h @@ -0,0 +1,46 @@ +/** + * 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 homo_ihc.h + * @author: asherli + * @date 2023-11-28 + */ + +#ifndef __HOMO_IHC_H__ +#define __HOMO_IHC_H__ +#include "openssl/bn.h" +#include "ppc-framework/libwrapper/Buffer.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void ihc_generate_key(OutputBuffer* key, int mode); +void ihc_encrypt( + OutputBuffer* cipherBytes, int mode, InputBuffer const* _key, BIGNUM const* _plain); +void ihc_decrypt(BIGNUM* _result, int _mode, InputBuffer const* _key, InputBuffer const* cipher); + +void ihc_add( + OutputBuffer* cipherBytes, int mode, InputBuffer const* cipher1, InputBuffer const* cipher2); +void ihc_sub( + OutputBuffer* cipherBytes, int mode, InputBuffer const* cipher1, InputBuffer const* cipher2); +void ihc_scalaMul(OutputBuffer* cipherBytes, int mode, BIGNUM const* v, InputBuffer const* cipher); + +unsigned int ihc_key_bytes(int mode); +uint64_t ihc_cipher_bytes(int mode); +#ifdef __cplusplus +} +#endif +#endif \ No newline at end of file diff --git a/cpp/wedpr-crypto/sdk/ppc-crypto-c-sdk/homo_paillier.cpp b/cpp/wedpr-crypto/sdk/ppc-crypto-c-sdk/homo_paillier.cpp new file mode 100644 index 00000000..020c8f57 --- /dev/null +++ b/cpp/wedpr-crypto/sdk/ppc-crypto-c-sdk/homo_paillier.cpp @@ -0,0 +1,555 @@ +/** + * 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 homo_paillier.cpp + * @author: yujiechen + * @date 2023-08-11 + */ +#include "homo_paillier.h" +#include "ppc-framework/libwrapper/BigNum.h" +#include "ppc-homo/paillier/OpenSSLPaillier.h" +#include "ppc-homo/paillier/OpenSSLPaillierKeyPair.h" +#include "utils/error.h" +#include +#include + +using namespace ppc::homo; +using namespace ppc::crypto; +using namespace bcos; + +thread_local OpenSSLPaillier::Ptr g_paillier_impl = std::make_shared(); + +unsigned int paillier_max_public_key_bytes(int key_bits) +{ + clear_last_error(); + return ppc::homo::PaillierPublicKey::maxBytes(key_bits); +} + +unsigned int paillier_r_bytes_len(int key_bits) +{ + clear_last_error(); + return ppc::homo::OpenSSLPaillier::rBytesLen(key_bits); +} + +unsigned int paillier_max_private_key_bytes(int key_bits) +{ + clear_last_error(); + return ppc::homo::PaillierPrivateKey::maxBytes(key_bits); +} + +unsigned int paillier_max_cipher_bytes(int key_bits) +{ + clear_last_error(); + return ppc::homo::OpenSSLPaillier::maxCipherBytesLen(key_bits); +} + +unsigned int paillier_key_bits_from_keypair(void* key_pair) +{ + clear_last_error(); + auto keyPair = (ppc::homo::OpenSSLPaillierKeyPair*)(key_pair); + auto pk = (ppc::homo::PaillierPublicKey*)(keyPair->pk()); + return pk->keyBits; +} + +unsigned int paillier_key_bits_from_public_key(void* public_key) +{ + clear_last_error(); + auto pk = (ppc::homo::PaillierPublicKey*)(public_key); + return pk->keyBits; +} + +/** + * @brief obtain n from the given keyPair + * + * @param n + * @param pk + * @return void + */ +void paillier_n_from_pk(BIGNUM* n, void* pk) +{ + clear_last_error(); + auto pkPtr = (PaillierPublicKey*)pk; + pkPtr->n.copy(n); +} + +/** + * @brief generate the paillier KeyPair + * + * @return void* pointer to the generated paillier key-pair + */ +void* paillier_generate_keypair(int key_bits) +{ + clear_last_error(); + try + { + auto keypair = g_paillier_impl->generateKeyPair(key_bits); + return keypair.release(); + } + catch (std::exception const& e) + { + auto errorMsg = boost::diagnostic_information(e); + set_last_error_msg(-1, errorMsg.c_str()); + return nullptr; + } +} + +/** + * @brief load the encoded privateKey and publicKey into key-pair object + * + * @param sk the encoded privateKey + * @param pk the encoded publicKey + * @return void* void* pointer to the loaded paillier key-pair + */ +void* paillier_load_keypair(InputBuffer const* sk, InputBuffer const* pk) +{ + clear_last_error(); + try + { + auto keyPair = + std::make_unique(sk->data, sk->len, pk->data, pk->len); + return keyPair.release(); + } + catch (std::exception const& e) + { + auto errorMsg = boost::diagnostic_information(e); + set_last_error_msg(-1, errorMsg.c_str()); + return nullptr; + } +} + + +/** + * @brief free the allocated keypair + * + * @param keypair + */ +void paillier_free_key_pair(void* keypair) +{ + clear_last_error(); + if (keypair) + { + free(keypair); + } +} + +/** + * @brief get the public key object according to the keypair + * + * @param keypair + * @return void* + */ +void* paillier_get_public_key(void* keypair) +{ + clear_last_error(); + auto paillierKeyPair = (OpenSSLPaillierKeyPair*)keypair; + return paillierKeyPair->pk(); +} +/** + * @brief load the publicKey object from the encoded publicKey + * + * @param pk the encoded publicKey + * @return void* the pointer to the public key object + */ +void* paillier_load_public_key(InputBuffer const* pkBytes) +{ + clear_last_error(); + try + { + auto pk = std::make_unique(pkBytes->data, pkBytes->len); + return pk.release(); + } + catch (std::exception const& e) + { + auto errorMsg = boost::diagnostic_information(e); + set_last_error_msg(-1, errorMsg.c_str()); + return nullptr; + } +} + +/** + * @brief free the allocated public key + * + * @param public_key + */ +void paillier_free_public_key(void* public_key) +{ + clear_last_error(); + if (public_key) + { + free(public_key); + } +} + +/** + * @brief free the private key + * + * @param private_key + */ +void paillier_free_private_key(void* private_key) +{ + clear_last_error(); + if (private_key) + { + free(private_key); + } +} + +/** + * @brief load the private key according to the keyBytes + * + * @param sk + * @return void* + */ +void* paillier_load_private_key(InputBuffer const* skBytes) +{ + clear_last_error(); + try + { + auto sk = std::make_unique(skBytes->data, skBytes->len); + return sk.release(); + } + catch (std::exception const& e) + { + auto errorMsg = boost::diagnostic_information(e); + set_last_error_msg(-1, errorMsg.c_str()); + return nullptr; + } +} + +/** + * @brief get the encoded publicKey from given keyPair object + * + * @param pkBytes return the encoded public key + * Note: should allocate OutputBuffer before call this function, the lifecycle of OutputBuffer is + * managed by the caller(maybe cross-programming language) + * @param keypair the pointer to the keyPair object + */ +void paillier_set_public_key_bytes_from_keypair(OutputBuffer* pkBytes, void* keypair) +{ + clear_last_error(); + try + { + auto paillierKeyPair = (OpenSSLPaillierKeyPair*)(keypair); + auto pk = (PaillierPublicKey*)(paillierKeyPair->pk()); + pkBytes->len = pk->serialize((bcos::byte*)pkBytes->data, pkBytes->len); + } + catch (std::exception const& e) + { + auto errorMsg = boost::diagnostic_information(e); + set_last_error_msg(-1, errorMsg.c_str()); + } +} + +OutputBuffer paillier_get_public_key_bytes_from_keyPair(void* keypair) +{ + clear_last_error(); + unsigned char* publicKeyBytes = NULL; + try + { + auto paillierKeyPair = (OpenSSLPaillierKeyPair*)(keypair); + auto pk = (PaillierPublicKey*)(paillierKeyPair->pk()); + + auto bufferLen = paillier_max_public_key_bytes(pk->keyBits); + // Note: this should be released by the caller after used + publicKeyBytes = (unsigned char*)malloc(bufferLen); + OutputBuffer publicKeyBuffer{publicKeyBytes, bufferLen}; + paillier_set_public_key_bytes_from_keypair(&publicKeyBuffer, keypair); + return publicKeyBuffer; + } + catch (std::exception const& e) + { + if (!publicKeyBytes) + { + free(publicKeyBytes); + } + auto errorMsg = boost::diagnostic_information(e); + set_last_error_msg(-1, errorMsg.c_str()); + return OutputBuffer{NULL, 0}; + } +} + +/** + * @brief Get the private key bytes object + * + * @param keypair the pointer to the keyPair object + * @return void* the encoded private key + */ +void paillier_set_private_key_bytes_from_keypair(OutputBuffer* skBytes, void* keypair) +{ + clear_last_error(); + try + { + auto paillierKeyPair = (OpenSSLPaillierKeyPair*)(keypair); + auto sk = (PaillierPrivateKey*)(paillierKeyPair->sk()); + skBytes->len = sk->serialize((bcos::byte*)skBytes->data, skBytes->len); + } + catch (std::exception const& e) + { + auto errorMsg = boost::diagnostic_information(e); + set_last_error_msg(-1, errorMsg.c_str()); + } +} + +/** + * @brief Get the private key bytes + * + * @param keypair the pointer to the keyPair object + * @return OutputBuffer the private key-bytes + * Note: the caller should release the allocated buffer + */ +OutputBuffer paillier_get_private_key_bytes_from_keypair(void* keypair) +{ + clear_last_error(); + unsigned char* skBytes = NULL; + try + { + auto paillierKeyPair = (OpenSSLPaillierKeyPair*)(keypair); + auto sk = (PaillierPrivateKey*)(paillierKeyPair->sk()); + auto bufferLen = paillier_max_private_key_bytes(sk->keyBits); + + // Note: this should be released by the caller after used + skBytes = (unsigned char*)malloc(bufferLen); + OutputBuffer skBuffer{skBytes, bufferLen}; + paillier_set_private_key_bytes_from_keypair(&skBuffer, keypair); + return skBuffer; + } + catch (std::exception const& e) + { + if (skBytes) + { + free(skBytes); + } + auto errorMsg = boost::diagnostic_information(e); + set_last_error_msg(-1, errorMsg.c_str()); + return OutputBuffer{NULL, 0}; + } +} + +/** + * @brief encrypt the value into paillier cipher using given keyPair with CRT optimization + * + * @param cipherBytes return the encrypted cipher + * @param value the value to be encrypted + * @param keypair the keyPair used to encrypt + */ +void paillier_encryt_fast( + OutputBuffer* cipherBytes, OutputBuffer* rBytes, BIGNUM* value, void* keypair) +{ + clear_last_error(); + try + { + g_paillier_impl->encrypt_with_crt(cipherBytes, rBytes, value, keypair); + } + catch (std::exception const& e) + { + auto errorMsg = boost::diagnostic_information(e); + set_last_error_msg(-1, errorMsg.c_str()); + } +} + +void paillier_encryt_fast_without_precompute(OutputBuffer* cipherBytes, OutputBuffer* rBytes, + BIGNUM* value, InputBuffer const* sk, InputBuffer const* pk) +{ + auto keyPair = paillier_load_keypair(sk, pk); + if (!last_call_success()) + { + return; + } + + paillier_encryt_fast(cipherBytes, rBytes, value, keyPair); + paillier_free_key_pair(keyPair); +} + +/** + * @brief encrypt the value into paillier cipher using given keyPair without CRT optimization + * + * @param cipherBytes return the encrypted cipher + * @param value the value to be encrypted + * @param keypair the keyPair used to encrypt + */ +void paillier_encryt( + OutputBuffer* cipherBytes, OutputBuffer* rBytes, BIGNUM* value, void* publicKey) +{ + clear_last_error(); + try + { + g_paillier_impl->encrypt(cipherBytes, rBytes, value, publicKey); + } + catch (std::exception const& e) + { + auto errorMsg = boost::diagnostic_information(e); + set_last_error_msg(-1, errorMsg.c_str()); + } +} +void paillier_encryt_without_precompute( + OutputBuffer* cipherBytes, OutputBuffer* rBytes, BIGNUM* value, InputBuffer const* pkBytes) +{ + auto pk = paillier_load_public_key(pkBytes); + if (!last_call_success()) + { + return; + } + paillier_encryt(cipherBytes, rBytes, value, pk); + paillier_free_public_key(pk); +} + +/** + * @brief decrypt the cipher using given keyPair + * + * @param cipher the cipher to be decrypted + * @param keypair the keyPair used to decrypt + * @return BIGNUM* the decrypted result + * Note: the caller should release the allocated BIGNUM + */ +BIGNUM* paillier_decrypt(InputBuffer const* cipher, void* keypair) +{ + clear_last_error(); + try + { + auto decryptResult = g_paillier_impl->decrypt( + bcos::bytesConstRef((bcos::byte const*)cipher->data, cipher->len), keypair); + BIGNUM* ret = BN_new(); + // swap the result + BN_swap(ret, decryptResult.bn().get()); + return ret; + } + catch (std::exception const& e) + { + auto errorMsg = boost::diagnostic_information(e); + set_last_error_msg(-1, errorMsg.c_str()); + return NULL; + } +} + +BIGNUM* paillier_decrypt_without_precompute( + InputBuffer const* cipher, InputBuffer const* sk, InputBuffer const* pk) +{ + auto keyPair = paillier_load_keypair(sk, pk); + if (!last_call_success()) + { + return NULL; + } + auto result = paillier_decrypt(cipher, keyPair); + paillier_free_key_pair(keyPair); + return result; +} + +/** + * @brief paillier ciphertext space addition, namely: cipher1 + cipher2 + * + * @param cipher1 + * @param cipher2 + * @param public_key + * @return void* the addition result + */ +void paillier_add(OutputBuffer* cipherBytes, InputBuffer const* cipher1, InputBuffer const* cipher2, + void* public_key) +{ + clear_last_error(); + try + { + auto cipher1Ref = bcos::bytesConstRef(cipher1->data, cipher1->len); + auto cipher2Ref = bcos::bytesConstRef(cipher2->data, cipher2->len); + g_paillier_impl->add(cipherBytes, cipher1Ref, cipher2Ref, public_key); + } + catch (std::exception const& e) + { + auto errorMsg = boost::diagnostic_information(e); + set_last_error_msg(-1, errorMsg.c_str()); + } +} +void paillier_add_without_precompute(OutputBuffer* cipherBytes, InputBuffer const* cipher1, + InputBuffer const* cipher2, InputBuffer const* pkBytes) +{ + auto pk = paillier_load_public_key(pkBytes); + if (!last_call_success()) + { + return; + } + paillier_add(cipherBytes, cipher1, cipher2, pk); + paillier_free_public_key(pk); +} +/** + * @brief paillier ciphertext space addition, namely: cipher1 - cipher2 + * + * @param cipher1 + * @param cipher2 + * @param public_key + * @return void* the subtraction result + */ +void paillier_sub(OutputBuffer* cipherBytes, InputBuffer const* cipher1, InputBuffer const* cipher2, + void* public_key) +{ + clear_last_error(); + try + { + auto cipher1Ref = bcos::bytesConstRef(cipher1->data, cipher1->len); + auto cipher2Ref = bcos::bytesConstRef(cipher2->data, cipher2->len); + g_paillier_impl->sub(cipherBytes, cipher1Ref, cipher2Ref, public_key); + } + catch (std::exception const& e) + { + auto errorMsg = boost::diagnostic_information(e); + set_last_error_msg(-1, errorMsg.c_str()); + } +} + +void paillier_sub_without_precompute(OutputBuffer* cipherBytes, InputBuffer const* cipher1, + InputBuffer const* cipher2, InputBuffer const* pkBytes) +{ + auto pk = paillier_load_public_key(pkBytes); + if (!last_call_success()) + { + return; + } + paillier_sub(cipherBytes, cipher1, cipher2, pk); + paillier_free_public_key(pk); +} +/** + * @brief paillier ciphertext space scala-multiply, namely: v * cipher + * + * @param v the scala-number + * Note: the lifecycle of value is managed by the caller + * @param cipher + * @param public_key + * @return void* the scala-multiply result + */ +void paillier_scala_mul( + OutputBuffer* cipherBytes, BIGNUM* v, InputBuffer const* cipher, void* public_key) +{ + clear_last_error(); + try + { + auto cipherRef = bcos::bytesConstRef(cipher->data, cipher->len); + g_paillier_impl->scalaMul(cipherBytes, v, cipherRef, public_key); + } + catch (std::exception const& e) + { + auto errorMsg = boost::diagnostic_information(e); + set_last_error_msg(-1, errorMsg.c_str()); + } +} + +void paillier_scala_mul_without_precompute( + OutputBuffer* cipherBytes, BIGNUM* v, InputBuffer const* cipher, InputBuffer const* pkBytes) +{ + auto pk = paillier_load_public_key(pkBytes); + if (!last_call_success()) + { + return; + } + paillier_scala_mul(cipherBytes, v, cipher, pk); + paillier_free_public_key(pk); +} \ No newline at end of file diff --git a/cpp/wedpr-crypto/sdk/ppc-crypto-c-sdk/homo_paillier.h b/cpp/wedpr-crypto/sdk/ppc-crypto-c-sdk/homo_paillier.h new file mode 100644 index 00000000..0c70c294 --- /dev/null +++ b/cpp/wedpr-crypto/sdk/ppc-crypto-c-sdk/homo_paillier.h @@ -0,0 +1,265 @@ +/** + * 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 homo_paillier.h + * @author: yujiechen + * @date 2023-08-11 + */ +#ifndef __HOMO_PAILLIER_H__ +#define __HOMO_PAILLIER_H__ + +#include "openssl/bn.h" +#include "ppc-framework/libwrapper/Buffer.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief get the paillier max public key bytes according to the keyBits + * + * @param key_bits e.g. 512/1024/2048/3096 + * @return unsigned int the public key bytes + */ +unsigned int paillier_max_public_key_bytes(int key_bits); + +/** + * @brief get the paillier random r bytes according to the keyBits + * @param key_bits e.g. 512/1024/2048/3096 + */ +unsigned int paillier_r_bytes_len(int key_bits); + +/** + * @brief get the paillier max private key bytes according to the keyBits + * + * @param key_bits e.g. 512/1024/2048/3096 + * @return unsigned int the private key bytes + */ +unsigned int paillier_max_private_key_bytes(int key_bits); + +/** + * @brief get the paillier max cipher bytes according to the keyBits + * + * @param key_bits e.g. 512/1024/2048/3096 + * @return unsigned int the cipher bytes + */ +unsigned int paillier_max_cipher_bytes(int key_bits); + + +/** + * @brief get the paillier max cipher bytes according to the keypair + * + * @param key_pair the key pair object + * @return unsigned int + */ +unsigned int paillier_key_bits_from_keypair(void* key_pair); + +/** + * @brief obtain n from the given keyPair + * + * @param n + * @param pk + */ +void paillier_n_from_pk(BIGNUM* n, void* pk); + +/** + * @brief get the paillier max cipher bytes according to the public key + * + * @param public_key the public key object + * @return unsigned int + */ +unsigned int paillier_key_bits_from_public_key(void* public_key); + +/** + * @brief generate the paillier KeyPair + * + * @return void* pointer to the generated paillier key-pair + */ +void* paillier_generate_keypair(int key_bits); + +/** + * @brief load the encoded privateKey and publicKey into key-pair object + * + * @param sk the encoded privateKey + * @param pk the encoded publicKey + * @return void* void* pointer to the loaded paillier key-pair + */ +void* paillier_load_keypair(InputBuffer const* sk, InputBuffer const* pk); + +/** + * @brief free the allocated keypair + * + * @param keypair + */ +void paillier_free_key_pair(void* keypair); + +/** + * @brief get the public key object according to the keypair + * + * @param keypair + * @return void* + */ +void* paillier_get_public_key(void* keypair); + +/** + * @brief load the publicKey object from the encoded publicKey + * + * @param pk the encoded publicKey + * @return void* the pointer to the public key object + */ +void* paillier_load_public_key(InputBuffer const* pk); + + +/** + * @brief free the allocated public key + * + * @param public_key + */ +void paillier_free_public_key(void* public_key); + +/** + * @brief load the private key according to the keyBytes + * + * @param sk + * @return void* + */ +void* paillier_load_private_key(InputBuffer const* sk); + +/** + * @brief free the private key + * + * @param private_key + */ +void paillier_free_private_key(void* private_key); + +/** + * @brief get the encoded publicKey from given keyPair object + * + * @param pkBytes return the encoded public key + * Note: should allocate OutputBuffer before call this function, the lifecycle of OutputBuffer is + * managed by the caller(maybe cross-programming language) + * @param keypair the pointer to the keyPair object + */ +void paillier_set_public_key_bytes_from_keypair(OutputBuffer* pkBytes, void* keypair); + +/** + * @brief get the encoded publicKey from given keyPair object + * + * @param keypair the pointer to the keyPair object + * @return OutputBuffer the public key-bytes + * Note: the caller should release the allocated buffer + */ +OutputBuffer paillier_get_public_key_bytes_from_keyPair(void* keypair); + + +/** + * @brief Get the private key bytes object + * + * @param pkBytes return the encoded private key + * Note: should allocate OutputBuffer before call this function, the lifecycle of OutputBuffer is + * managed by the caller(maybe cross-programming language) + * @param keypair the pointer to the keyPair object + */ +void paillier_set_private_key_bytes_from_keypair(OutputBuffer* skBytes, void* keypair); + +/** + * @brief Get the private key bytes + * + * @param keypair the pointer to the keyPair object + * @return OutputBuffer the private key-bytes + * Note: the caller should release the allocated buffer + */ +OutputBuffer paillier_get_private_key_bytes_from_keypair(void* keypair); + +/** + * @brief encrypt the value into paillier cipher using given keyPair with CRT optimization + * + * @param cipherBytes return the encrypted cipher + * @param value the value to be encrypted + * @param keypair the keyPair used to encrypt + */ +void paillier_encryt_fast( + OutputBuffer* cipherBytes, OutputBuffer* rBytes, BIGNUM* value, void* keypair); +void paillier_encryt_fast_without_precompute(OutputBuffer* cipherBytes, OutputBuffer* rBytes, + BIGNUM* value, InputBuffer const* sk, InputBuffer const* pk); + +/** + * @brief encrypt the value into paillier cipher using given keyPair without CRT optimization + * + * @param cipherBytes return the encrypted cipher + * @param value the value to be encrypted + * @param publicKey the keyPair used to encrypt + */ +void paillier_encryt( + OutputBuffer* cipherBytes, OutputBuffer* rBytes, BIGNUM* value, void* publicKey); +void paillier_encryt_without_precompute( + OutputBuffer* cipherBytes, OutputBuffer* rBytes, BIGNUM* value, InputBuffer const* pk); + +/** + * @brief decrypt the cipher using given keyPair + * + * @param cipher the cipher to be decrypted + * @param keypair the keyPair used to decrypt + * @return BIGNUM* the decrypted result + * Note: the caller should release the allocated BIGNUM + */ +BIGNUM* paillier_decrypt(InputBuffer const* cipher, void* keypair); +BIGNUM* paillier_decrypt_without_precompute( + InputBuffer const* cipher, InputBuffer const* sk, InputBuffer const* pk); + +/** + * @brief paillier ciphertext space addition, namely: cipher1 + cipher2 + * + * @param cipher1 + * @param cipher2 + * @param public_key + * @return void* the addition result + */ +void paillier_add(OutputBuffer* cipherBytes, InputBuffer const* cipher1, InputBuffer const* cipher2, + void* public_key); +void paillier_add_without_precompute(OutputBuffer* cipherBytes, InputBuffer const* cipher1, + InputBuffer const* cipher2, InputBuffer const* pk); + +/** + * @brief paillier ciphertext space addition, namely: cipher1 - cipher2 + * + * @param cipher1 + * @param cipher2 + * @param public_key + * @return void* the subtraction result + */ +void paillier_sub(OutputBuffer* cipherBytes, InputBuffer const* cipher1, InputBuffer const* cipher2, + void* public_key); +void paillier_sub_without_precompute(OutputBuffer* cipherBytes, InputBuffer const* cipher1, + InputBuffer const* cipher2, InputBuffer const* pkBytes); + +/** + * @brief paillier ciphertext space scala-multiply, namely: v * cipher + * + * @param v the scala-number + * Note: the lifecycle of value is managed by the caller + * @param cipher + * @param public_key + * @return void* the scala-multiply result + */ +void paillier_scala_mul( + OutputBuffer* cipherBytes, BIGNUM* v, InputBuffer const* cipher, void* public_key); +void paillier_scala_mul_without_precompute( + OutputBuffer* cipherBytes, BIGNUM* v, InputBuffer const* cipher, InputBuffer const* pkBytes); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/cpp/wedpr-crypto/sdk/ppc-crypto-c-sdk/symmetric_encryption.cpp b/cpp/wedpr-crypto/sdk/ppc-crypto-c-sdk/symmetric_encryption.cpp new file mode 100644 index 00000000..fd5c4686 --- /dev/null +++ b/cpp/wedpr-crypto/sdk/ppc-crypto-c-sdk/symmetric_encryption.cpp @@ -0,0 +1,187 @@ +/** + * 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 symmetric_encryption.cpp + * @author: yujiechen + * @date 2023-09-08 + */ +#include "symmetric_encryption.h" +#include "ppc-crypto-core/src/sym-crypto/OpenSSL3DES.h" +#include "ppc-crypto-core/src/sym-crypto/OpenSSLAES.h" +#include "ppc-crypto-core/src/sym-crypto/OpenSSLSM4.h" +#include "utils/error.h" +#include +#include + +using namespace ppc; +using namespace ppc::crypto; + +thread_local OpenSSLSM4::Ptr g_sm4_impl = std::make_shared(); +thread_local OpenSSL3DES::Ptr g_3des_impl = std::make_shared(); +thread_local OpenSSLAES::Ptr g_aes128_impl = + std::make_shared(OpenSSLAES::AESType::AES128); +thread_local OpenSSLAES::Ptr g_aes192_impl = + std::make_shared(OpenSSLAES::AESType::AES192); +thread_local OpenSSLAES::Ptr g_aes256_impl = + std::make_shared(OpenSSLAES::AESType::AES256); + + +SymCrypto::Ptr obtainSymCryptoImpl(int algorithm) +{ + switch (algorithm) + { + case AlgorithmType::AES_128: + return g_aes128_impl; + case AlgorithmType::AES_192: + return g_aes192_impl; + case AlgorithmType::AES_256: + return g_aes256_impl; + case AlgorithmType::TrippleDES: + return g_3des_impl; + case AlgorithmType::SM4: + return g_sm4_impl; + default: + return nullptr; + } +} + +unsigned int symmetric_block_size(int algorithm) +{ + clear_last_error(); + auto impl = obtainSymCryptoImpl(algorithm); + if (!impl) + { + auto errorMsg = + "symmetric_block_size error for unsupported algorithm: " + std::to_string(algorithm); + set_last_error_msg(-1, errorMsg.c_str()); + return -1; + } + return impl->blockSize(); +} + +int symmetric_key_bytes(int algorithm, int mode) +{ + clear_last_error(); + try + { + auto impl = obtainSymCryptoImpl(algorithm); + if (!impl) + { + auto errorMsg = + "symmetric_key_bytes error for unsupported algorithm: " + std::to_string(algorithm); + set_last_error_msg(-1, errorMsg.c_str()); + return -1; + } + return impl->keyBytes((SymCrypto::OperationMode)mode); + } + catch (std::exception const& e) + { + auto errorMsg = boost::diagnostic_information(e); + set_last_error_msg(-1, errorMsg.c_str()); + } + return -1; +} +/** + * @brief generate key for symmetric encryption + * + * @param _sk the generated key + */ +void symmetric_generate_key(OutputBuffer* _sk, int algorithm, int mode) +{ + clear_last_error(); + try + { + auto impl = obtainSymCryptoImpl(algorithm); + if (!impl) + { + auto errorMsg = "Unsupported algorithm: " + std::to_string(algorithm); + set_last_error_msg(-1, errorMsg.c_str()); + return; + } + impl->generateKey(_sk, (SymCrypto::OperationMode)mode); + } + catch (std::exception const& e) + { + auto errorMsg = boost::diagnostic_information(e); + set_last_error_msg(-1, errorMsg.c_str()); + } +} + +/** + * @brief encrypt the plainData into cipher using given algorithm and mode + * + * @param _cipher the encrypted cipher + * @param algorithm the symmetric encryption algorithm, e.g. AES/DES/SM4 + * @param mode the encryption mode + * @param sk the sk used to encrypt + * @param plainData the plainData + */ +void symmetric_encrypt(OutputBuffer* cipher, int algorithm, int mode, InputBuffer const* sk, + InputBuffer const* iv, InputBuffer const* plainData) +{ + clear_last_error(); + try + { + auto impl = obtainSymCryptoImpl(algorithm); + if (!impl) + { + auto errorMsg = + "symmetric_encrypt error: unsupported algorithm " + std::to_string(algorithm); + set_last_error_msg(-1, errorMsg.c_str()); + return; + } + impl->encrypt(cipher, (SymCrypto::OperationMode)mode, + bcos::bytesConstRef(sk->data, sk->len), bcos::bytesConstRef(iv->data, iv->len), + bcos::bytesConstRef(plainData->data, plainData->len)); + } + catch (std::exception const& e) + { + auto errorMsg = boost::diagnostic_information(e); + set_last_error_msg(-1, errorMsg.c_str()); + } +} + +/** + * @brief decrypt the given cipher into plain using given sk/algorithm and mode + * + * @param plain the decrypted plainData + * @param algorithm the symmetric encryption algorithm, e.g. AES/DES/SM4 + * @param mode the encryption mode + * @param sk the sk used to decrypt + * @param cipher the cipher + */ +void symmetric_decrypt(OutputBuffer* plain, int algorithm, int mode, InputBuffer const* sk, + InputBuffer const* iv, InputBuffer const* cipher) +{ + clear_last_error(); + try + { + auto impl = obtainSymCryptoImpl(algorithm); + if (!impl) + { + auto errorMsg = + "symmetric_decrypt failed for unsupported algorithm: " + std::to_string(algorithm); + set_last_error_msg(-1, errorMsg.c_str()); + return; + } + impl->decrypt(plain, (SymCrypto::OperationMode)mode, bcos::bytesConstRef(sk->data, sk->len), + bcos::bytesConstRef(iv->data, iv->len), bcos::bytesConstRef(cipher->data, cipher->len)); + } + catch (std::exception const& e) + { + auto errorMsg = boost::diagnostic_information(e); + set_last_error_msg(-1, errorMsg.c_str()); + } +} diff --git a/cpp/wedpr-crypto/sdk/ppc-crypto-c-sdk/symmetric_encryption.h b/cpp/wedpr-crypto/sdk/ppc-crypto-c-sdk/symmetric_encryption.h new file mode 100644 index 00000000..a23c1e55 --- /dev/null +++ b/cpp/wedpr-crypto/sdk/ppc-crypto-c-sdk/symmetric_encryption.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 symmetric_encryption.h + * @author: yujiechen + * @date 2023-08-25 + */ +#ifndef __SYMMETRIC_ENCRYPTION_H__ +#define __SYMMETRIC_ENCRYPTION_H__ + +#include "ppc-framework/libwrapper/Buffer.h" + +#ifdef __cplusplus +extern "C" { +#endif +enum AlgorithmType +{ + AES_128, + AES_192, + AES_256, + TrippleDES, + SM4 +}; +unsigned int symmetric_block_size(int algorithm); +int symmetric_key_bytes(int algorithm, int mode); +/** + * @brief generate key for symmetric encryption + * + * @param _sk the generated key + */ +void symmetric_generate_key(OutputBuffer* _sk, int algorithm, int mode); + +/** + * @brief encrypt the plainData into cipher using given algorithm and mode + * + * @param _cipher the encrypted cipher + * @param algorithm the symmetric encryption algorithm, e.g. AES/DES/SM4 + * @param mode the encryption mode + * @param sk the sk used to encrypt + * @param plainData the plainData + */ +void symmetric_encrypt(OutputBuffer* cipher, int algorithm, int mode, InputBuffer const* sk, + InputBuffer const* iv, InputBuffer const* plainData); + +/** + * @brief decrypt the cipher + * + * @param algorithm + * @param mode + * @param sk + * @param cipher + */ + +/** + * @brief decrypt the given cipher into plain using given sk/algorithm and mode + * + * @param plain the decrypted plainData + * @param algorithm the symmetric encryption algorithm, e.g. AES/DES/SM4 + * @param mode the encryption mode + * @param sk the sk used to decrypt + * @param cipher the cipher + */ +void symmetric_decrypt(OutputBuffer* plain, int algorithm, int mode, InputBuffer const* sk, + InputBuffer const* iv, InputBuffer const* cipher); + +#ifdef __cplusplus +} +#endif +#endif \ No newline at end of file diff --git a/cpp/wedpr-crypto/sdk/ppc-crypto-c-sdk/utils/error.cpp b/cpp/wedpr-crypto/sdk/ppc-crypto-c-sdk/utils/error.cpp new file mode 100644 index 00000000..67907256 --- /dev/null +++ b/cpp/wedpr-crypto/sdk/ppc-crypto-c-sdk/utils/error.cpp @@ -0,0 +1,73 @@ +/** + * 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 error.cpp + * @author: yujiechen + * @date 2023-08-11 + */ + + +#include "error.h" + +#include +#include +#include + +// record c error +thread_local int g_global_error = 0; +thread_local std::string g_global_msg; + +/** + * @brief the last sync operation success or not + * + * @return int + */ +int last_call_success() +{ + return g_global_error == PPC_CRYPTO_C_SDK_SUCCESS; +} + +/** + * @brief gets status of the most recent sync operation + * + * @return int + */ +int get_last_error() +{ + return g_global_error; +} + +/** + * @brief gets error message of the most recent sync operation, effect if get_last_error + * return not zero + * + * @return const char* + */ +const char* get_last_error_msg() +{ + return g_global_msg.c_str(); +} + +void clear_last_error() +{ + g_global_error = 0; + g_global_msg.clear(); +} + +void set_last_error_msg(int error, const char* msg) +{ + g_global_error = error; + g_global_msg = std::string(msg); +} \ No newline at end of file diff --git a/cpp/wedpr-crypto/sdk/ppc-crypto-c-sdk/utils/error.h b/cpp/wedpr-crypto/sdk/ppc-crypto-c-sdk/utils/error.h new file mode 100644 index 00000000..5355814b --- /dev/null +++ b/cpp/wedpr-crypto/sdk/ppc-crypto-c-sdk/utils/error.h @@ -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 error.h + * @author: yujiechen + * @date 2023-08-11 + */ + +#ifndef __INCLUDE_ERROR__ +#define __INCLUDE_ERROR__ + +#ifdef __cplusplus +extern "C" { +#endif + +#define PPC_CRYPTO_C_SDK_SUCCESS (0) + +/** + * @brief the last sync operation success or not + * + * @return int + */ +int last_call_success(); + +/** + * @brief gets status of the recent sync operation + * Note: thread safe operation + * + * @return int + */ +int get_last_error(); + +/** + * @brief gets error message of the recent sync operation, effect if get_last_error, + * return not zero + * Note: thread safe operation + * + * @return const char* + */ +const char* get_last_error_msg(); + +/** + * @brief clear the last error + */ +void clear_last_error(); + +/** + * @brief set the last error and error message + */ +void set_last_error_msg(int error, const char* msg); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/cpp/wedpr-crypto/sdk/ppc-crypto-c-sdk/utils/utilities.cpp b/cpp/wedpr-crypto/sdk/ppc-crypto-c-sdk/utils/utilities.cpp new file mode 100644 index 00000000..fdb58790 --- /dev/null +++ b/cpp/wedpr-crypto/sdk/ppc-crypto-c-sdk/utils/utilities.cpp @@ -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 utilities.cpp + * @author: yujiechen + * @date 2023-08-22 + */ +#include "utilities.h" +#include "error.h" +#include + +using namespace bcos; + +int max_msg_size = 255; + +void to_hex(OutputBuffer* hexData, InputBuffer const* bytesData) +{ + clear_last_error(); + try + { + auto hexStr = *(bcos::toHexString(bytesData->data, bytesData->data + bytesData->len)); + hexData->len = hexStr.size(); + memcpy((void*)hexData->data, (const void*)hexStr.data(), hexData->len); + } + catch (std::exception const& e) + { + auto errorMsg = boost::diagnostic_information(e); + BCOS_LOG(ERROR) << LOG_DESC("to_hex error") << errorMsg; + set_last_error_msg(-1, errorMsg.data()); + } +} + +void from_hex(OutputBuffer* bytesData, InputBuffer const* hexData) +{ + clear_last_error(); + try + { + // TODO: decrease the copy overhead + auto hexString = std::string(hexData->data, hexData->data + hexData->len); + auto bytesResult = *(bcos::fromHexString(hexString)); + bytesData->len = bytesResult.size(); + memcpy((void*)bytesData->data, (const void*)bytesResult.data(), bytesResult.size()); + } + catch (std::exception const& e) + { + auto errorMsg = boost::diagnostic_information(e); + BCOS_LOG(ERROR) << LOG_DESC("from_hex error") << errorMsg; + set_last_error_msg(-1, errorMsg.data()); + } +} \ No newline at end of file diff --git a/cpp/wedpr-crypto/sdk/ppc-crypto-c-sdk/utils/utilities.h b/cpp/wedpr-crypto/sdk/ppc-crypto-c-sdk/utils/utilities.h new file mode 100644 index 00000000..0f1bb6f1 --- /dev/null +++ b/cpp/wedpr-crypto/sdk/ppc-crypto-c-sdk/utils/utilities.h @@ -0,0 +1,34 @@ +/** + * 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 utilities.h + * @author: yujiechen + * @date 2023-08-22 + */ + +#ifndef __UTILITIES_H__ +#define __UTILITIES_H__ +#include "ppc-framework/libwrapper/Buffer.h" + +#ifdef __cplusplus +extern "C" { +#endif +extern int max_msg_size; +void to_hex(OutputBuffer* hexData, InputBuffer const* bytesData); +void from_hex(OutputBuffer* bytesData, InputBuffer const* hexData); +#ifdef __cplusplus +} +#endif +#endif diff --git a/cpp/wedpr-crypto/sdk/tests/CMakeLists.txt b/cpp/wedpr-crypto/sdk/tests/CMakeLists.txt new file mode 100644 index 00000000..214f1ced --- /dev/null +++ b/cpp/wedpr-crypto/sdk/tests/CMakeLists.txt @@ -0,0 +1,10 @@ +file(GLOB_RECURSE SOURCES "*.cpp" "*.h") + +# cmake settings +set(TEST_BINARY_NAME test-ppc-crypto-c-sdk) + +add_executable(${TEST_BINARY_NAME} ${SOURCES}) +target_include_directories(${TEST_BINARY_NAME} PRIVATE .) + +target_link_libraries(${TEST_BINARY_NAME} ${PPC_CRYPTO_C_SDK_STATIC_TARGET} ${BOOST_UNIT_TEST}) +add_test(NAME test-ppc-crypto-c-sdk WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} COMMAND ${TEST_BINARY_NAME}) \ No newline at end of file diff --git a/cpp/wedpr-crypto/sdk/tests/TestFastOre.cpp b/cpp/wedpr-crypto/sdk/tests/TestFastOre.cpp new file mode 100644 index 00000000..3218c3dc --- /dev/null +++ b/cpp/wedpr-crypto/sdk/tests/TestFastOre.cpp @@ -0,0 +1,150 @@ +/* + * 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 applicabl 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 TestFastOre.cpp + * @author: shawnhe + * @date 2023-11-24 + */ + +#include "ppc-crypto-c-sdk/fast_ore.h" +#include "ppc-framework/Common.h" +#include +#include + +using namespace bcos; +using namespace bcos::test; +namespace ppc::test +{ +BOOST_FIXTURE_TEST_SUITE(fastOreTest, TestPromptFixture) + + +void testStringOreImpl(bcos::bytes const& plain, bool hex) +{ + // generate sk + bcos::bytes skBytes(fast_ore_key_bytes()); + OutputBuffer skBuffer{skBytes.data(), skBytes.size()}; + fast_ore_generate_key(&skBuffer); + + // encrypt + InputBuffer sk{skBytes.data(), skBytes.size()}; + InputBuffer plainBuffer{plain.data(), plain.size()}; + + bcos::bytes cipher(fast_ore_get_cipher_size(plain.size(), hex)); + OutputBuffer cipherBuffer{cipher.data(), cipher.size()}; + string_fast_ore_encrypt(&cipherBuffer, &sk, &plainBuffer, hex); + // decrypt + InputBuffer cipherBuffer2{cipher.data(), cipher.size()}; + bcos::bytes decryptedPlain(fast_ore_get_plain_size(cipher.size(), hex)); + OutputBuffer decryptedPlainBuffer{decryptedPlain.data(), decryptedPlain.size()}; + string_fast_ore_decrypt(&decryptedPlainBuffer, &sk, &cipherBuffer2, hex); + std::cout << "##### plain: " << std::string(plain.begin(), plain.end()) << std::endl; + std::cout << "##### decryptedPlain: " + << std::string(decryptedPlain.begin(), decryptedPlain.end()) << std::endl; + // check + BOOST_CHECK(decryptedPlain == plain); +} + +void testIntegerOreImpl(const int64_t& plain, bool hex) +{ + // generate sk + bcos::bytes skBytes(fast_ore_key_bytes()); + OutputBuffer skBuffer{skBytes.data(), skBytes.size()}; + fast_ore_generate_key(&skBuffer); + + // encrypt + InputBuffer sk{skBytes.data(), skBytes.size()}; + + bcos::bytes cipher(fast_ore_get_cipher_size(sizeof(plain), hex)); + OutputBuffer cipherBuffer{cipher.data(), cipher.size()}; + integer_fast_ore_encrypt(&cipherBuffer, &sk, plain, hex); + // decrypt + InputBuffer cipherBuffer2{cipher.data(), cipher.size()}; + + int64_t decryptedPlain; + integer_fast_ore_decrypt(&decryptedPlain, &sk, &cipherBuffer2, hex); + + // check + BOOST_CHECK(decryptedPlain == plain); +} + +void testFloatOreImpl(const float50& plain, bool hex) +{ + // generate sk + bcos::bytes skBytes(fast_ore_key_bytes()); + OutputBuffer skBuffer{skBytes.data(), skBytes.size()}; + fast_ore_generate_key(&skBuffer); + + // encrypt + InputBuffer sk{skBytes.data(), skBytes.size()}; + + auto str = plain.str(); + bcos::bytes cipher(fast_ore_get_float_cipher_size(str.size(), hex)); + OutputBuffer cipherBuffer{cipher.data(), cipher.size()}; + + + InputBuffer inputBuffer{(bcos::byte*)str.data(), str.size()}; + float_fast_ore_encrypt(&cipherBuffer, &sk, &inputBuffer, hex); + + // decrypt + InputBuffer cipherBuffer2{cipherBuffer.data, cipherBuffer.len}; + + std::string decryptedPlain; + decryptedPlain.resize(32); + OutputBuffer decryptedPlainBuffer{(bcos::byte*)decryptedPlain.data(), decryptedPlain.size()}; + float_fast_ore_decrypt(&decryptedPlainBuffer, &sk, &cipherBuffer2, hex); + decryptedPlain.resize(decryptedPlainBuffer.len); + + // check + BOOST_CHECK(float50{decryptedPlain} == plain); +} + +BOOST_AUTO_TEST_CASE(testStringOreOps) +{ + std::string plain = "adbwerwerwe"; + bcos::bytes plainBytes(plain.begin(), plain.end()); + testStringOreImpl(plainBytes, true); + testStringOreImpl(plainBytes, false); + + plain = "中文中文"; + bcos::bytes plainBytes2(plain.begin(), plain.end()); + testStringOreImpl(plainBytes2, true); + testStringOreImpl(plainBytes2, false); +} + +BOOST_AUTO_TEST_CASE(testIntegerOreOps) +{ + for (int i = 0; i < 1000; i++) + { + testIntegerOreImpl(i * 123456, true); + testIntegerOreImpl(i * 123456, false); + testIntegerOreImpl(i * -123456, true); + testIntegerOreImpl(i * -123456, false); + } +} + +BOOST_AUTO_TEST_CASE(testFloatOreOps) +{ + for (int i = 0; i < 1000; i++) + { + auto plain = float50{"-134335849.23449798"}; + testFloatOreImpl(plain * i, true); + testFloatOreImpl(plain * i, false); + testFloatOreImpl(plain * -i, true); + testFloatOreImpl(plain * -i, false); + } +} + +BOOST_AUTO_TEST_SUITE_END() +} // namespace ppc::test \ No newline at end of file diff --git a/cpp/wedpr-crypto/sdk/tests/TestHomoPaillier.cpp b/cpp/wedpr-crypto/sdk/tests/TestHomoPaillier.cpp new file mode 100644 index 00000000..7a8df98c --- /dev/null +++ b/cpp/wedpr-crypto/sdk/tests/TestHomoPaillier.cpp @@ -0,0 +1,461 @@ +/* + * 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 applicabl 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 TestHomoPaillier.cpp + * @author: yujiechen + * @date 2023-08-15 + */ +#include "ppc-crypto-c-sdk/fast_ore.h" +#include "ppc-crypto-c-sdk/floating_point_ihc.h" +#include "ppc-crypto-c-sdk/homo_ihc.h" +#include "ppc-crypto-c-sdk/homo_paillier.h" +#include "ppc-crypto-c-sdk/utils/error.h" +#include "ppc-framework/crypto/Ihc.h" +#include "ppc-framework/libwrapper/BigNum.h" +#include "ppc-framework/libwrapper/Buffer.h" +#include "ppc-framework/libwrapper/FloatingPointNumber.h" +#include "ppc-homo/codec/FloatingPointCodec.h" +#include "ppc-homo/paillier/OpenSSLPaillierKeyPair.h" +#include +#include +#include +#include + +using namespace bcos; +using namespace bcos::test; +using namespace ppc::homo; +using namespace ppc::crypto; +namespace ppc::test +{ +BOOST_FIXTURE_TEST_SUITE(homoPaillierTest, TestPromptFixture) + +void checkPrivateKey(PaillierPrivateKey* sk1, PaillierPrivateKey* sk2) +{ + BOOST_CHECK(sk1->keyBits == sk2->keyBits); + BOOST_CHECK(sk1->lambda.cmp(sk2->lambda.bn().get()) == 0); + BOOST_CHECK(sk1->p.cmp(sk2->p.bn().get()) == 0); + BOOST_CHECK(sk1->q.cmp(sk2->q.bn().get()) == 0); + BOOST_CHECK(sk1->pSqrt.cmp(sk2->pSqrt.bn().get()) == 0); + BOOST_CHECK(sk1->qSqrt.cmp(sk2->qSqrt.bn().get()) == 0); + BOOST_CHECK(sk1->qSqrtInverse.cmp(sk2->qSqrtInverse.bn().get()) == 0); + BOOST_CHECK(sk1->pOrderSqrt.cmp(sk2->pOrderSqrt.bn().get()) == 0); + BOOST_CHECK(sk1->qOrderSqrt.cmp(sk2->qOrderSqrt.bn().get()) == 0); +} +void checkPublicKey(PaillierPublicKey* pk1, PaillierPublicKey* pk2) +{ + BOOST_CHECK(pk1->keyBits == pk2->keyBits); + BOOST_CHECK(pk1->n.cmp(pk2->n.bn().get()) == 0); + BOOST_CHECK(pk1->nSqrt.cmp(pk2->nSqrt.bn().get()) == 0); + BOOST_CHECK(pk1->h.cmp(pk2->h.bn().get()) == 0); + BOOST_CHECK(pk1->h_s.cmp(pk2->h_s.bn().get()) == 0); +} +void testPaillierKeyPairImpl(int _keyBits) +{ + auto keyPair = paillier_generate_keypair(_keyBits); + auto encodedPk = paillier_get_public_key_bytes_from_keyPair(keyPair); + auto encodedSk = paillier_get_private_key_bytes_from_keypair(keyPair); + // load the keypair + InputBuffer sk{(const unsigned char*)encodedSk.data, encodedSk.len}; + InputBuffer pk{(const unsigned char*)encodedPk.data, encodedPk.len}; + auto decodedKeyPair = paillier_load_keypair(&sk, &pk); + // check the key pair + auto pk1 = (PaillierPublicKey*)(((OpenSSLPaillierKeyPair*)keyPair)->pk()); + auto pk2 = (PaillierPublicKey*)(((OpenSSLPaillierKeyPair*)decodedKeyPair)->pk()); + checkPublicKey(pk1, pk2); + + auto sk1 = (PaillierPrivateKey*)(((OpenSSLPaillierKeyPair*)keyPair)->sk()); + auto sk2 = (PaillierPrivateKey*)(((OpenSSLPaillierKeyPair*)decodedKeyPair)->sk()); + checkPrivateKey(sk1, sk2); + + // load the public key + auto decodedPk = paillier_load_public_key(&pk); + checkPublicKey(pk1, (PaillierPublicKey*)decodedPk); +} +BOOST_AUTO_TEST_CASE(testPaillierKeyPair) +{ + testPaillierKeyPairImpl(2048); +} + +bcos::bytes testEncryptDecrypt(BIGNUM* _value, void* keypair, int _keyBits) +{ + auto pk = ((OpenSSLPaillierKeyPair*)keypair)->pk(); + BigNum n; + paillier_n_from_pk(n.bn().get(), (void*)pk); + std::cout << "#### n: " << BN_print_fp(stdout, n.bn().get()) << std::endl; + + bcos::bytes cipher(paillier_max_cipher_bytes(_keyBits), 0); + OutputBuffer cipherBuffer{cipher.data(), cipher.size()}; + // encrypt fast + bcos::bytes rBytes(paillier_r_bytes_len(_keyBits)); + OutputBuffer rBuffer{rBytes.data(), rBytes.size()}; + paillier_encryt_fast(&cipherBuffer, &rBuffer, _value, keypair); + if (!last_call_success()) + { + std::cout << "### paillier_encryt_fast error for: " << get_last_error_msg() << std::endl; + } + BOOST_CHECK(last_call_success()); + std::cout << "#### rBuffer: " << bcos::toHex(rBytes) << ", rBuffer size: " << rBuffer.len + << std::endl; + + // encrypt + bcos::bytes cipher2(paillier_max_cipher_bytes(_keyBits), 0); + OutputBuffer cipherBuffer2{cipher2.data(), cipher2.size()}; + paillier_encryt(&cipherBuffer2, nullptr, _value, pk); + if (!last_call_success()) + { + std::cout << "### paillier_encryt error for: " << get_last_error_msg() << std::endl; + } + BOOST_CHECK(last_call_success() == 1); + // decrypt with keypair + InputBuffer inputBuffer{cipherBuffer.data, cipherBuffer.len}; + auto decodeV = paillier_decrypt(&inputBuffer, keypair); + if (!last_call_success()) + { + std::cout << "#### paillier decrypt error: " << get_last_error_msg() << std::endl; + } + BOOST_CHECK(last_call_success() == 1); + BOOST_CHECK(BN_cmp(_value, decodeV) == 0); + + InputBuffer inputBuffer2{cipherBuffer2.data, cipherBuffer2.len}; + decodeV = paillier_decrypt(&inputBuffer2, keypair); + if (!last_call_success()) + { + std::cout << "#### paillier decrypt error: " << get_last_error_msg() << std::endl; + } + BOOST_CHECK(last_call_success()); + std::cout << "###### expectedValue: " << std::endl; + BN_print_fp(stdout, _value); + std::cout << "###### decodeV:" << std::endl; + BN_print_fp(stdout, decodeV); + BOOST_CHECK(BN_cmp(_value, decodeV) == 0); + cipher.resize(cipherBuffer.len); + return cipher; +} + +void testPaillierOpsImpl( + BigNum const& m1, BigNum const& m2, BigNum const& v, void* keypair, int keyBits) +{ + auto pk = ((OpenSSLPaillierKeyPair*)keypair)->pk(); + auto c1 = testEncryptDecrypt(m1.bn().get(), keypair, keyBits); + InputBuffer c1Buffer{c1.data(), c1.size()}; + + auto c2 = testEncryptDecrypt(m2.bn().get(), keypair, keyBits); + InputBuffer c2Buffer{c2.data(), c2.size()}; + + /// check m1 + m2 + bcos::bytes cipherResult(paillier_max_cipher_bytes(keyBits), 0); + OutputBuffer resultBuffer{cipherResult.data(), cipherResult.size()}; + paillier_add(&resultBuffer, &c1Buffer, &c2Buffer, pk); + if (!last_call_success()) + { + std::cout << "### paillier_add error for: " << get_last_error_msg() << std::endl; + } + BOOST_CHECK(last_call_success()); + // decrypt and check + InputBuffer encodedBuffer{resultBuffer.data, resultBuffer.len}; + auto decodeV = paillier_decrypt(&encodedBuffer, keypair); + if (!last_call_success()) + { + std::cout << "##### paillier_decrypt error: " << get_last_error_msg() << std::endl; + } + BOOST_CHECK(last_call_success()); + auto addResult = m1.add(m2.bn().get()); + std::cout << "###### expectedAddResult: " << std::endl; + BN_print_fp(stdout, addResult.bn().get()); + std::cout << "###### addResult:" << std::endl; + BN_print_fp(stdout, decodeV); + BOOST_CHECK(BN_cmp(addResult.bn().get(), decodeV) == 0); + + /// check m1 - m2 + OutputBuffer subBuffer{cipherResult.data(), cipherResult.size()}; + paillier_sub(&subBuffer, &c1Buffer, &c2Buffer, pk); + if (!last_call_success()) + { + std::cout << "### paillier_sub error for: " << get_last_error_msg() << std::endl; + } + BOOST_CHECK(last_call_success()); + // decrypt and check + InputBuffer subResultBuffer{subBuffer.data, subBuffer.len}; + decodeV = paillier_decrypt(&subResultBuffer, keypair); + if (!last_call_success()) + { + std::cout << "#### paillier decrypt error: " << get_last_error_msg() << std::endl; + } + BOOST_CHECK(last_call_success()); + auto subResult = m1.sub(m2.bn().get()); + std::cout << "###### m1:" << std::endl; + BN_print_fp(stdout, m1.bn().get()); + std::cout << "###### m2:" << std::endl; + BN_print_fp(stdout, m2.bn().get()); + + std::cout << "###### expectedSubResult: " << std::endl; + BN_print_fp(stdout, subResult.bn().get()); + std::cout << "###### subResult:" << std::endl; + BN_print_fp(stdout, decodeV); + BOOST_CHECK(BN_cmp(subResult.bn().get(), decodeV) == 0); + + /// check v * m1 + OutputBuffer mulBuffer{cipherResult.data(), cipherResult.size()}; + paillier_scala_mul(&mulBuffer, v.bn().get(), &c1Buffer, pk); + if (!last_call_success()) + { + std::cout << "### paillier_scala_mul error for: " << get_last_error_msg() << std::endl; + } + BOOST_CHECK(last_call_success()); + InputBuffer mulResultBuffer{mulBuffer.data, mulBuffer.len}; + decodeV = paillier_decrypt(&mulResultBuffer, keypair); + if (!last_call_success()) + { + std::cout << "#### paillier decrypt error: " << get_last_error_msg() << std::endl; + } + BOOST_CHECK(last_call_success()); + auto ctx = createBNContext(); + BigNum mulResult; + v.mul(mulResult.bn().get(), m1.bn().get(), ctx.get()); + std::cout << "###### expectedMulResult: " << std::endl; + BN_print_fp(stdout, mulResult.bn().get()); + std::cout << "###### mulResult:" << std::endl; + BN_print_fp(stdout, decodeV); + BOOST_CHECK(BN_cmp(mulResult.bn().get(), decodeV) == 0); +} +// test paillier encrypt-decrypt +BOOST_AUTO_TEST_CASE(testPaillierEncryptDecrypt) +{ + BigNum value(bcos::utcSteadyTime()); + int keyBits = 2048; + auto keypair = paillier_generate_keypair(keyBits); + testEncryptDecrypt(value.bn().get(), keypair, keyBits); +} +// test paillier ops +BOOST_AUTO_TEST_CASE(testPaillierOps) +{ + int64_t m1 = 12323423434 + rand(); + int64_t m2 = 2342342344 + rand(); + int64_t v = 21334234234; + int keyBits = 2048; + srand(bcos::utcSteadyTime()); + + // positive case + auto keypair = paillier_generate_keypair(keyBits); + testPaillierOpsImpl(BigNum(m1), BigNum(m2), BigNum(v), keypair, keyBits); + + // negative case + m1 = -1234324 - rand(); + testPaillierOpsImpl(BigNum(m1), BigNum(m2), BigNum(v), keypair, keyBits); + + v = -34534 - rand(); + testPaillierOpsImpl(BigNum(m1), BigNum(m2), BigNum(v), keypair, keyBits); +} + +bcos::bytes testEncryptionDecryption(bcos::bytes const& skBytes, int mode, BigNum const& m1) +{ + // encrypt + InputBuffer sk{skBytes.data(), skBytes.size()}; + bcos::bytes cipher(ihc_cipher_bytes(mode)); + std::cout << "##### cipher len: " << cipher.size() << std::endl; + OutputBuffer cipherBuffer{cipher.data(), cipher.size()}; + ihc_encrypt(&cipherBuffer, mode, &sk, m1.bn().get()); + std::cout << "##### cipher1: " << toHex(cipher) << std::endl; + // decrypt + InputBuffer cipherInput{cipher.data(), cipher.size()}; + BigNum resulttmp; + ihc_decrypt(resulttmp.bn().get(), mode, &sk, &cipherInput); + if (!last_call_success()) + { + std::cout << "##### testEncryptionDecryption error: " << get_last_error_msg() << std::endl; + } + BOOST_CHECK(last_call_success()); + // check + std::cout << "#### m1: " << std::endl; + BN_print_fp(stdout, m1.bn().get()); + std::cout << "#### resulttmp: " << std::endl; + BN_print_fp(stdout, resulttmp.bn().get()); + BOOST_CHECK(resulttmp.cmp(m1.bn().get()) == 0); + return cipher; +} +void testIhcImpl(int mode, BigNum const& m1, BigNum const& m2, BigNum const& v) +{ + // generate sk + bcos::bytes skBytes(ihc_key_bytes(mode)); + OutputBuffer skBuffer{skBytes.data(), skBytes.size()}; + ihc_generate_key(&skBuffer, mode); + InputBuffer sk{skBytes.data(), skBytes.size()}; + // c1 + auto c1 = testEncryptionDecryption(skBytes, mode, m1); + // c2 + auto c2 = testEncryptionDecryption(skBytes, mode, m2); + // add test: m1 + m2 + std::cout << "##### testIhcImpl: add case" << std::endl; + InputBuffer cipher1Input{c1.data(), c1.size()}; + InputBuffer cipher2Input{c2.data(), c2.size()}; + bcos::bytes cipherSum(ihc_cipher_bytes(mode)); + OutputBuffer cipherBufferSum{cipherSum.data(), cipherSum.size()}; + ihc_add(&cipherBufferSum, mode, &cipher1Input, &cipher2Input); + std::cout << "##### cipherSum: " << toHex(cipherSum) << std::endl; + // decrypt + InputBuffer cipherSumBuffer{cipherSum.data(), cipherSum.size()}; + BigNum addResult; + ihc_decrypt(addResult.bn().get(), mode, &sk, &cipherSumBuffer); + // check + BigNum expected = m1.add(m2.bn().get()); + BOOST_CHECK(expected.cmp(addResult.bn().get()) == 0); + std::cout << "##### testIhcImpl: add case finish" << std::endl; +} + +bcos::bytes testIhcFloatingEncryptionDecryption( + int mode, bcos::bytes const& skBytes, FloatingPointNumber const& m1) + +{ + InputBuffer sk{skBytes.data(), skBytes.size()}; + // encryption + bcos::bytes cipher(ihc_floating_cipher_bytes(mode)); + OutputBuffer cipherBuffer{cipher.data(), cipher.size()}; + ihc_floating_encrypt(&cipherBuffer, mode, &sk, m1.value.bn().get(), m1.exponent); + std::cout << "cipher: " << toHex(cipher) << std::endl; + InputBuffer cipherInput{cipher.data(), cipher.size()}; + + // decrypt + BigNum decryptedResult; + int16_t decryptedExponent = 0; + + ihc_floating_decrypt(decryptedResult.bn().get(), &decryptedExponent, mode, &sk, &cipherInput); + BOOST_CHECK(m1.exponent == decryptedExponent); + BOOST_CHECK(m1.value.cmp(decryptedResult.bn().get()) == 0); + return cipher; +} + +void testIhcFloatingImpl( + int mode, std::string const& s1, std::string const& s2, std::string const& s3) +{ + std::cout << "testIhcFloatingImpl" << std::endl; + // 生成密钥 + bcos::bytes skBytes(ihc_key_bytes(mode)); + OutputBuffer skBuffer{skBytes.data(), skBytes.size()}; + ihc_generate_key(&skBuffer, mode); + InputBuffer sk{skBytes.data(), skBytes.size()}; + + auto codec = std::make_shared(); + auto m1 = codec->toFloatingPoint(s1); + auto m2 = codec->toFloatingPoint(s2); + auto m3 = codec->toFloatingPoint(s3); + float50 f1(s1); + float50 f2(s2); + float50 f3(s3); + + auto c1 = testIhcFloatingEncryptionDecryption(mode, skBytes, m1); + auto c2 = testIhcFloatingEncryptionDecryption(mode, skBytes, m2); + auto c3 = testIhcFloatingEncryptionDecryption(mode, skBytes, m3); + // add test + std::cout << "#### testIhcFloatingImpl: add test" << std::endl; + bcos::bytes cipherSum(ihc_floating_cipher_bytes(mode)); + OutputBuffer cipherBufferSum{cipherSum.data(), cipherSum.size()}; + InputBuffer c1Buffer{c1.data(), c1.size()}; + InputBuffer c2Buffer{c2.data(), c2.size()}; + ihc_floating_add(&cipherBufferSum, mode, &c1Buffer, &c2Buffer); + InputBuffer cipherSumInput{cipherSum.data(), cipherSum.size()}; + FloatingPointNumber addResult; + ihc_floating_decrypt( + addResult.value.bn().get(), &addResult.exponent, mode, &sk, &cipherSumInput); + std::cout << std::fixed << std::setprecision(15); + std::cout << "#### f1 + f2: " << (f1 + f2) << std::endl; + std::cout << "#### addResult: " << codec->toFloat50(addResult) << std::endl; + float50 epsilon("0.0000000000001"); + BOOST_CHECK(fabs(codec->toFloat50(addResult) - f1 - f2) <= epsilon); + std::cout << "#### testIhcFloatingImpl: add test finished" << std::endl; + + // sub test + std::cout << "#### testIhcFloatingImpl: sub test" << std::endl; + bcos::bytes cipherSub(ihc_floating_cipher_bytes(mode)); + OutputBuffer cipherSubBuffer{cipherSub.data(), cipherSub.size()}; + ihc_floating_sub(&cipherSubBuffer, mode, &c1Buffer, &c2Buffer); + InputBuffer cipherSubInput{cipherSub.data(), cipherSub.size()}; + FloatingPointNumber subResult; + ihc_floating_decrypt( + subResult.value.bn().get(), &subResult.exponent, mode, &sk, &cipherSubInput); + std::cout << std::fixed << std::setprecision(15); + std::cout << "#### f1 - f2: " << (f1 - f2) << std::endl; + std::cout << "#### subResult: " << codec->toFloat50(subResult) << std::endl; + BOOST_CHECK(fabs(codec->toFloat50(subResult) - (f1 - f2)) <= epsilon); + std::cout << "#### testIhcFloatingImpl: sub test finished" << std::endl; + + // scalaMul test + std::cout << "#### testIhcFloatingImpl: scalaMul test" << std::endl; + bcos::bytes cipherMul(ihc_floating_cipher_bytes(mode)); + OutputBuffer cipherMulBuffer{cipherMul.data(), cipherMul.size()}; + ihc_floating_scalaMul(&cipherMulBuffer, mode, m3.value.bn().get(), m3.exponent, &c1Buffer); + InputBuffer cipherMulInput{cipherMul.data(), cipherMul.size()}; + FloatingPointNumber mulResult; + ihc_floating_decrypt( + mulResult.value.bn().get(), &mulResult.exponent, mode, &sk, &cipherMulInput); + BOOST_CHECK(fabs(codec->toFloat50(mulResult) - (f1 * f3)) <= epsilon); + std::cout << "#### testIhcFloatingImpl: scalaMul test finished" << std::endl; +} + +void testIhcItermImpl(int _mode) +{ + // generate sk + bcos::bytes skBytes(ihc_key_bytes(_mode)); + OutputBuffer skBuffer{skBytes.data(), skBytes.size()}; + ihc_generate_key(&skBuffer, _mode); + std::cout << "##### skBuffer: " << toHex(skBytes) << std::endl; + // encrypt + InputBuffer sk{skBytes.data(), skBytes.size()}; + BigNum m1(10000); + bcos::bytes cipherSum(ihc_cipher_bytes(_mode)); + OutputBuffer cipherBufferSum{cipherSum.data(), cipherSum.size()}; + BigNum expected(10000); + ihc_encrypt(&cipherBufferSum, _mode, &sk, m1.bn().get()); + for (int i = 0; i < 100; i++) + { + bcos::bytes cipher(ihc_cipher_bytes(_mode)); + OutputBuffer cipherBuffer{cipher.data(), cipher.size()}; + ihc_encrypt(&cipherBuffer, _mode, &sk, m1.bn().get()); + InputBuffer cipherInput{cipher.data(), cipher.size()}; + InputBuffer cipherSumInput{cipherSum.data(), cipherSum.size()}; + ihc_add(&cipherBufferSum, _mode, &cipherSumInput, &cipherInput); + if (!last_call_success()) + { + std::cout << "#### ihc add error: " << get_last_error_msg() << std::endl; + } + BOOST_CHECK(last_call_success()); + BigNum result; + ihc_decrypt(result.bn().get(), _mode, &sk, &cipherSumInput); + expected = expected.add(m1.bn().get()); + BOOST_CHECK(result.cmp(expected.bn().get()) == 0); + } +} + +BOOST_AUTO_TEST_CASE(testIhcOps) +{ + int64_t m1 = 123213231; + int64_t m2 = 123213231; + int64_t v = 23; + int keyBits = 64; + testIhcImpl((int)Ihc::IhcMode::IHC_128, BigNum(m1), BigNum(m2), BigNum(v)); + // negative case + m1 = -1234324 - rand(); + testIhcImpl((int)Ihc::IhcMode::IHC_128, BigNum(m1), BigNum(m2), BigNum(v)); + v = -34534 - rand(); + testIhcImpl((int)Ihc::IhcMode::IHC_128, BigNum(m1), BigNum(m2), BigNum(v)); + + testIhcItermImpl((int)Ihc::IhcMode::IHC_128); + + std::string s1("-23423423.24534534"); + std::string s2("0.0000234688"); + std::string s3("-1233.002348"); + testIhcFloatingImpl((int)Ihc::IhcMode::IHC_128, s1, s2, s3); +} +BOOST_AUTO_TEST_SUITE_END() +} // namespace ppc::test diff --git a/cpp/wedpr-crypto/sdk/tests/main.cpp b/cpp/wedpr-crypto/sdk/tests/main.cpp new file mode 100644 index 00000000..2c06f9b5 --- /dev/null +++ b/cpp/wedpr-crypto/sdk/tests/main.cpp @@ -0,0 +1,2 @@ +#define BOOST_TEST_MAIN +#include \ No newline at end of file diff --git a/cpp/wedpr-helper/libhelper/CMakeLists.txt b/cpp/wedpr-helper/libhelper/CMakeLists.txt new file mode 100644 index 00000000..43b4a8e1 --- /dev/null +++ b/cpp/wedpr-helper/libhelper/CMakeLists.txt @@ -0,0 +1,8 @@ +file(GLOB_RECURSE SRCS *.cpp) + +include_directories(${CMAKE_BINARY_DIR}) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + +add_library(${HELPER_TARGET} ${SRCS}) +find_package(Boost COMPONENTS filesystem program_options) +target_link_libraries(${HELPER_TARGET} PUBLIC Boost::filesystem Boost::program_options) \ No newline at end of file diff --git a/cpp/wedpr-helper/libhelper/CommandHelper.cpp b/cpp/wedpr-helper/libhelper/CommandHelper.cpp new file mode 100644 index 00000000..b3b8939f --- /dev/null +++ b/cpp/wedpr-helper/libhelper/CommandHelper.cpp @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2022 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 CommandHelper.cpp + * @author: yujiechen + * @date 2022-11-4 + */ +#include "CommandHelper.h" +#include +#include +#include +#include +#include + +using namespace ppc; + +void ppc::printVersion(std::string const& binaryName) +{ + std::cout << binaryName << " Version : " << PPC_PROJECT_VERSION << std::endl; + std::cout << "Build Time : " << PPC_BUILD_TIME << std::endl; + std::cout << "Build Type : " << PPC_BUILD_PLATFORM << "/" << PPC_BUILD_TYPE + << std::endl; + std::cout << "Git Branch : " << PPC_BUILD_BRANCH << std::endl; + std::cout << "Git Commit : " << PPC_COMMIT_HASH << std::endl; +} + +CommandLineParam ppc::initCommandLine(std::string const& binaryName, int argc, const char* argv[]) +{ + boost::program_options::options_description main_options("Usage of PPC"); + main_options.add_options()("help,h", "print help information")("version,v", "version of PPC")( + "config,c", boost::program_options::value(), "./config.ini"); + boost::program_options::variables_map vm; + try + { + boost::program_options::store( + boost::program_options::parse_command_line(argc, argv, main_options), vm); + } + catch (...) + { + printVersion(binaryName); + } + /// help information + if (vm.count("help") || vm.count("h")) + { + std::cout << main_options << std::endl; + exit(0); + } + /// version information + if (vm.count("version") || vm.count("v")) + { + printVersion(binaryName); + exit(0); + } + std::string configPath("./config.ini"); + if (vm.count("config")) + { + configPath = vm["config"].as(); + } + if (vm.count("c")) + { + configPath = vm["c"].as(); + } + // std::ifstream configFile(configPath); + // if (!configFile) + if (!boost::filesystem::exists(configPath)) + { + std::cout << "config \'" << configPath << "\' not found!"; + exit(0); + } + return ppc::CommandLineParam{configPath}; +} diff --git a/cpp/wedpr-helper/libhelper/CommandHelper.h b/cpp/wedpr-helper/libhelper/CommandHelper.h new file mode 100644 index 00000000..73e44286 --- /dev/null +++ b/cpp/wedpr-helper/libhelper/CommandHelper.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2022 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 CommandHelper.h + * @author: yujiechen + * @date 2022-11-4 + */ +#pragma once +#include +#include + +namespace ppc +{ +struct CommandLineParam +{ + std::string configFilePath; +}; +void printVersion(std::string const& binaryName); +CommandLineParam initCommandLine(std::string const& binaryName, int argc, const char* argv[]); +} // namespace ppc \ No newline at end of file diff --git a/cpp/wedpr-helper/libhelper/ExitHandler.h b/cpp/wedpr-helper/libhelper/ExitHandler.h new file mode 100644 index 00000000..93f66195 --- /dev/null +++ b/cpp/wedpr-helper/libhelper/ExitHandler.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2022 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 ExitHandler.cpp + * @author: yujiechen + * @date 2022-11-4 + */ +#pragma once +#include + +namespace ppc +{ +class ExitHandler +{ +public: + void exit() { exitHandler(0); } + static void exitHandler(int signal) + { + std::cout << "[" << bcos::getCurrentDateTime() << "] " + << "exit because receive signal " << signal << std::endl; + ExitHandler::c_shouldExit.store(true); + } + bool shouldExit() const { return ExitHandler::c_shouldExit.load(); } + + static std::atomic_bool c_shouldExit; +}; +std::atomic_bool ExitHandler::c_shouldExit = {false}; + +void setDefaultOrCLocale() +{ +#if __unix__ + if (!std::setlocale(LC_ALL, "")) + { + setenv("LC_ALL", "C", 1); + } +#endif +} +} // namespace ppc \ No newline at end of file diff --git a/cpp/wedpr-helper/ppc-tools/CMakeLists.txt b/cpp/wedpr-helper/ppc-tools/CMakeLists.txt new file mode 100644 index 00000000..5e8810c2 --- /dev/null +++ b/cpp/wedpr-helper/ppc-tools/CMakeLists.txt @@ -0,0 +1,12 @@ +aux_source_directory(src/cuckoo SRCS) +aux_source_directory(src/config SRCS) + +add_library(${TOOLS_TARGET} ${SRCS}) + +target_link_libraries(${TOOLS_TARGET} PUBLIC ${BCOS_UTILITIES_TARGET} ${BOOST_SERIALIZATION} ${CPU_FEATURES_LIB}) + +if (TESTS) + enable_testing() + set(CTEST_OUTPUT_ON_FAILURE TRUE) + add_subdirectory(tests) +endif () diff --git a/cpp/wedpr-helper/ppc-tools/src/codec/CodecUtility.h b/cpp/wedpr-helper/ppc-tools/src/codec/CodecUtility.h new file mode 100644 index 00000000..d8f83201 --- /dev/null +++ b/cpp/wedpr-helper/ppc-tools/src/codec/CodecUtility.h @@ -0,0 +1,110 @@ +/* + * 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 CodecUtility.h + * @author: yujiechen + * @date 2023-8-11 + */ +#pragma once +#include "openssl/bn.h" +#include "ppc-framework/libwrapper/BigNum.h" +#include +#include +#include +namespace ppc +{ +inline bcos::byte* encodeBuffer( + bcos::byte* _pbuffer, bcos::byte* _pend, bcos::bytesConstRef const& _data) +{ + if (_pend - _pbuffer < (int64_t)sizeof(uint16_t)) + { + std::out_of_range("Unenough allocated buffer"); + } + // encode the length of the _data + uint16_t dataNumBigEndianLen = boost::endian::native_to_big((uint16_t)_data.size()); + std::memcpy((void*)_pbuffer, (const void*)&dataNumBigEndianLen, sizeof(uint16_t)); + _pbuffer += sizeof(uint16_t); + if (_pend - _pbuffer <= (int64_t)_data.size()) + { + std::out_of_range("Unenough allocated buffer"); + } + std::memcpy((void*)_pbuffer, _data.data(), _data.size()); + _pbuffer += _data.size(); + return _pbuffer; +} +/// encode bigNum to the given buffer +// Note: _pbuffer will be updated +inline bcos::byte* encodeBigNum( + bcos::byte* _pbuffer, bcos::byte* _pend, ppc::crypto::BigNum const& _value) +{ + // convert the BigNum into bytes + bcos::bytes bigNumData; + _value.toBytes(bigNumData, true); + return encodeBuffer(_pbuffer, _pend, bcos::ref(bigNumData)); +} + +// encode the integer value into buffer +// Note: _pbuffer will be updated +template +inline bcos::byte* encodeInteger(bcos::byte* _pbuffer, bcos::byte* _pend, T const _value) +{ + if (_pend - _pbuffer < (int64_t)sizeof(T)) + { + std::out_of_range("Unenough allocated buffer"); + } + auto nativeValue = boost::endian::native_to_big(_value); + std::memcpy((void*)_pbuffer, (const void*)&nativeValue, sizeof(T)); + _pbuffer += sizeof(T); + return _pbuffer; +} + +// decode the bigNum from _buffer[_offset, _offset + sizeof(T)] +inline uint64_t decodeBuffer(bcos::bytes& _result, bcos::byte const* _buffer, + unsigned int _bufferLen, uint64_t const _offset) +{ + uint64_t offset = _offset; + CHECK_OFFSET_WITH_THROW_EXCEPTION(offset + 2, _bufferLen); + // decode the nativeDataLen + uint16_t nativeDataLen = boost::endian::big_to_native(*((uint16_t*)(_buffer + offset))); + offset += 2; + CHECK_OFFSET_WITH_THROW_EXCEPTION(offset + nativeDataLen, _bufferLen); + // decode the buffer + _result.insert(_result.begin(), (bcos::byte*)_buffer + offset, + (bcos::byte*)_buffer + offset + nativeDataLen); + offset += nativeDataLen; + return offset; +} + +// decode the bigNum from _buffer[_offset, _offset + sizeof(T)] +inline uint64_t decodeBigNum(ppc::crypto::BigNum& _result, bcos::byte const* _buffer, + unsigned int _bufferLen, uint64_t const _offset) +{ + bcos::bytes decodedBuffer; + auto offset = decodeBuffer(decodedBuffer, _buffer, _bufferLen, _offset); + // convert result into BigNum + _result.fromBytes(bcos::ref(decodedBuffer), true); + return offset; +} + +// decode integer from _buffer + _offset, return the new offset +template +inline uint64_t decodeInteger( + T& _result, bcos::byte const* _buffer, unsigned int _bufferLen, uint64_t _offset) +{ + CHECK_OFFSET_WITH_THROW_EXCEPTION(_offset + sizeof(T), _bufferLen); + _result = boost::endian::big_to_native(*((T*)(_buffer + _offset))); + return (_offset + sizeof(T)); +} +} // namespace ppc \ No newline at end of file diff --git a/cpp/wedpr-helper/ppc-tools/src/common/ConcurrentPool.h b/cpp/wedpr-helper/ppc-tools/src/common/ConcurrentPool.h new file mode 100644 index 00000000..3b8d2b90 --- /dev/null +++ b/cpp/wedpr-helper/ppc-tools/src/common/ConcurrentPool.h @@ -0,0 +1,79 @@ +/** + * Copyright (C) 2022 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 ConcurrentPool.h + * @author: zachma + * @date 2023-8-30 + */ + +#pragma once +#include +#include +#include + +namespace ppc::tools +{ +template > +class ConcurrentPool +{ +public: + void insert(_K _key, _V _elem) + { + { + std::lock_guard guard{x_mutex}; + m_pool.insert(std::pair<_K, _V>(_key, _elem)); + } + m_cv.notify_one(); + } + + bool empty() + { + boost::unique_lock lock{x_mutex}; + return m_pool.empty(); + } + + _V pop(_K _key) + { + boost::unique_lock lock{x_mutex}; + m_cv.wait(lock, [this, _key] { return exist(_key); }); + auto v = m_pool[_key]; + m_pool.erase(_key); + return v; + } + + std::pair tryPop(_K _key, int milliseconds) + { + boost::unique_lock lock{x_mutex}; + // in consideration that when the system time has been changed, + // the process maybe stucked in 'wait_for' + auto ret = m_cv.wait_for( + lock, boost::chrono::milliseconds(milliseconds), [this, _key] { return exist(_key); }); + if (!ret) + { + return std::make_pair(false, _V()); + } + auto item = m_pool[_key]; + m_pool.erase(_key); + return std::make_pair(ret, item); + } + + bool exist(_K _key) { return m_pool.find(_key) != m_pool.end(); } + +private: + PoolKV m_pool; + boost::mutex x_mutex; + boost::condition_variable m_cv; +}; +} // namespace ppc::tools \ No newline at end of file diff --git a/cpp/wedpr-helper/ppc-tools/src/common/MemInfo.h b/cpp/wedpr-helper/ppc-tools/src/common/MemInfo.h new file mode 100644 index 00000000..f9cb1f25 --- /dev/null +++ b/cpp/wedpr-helper/ppc-tools/src/common/MemInfo.h @@ -0,0 +1,58 @@ +/** + * 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 MemInfo.h + * @author: shawnhe + * @date 2024-03-04 + */ + +#pragma once + +#ifdef __linux__ +#include +#include +#include +#include + +namespace ppc::tools +{ +inline bool hasAvailableMem(uint32_t _minNeedMemoryGB) +{ + std::ifstream meminfo("/proc/meminfo"); + if (!meminfo.is_open()) + { + std::cerr << "Failed to open /proc/meminfo!" << std::endl; + return -1; + } + + std::string line; + long long availableMem = 0; + + while (std::getline(meminfo, line)) + { + if (line.find("MemAvailable:") != std::string::npos) + { + sscanf(line.c_str(), "MemAvailable: %lld kB", &availableMem); + break; + } + } + + meminfo.close(); + + auto availableMemGB = availableMem / (1024 * 1024); // Convert to GB + return availableMemGB >= _minNeedMemoryGB; +} +} // namespace ppc::tools +#endif diff --git a/cpp/wedpr-helper/ppc-tools/src/common/Progress.h b/cpp/wedpr-helper/ppc-tools/src/common/Progress.h new file mode 100644 index 00000000..37a12ca1 --- /dev/null +++ b/cpp/wedpr-helper/ppc-tools/src/common/Progress.h @@ -0,0 +1,105 @@ +/** + * Copyright (C) 2022 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 Progress.h + * @author: shawnhe + * @date 2023-03-10 + */ + +#pragma once + +#include +#include +#include +#include + +#define TOOLS_PROGRESS_LOG(LEVEL) BCOS_LOG(LEVEL) << LOG_BADGE("PPCTools") + +namespace ppc::tools +{ +using FlagType = std::variant; + + +class Progress +{ +public: + using Ptr = std::shared_ptr; + using ConstPtr = std::shared_ptr; + Progress(bcos::ThreadPool::Ptr _threadPool) : m_threadPool(std::move(_threadPool)){}; + ~Progress() + { + std::unordered_set().swap(m_flags); + MallocExtension::instance()->ReleaseFreeMemory(); + } + + void reset(int64_t _target, std::function&& _finalizeHandler) + { + TOOLS_PROGRESS_LOG(INFO) << LOG_BADGE("reset") << LOG_KV("target", _target); + bcos::WriteGuard l(x_flags); + m_flags.clear(); + m_target = _target; + m_finalizeHandler = std::move(_finalizeHandler); + } + + template + int64_t mark(T&& _flag) + { + TOOLS_PROGRESS_LOG(TRACE) << LOG_BADGE("mark") << LOG_KV("flag", _flag); + int64_t fSize; + std::function callback = nullptr; + { + bcos::WriteGuard l(x_flags); + m_flags.insert(std::forward(_flag)); + fSize = (int64_t)m_flags.size(); + if (fSize == m_target) + { + callback = std::move(m_finalizeHandler); + } + } + + if (callback) + { + TOOLS_PROGRESS_LOG(INFO) + << LOG_BADGE("handle finalizeHandler") << LOG_KV("target", m_target); + + if (m_threadPool) + { + m_threadPool->enqueue([callback] { callback(); }); + } + else + { + callback(); + } + } + + return fSize; + } + + int64_t current() + { + bcos::ReadGuard l(x_flags); + return (int64_t)m_flags.size(); + } + + +private: + bcos::ThreadPool::Ptr m_threadPool; + mutable bcos::SharedMutex x_flags; + std::unordered_set m_flags; + int64_t m_target{-1}; + std::function m_finalizeHandler; +}; + +} // namespace ppc::tools diff --git a/cpp/wedpr-helper/ppc-tools/src/common/TransTools.h b/cpp/wedpr-helper/ppc-tools/src/common/TransTools.h new file mode 100644 index 00000000..75a72f5e --- /dev/null +++ b/cpp/wedpr-helper/ppc-tools/src/common/TransTools.h @@ -0,0 +1,191 @@ +/** + * Copyright (C) 2022 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 TransTools.h + * @author: shawnhe + * @date 2022-11-07 + */ + +#pragma once + +#include +#include + +namespace ppc::tools +{ +template +inline void encodeUnsignedNum(bcos::bytesPointer _buffer, UnsignedT _number) +{ + UnsignedT temp; + if (sizeof(_number) == 2) + { + temp = boost::asio::detail::socket_ops::host_to_network_short(_number); + } + else if (sizeof(_number) == 4) + { + temp = boost::asio::detail::socket_ops::host_to_network_long(_number); + } + else + { + temp = _number; + } + + _buffer->clear(); + _buffer->assign((bcos::byte*)&temp, (bcos::byte*)&temp + sizeof(_number)); +} + +template +inline void encodeUnsignedNum(bcos::byte* _buffer, UnsignedT _number) +{ + UnsignedT temp; + if (sizeof(_number) == 2) + { + temp = boost::asio::detail::socket_ops::host_to_network_short(_number); + } + else if (sizeof(_number) == 4) + { + temp = boost::asio::detail::socket_ops::host_to_network_long(_number); + } + else + { + temp = _number; + } + + memcpy(_buffer, (bcos::byte*)&temp, sizeof(_number)); +} + +template +inline void encodeUnsignedNum(std::string& _res, UnsignedT _number) +{ + _res = ""; + UnsignedT temp; + auto _buffer = std::make_shared(); + if (sizeof(_number) == 2) + { + temp = boost::asio::detail::socket_ops::host_to_network_short(_number); + } + else if (sizeof(_number) == 4) + { + temp = boost::asio::detail::socket_ops::host_to_network_long(_number); + } + else + { + temp = _number; + } + + _buffer->clear(); + _buffer->assign((bcos::byte*)&temp, (bcos::byte*)&temp + sizeof(_number)); + _res.assign(_buffer->begin(), _buffer->end()); +} + +template +inline void decodeUnsignedNum(UnsignedT& _number, const std::string& _restr) +{ + auto _buffer = std::make_shared(bcos::bytes(_restr.begin(), _restr.end())); + if (sizeof(_number) == 1) + { + _number = *((uint8_t*)_buffer->data()); + } + else if (sizeof(_number) == 2) + { + _number = + boost::asio::detail::socket_ops::network_to_host_short(*((uint16_t*)_buffer->data())); + } + else if (sizeof(_number) == 4) + { + _number = + boost::asio::detail::socket_ops::network_to_host_long(*((uint32_t*)_buffer->data())); + } + else + { + _number = UnsignedT(*((UnsignedT*)_buffer->data())); + } +} + +template +inline void decodeUnsignedNum(UnsignedT& _number, bcos::bytesPointer _buffer) +{ + if (sizeof(_number) == 1) + { + _number = *((uint8_t*)_buffer->data()); + } + else if (sizeof(_number) == 2) + { + _number = + boost::asio::detail::socket_ops::network_to_host_short(*((uint16_t*)_buffer->data())); + } + else if (sizeof(_number) == 4) + { + _number = + boost::asio::detail::socket_ops::network_to_host_long(*((uint32_t*)_buffer->data())); + } + else + { + _number = UnsignedT(*((UnsignedT*)_buffer->data())); + } +} + +template +inline void decodeUnsignedNum(UnsignedT& _number, bcos::byte* _buffer) +{ + if (sizeof(_number) == 1) + { + _number = *((uint8_t*)_buffer); + } + else if (sizeof(_number) == 2) + { + _number = boost::asio::detail::socket_ops::network_to_host_short(*((uint16_t*)_buffer)); + } + else if (sizeof(_number) == 4) + { + _number = boost::asio::detail::socket_ops::network_to_host_long(*((uint32_t*)_buffer)); + } + else + { + _number = UnsignedT(*((UnsignedT*)_buffer)); + } +} + +template +T toBigEndian(T value) +{ + T result = 0; + uint8_t* resultBytes = reinterpret_cast(&result); + uint8_t* valueBytes = reinterpret_cast(&value); + + for (size_t i = 0; i < sizeof(T); ++i) + { + resultBytes[i] = valueBytes[sizeof(T) - 1 - i]; + } + + return result; +} + +template +T fromBigEndian(T value) +{ + T result = 0; + uint8_t* resultBytes = reinterpret_cast(&result); + uint8_t* valueBytes = reinterpret_cast(&value); + + for (size_t i = 0; i < sizeof(T); ++i) + { + resultBytes[i] = valueBytes[sizeof(T) - 1 - i]; + } + + return result; +} + +} // namespace ppc::tools diff --git a/cpp/wedpr-helper/ppc-tools/src/config/CEMConfig.h b/cpp/wedpr-helper/ppc-tools/src/config/CEMConfig.h new file mode 100644 index 00000000..69d24ed3 --- /dev/null +++ b/cpp/wedpr-helper/ppc-tools/src/config/CEMConfig.h @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2022 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 StorageConfig.h + * @author: yujiechen + * @date 2022-11-4 + */ +#pragma once +#include +#include + +namespace ppc::tools +{ +struct CEMConfig +{ + std::string datasetFilePath; + std::string datasetHDFSPath; + std::string ciphertextSuffix; + uint64_t readPerBatchLines; +}; +} // namespace ppc::tools \ No newline at end of file diff --git a/cpp/wedpr-helper/ppc-tools/src/config/Common.h b/cpp/wedpr-helper/ppc-tools/src/config/Common.h new file mode 100644 index 00000000..3a242820 --- /dev/null +++ b/cpp/wedpr-helper/ppc-tools/src/config/Common.h @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2022 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 Common.h + * @author: yujiechen + * @date 2022-11-4 + */ +#pragma once +#include "ppc-framework/Common.h" +#include + +#define MAXPORT 65535 +#define PPCConfig_LOG(LEVEL) BCOS_LOG(LEVEL) << LOG_BADGE("PPCConfig") + +namespace ppc::tools +{ +DERIVE_PPC_EXCEPTION(InvalidConfig); +} \ No newline at end of file diff --git a/cpp/wedpr-helper/ppc-tools/src/config/MPCConfig.h b/cpp/wedpr-helper/ppc-tools/src/config/MPCConfig.h new file mode 100644 index 00000000..c4e9418b --- /dev/null +++ b/cpp/wedpr-helper/ppc-tools/src/config/MPCConfig.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2022 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 MPCConfig.h + * @author: yujiechen + * @date 2022-11-4 + */ +#pragma once +#include +#include + +namespace ppc::tools +{ +struct MPCConfig +{ + std::string jobPath; + std::string mpcRootPath; + std::string mpcRootPathNoGateway; + uint64_t readPerBatchLines; + int threadPoolSize; + + std::string spdzConnectedIP; + int spdzConnectedPort; +}; +} // namespace ppc::tools \ No newline at end of file diff --git a/cpp/wedpr-helper/ppc-tools/src/config/NetworkConfig.h b/cpp/wedpr-helper/ppc-tools/src/config/NetworkConfig.h new file mode 100644 index 00000000..c0e513fb --- /dev/null +++ b/cpp/wedpr-helper/ppc-tools/src/config/NetworkConfig.h @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2022 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 NetworkConfig.h + * @author: yujiechen + * @date 2022-11-4 + */ +#pragma once + +namespace ppc::tools +{ +struct NetworkConfig +{ + constexpr static int DefaultRpcListenPort = 10200; + + // the configuration for rpc + std::string listenIp; + int listenPort; + uint32_t threadPoolSize; + std::string token; + bool disableSsl; + + bool enableSM; + // the gateway protocol + int protocol; // websocket or http + std::string url; + // the rpc cert path + std::string certPath; + // the cert info for non-sm + std::string caCertPath; + std::string sslKeyPath; + std::string sslCertPath; + // the cert info for sm + std::string smCaCertPath; + std::string smSslKeyPath; + std::string smSslCertPath; + std::string smEnSslKeyPath; + std::string smEnSslCertPath; + + constexpr static std::string_view CA_CERT_NAME = "ca.crt"; + constexpr static std::string_view SM_CA_CERT_NAME = "sm_ca.crt"; + + constexpr static std::string_view SSL_CERT_NAME = "ssl.crt"; + constexpr static std::string_view SM_SSL_CERT_NAME = "sm_ssl.crt"; + + constexpr static std::string_view SSL_KEY_NAME = "ssl.key"; + constexpr static std::string_view SM_SSL_KEY_NAME = "sm_ssl.key"; + + constexpr static std::string_view SM_SSL_EN_CERT_NAME = "sm_enssl.crt"; + constexpr static std::string_view SM_SSL_EN_KEY_NAME = "sm_enssl.key"; + + constexpr static int PROTOCOL_WEBSOCKET = 0; + constexpr static int PROTOCOL_HTTP = 1; +}; +} // namespace ppc::tools \ No newline at end of file diff --git a/cpp/wedpr-helper/ppc-tools/src/config/PPCConfig.cpp b/cpp/wedpr-helper/ppc-tools/src/config/PPCConfig.cpp new file mode 100644 index 00000000..51aef29f --- /dev/null +++ b/cpp/wedpr-helper/ppc-tools/src/config/PPCConfig.cpp @@ -0,0 +1,680 @@ +/* + * Copyright (C) 2022 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 PPCConfig.cpp + * @author: yujiechen + * @date 2022-11-4 + */ +#include "PPCConfig.h" +#include +#include +#include +#include +#include + +using namespace ppc::tools; +using namespace ppc::front; +using namespace ppc::protocol; +using namespace ppc::storage; +using namespace bcos; + +void PPCConfig::loadGatewayConfig(boost::property_tree::ptree const& _pt, bool requireTransport) +{ + // load the network config + PPCConfig_LOG(INFO) << LOG_DESC("loadGatewayConfig: load the network config") + << LOG_KV("requireTransport", requireTransport); + // gateway default enable-ssl + loadNetworkConfig( + m_gatewayConfig.networkConfig, _pt, "gateway", NetworkConfig::DefaultRpcListenPort, false); + PPCConfig_LOG(INFO) << LOG_DESC("loadGatewayConfig: load the network config success"); + + m_gatewayConfig.nodePath = _pt.get("gateway.nodes_path", "./"); + m_gatewayConfig.nodeFileName = _pt.get("gateway.nodes_file", "nodes.json"); + + m_gatewayConfig.reconnectTime = _pt.get("gateway.reconnect_time", 10000); + m_gatewayConfig.unreachableDistance = _pt.get("gateway.unreachable_distance", 10); + if (m_gatewayConfig.unreachableDistance < GatewayConfig::MinUnreachableDistance) + { + BOOST_THROW_EXCEPTION(InvalidConfig() << bcos::errinfo_comment( + "Invalid unreachable_distance, must no smaller than " + + std::to_string(GatewayConfig::MinUnreachableDistance))); + } + // load the maxAllowedMsgSize, in MBytes + m_gatewayConfig.maxAllowedMsgSize = + _pt.get("gateway.max_allow_msg_size", GatewayConfig::DefaultMaxAllowedMsgSize) * + 1024 * 1024; + if (m_gatewayConfig.maxAllowedMsgSize < GatewayConfig::MinMsgSize || + m_gatewayConfig.maxAllowedMsgSize >= GatewayConfig::MaxMsgSize) + { + BOOST_THROW_EXCEPTION( + InvalidConfig() << errinfo_comment( + "the gateway.max_allow_msg_size must be smaller than " + + std::to_string(GatewayConfig::MinMsgSize) + "Bytes and no larger than" + + std::to_string(GatewayConfig::MaxMsgSize) + "Bytes, recommend to 100MBytes")); + } + // load the holdingMessageMinutes, in minutes + m_holdingMessageMinutes = loadHoldingMessageMinutes(_pt, "gateway.holding_msg_minutes"); + // load seqSyncPeriod + m_seqSyncPeriod = _pt.get("gateway.seq_sync_period_ms", 5000); + if (m_seqSyncPeriod < 3000) + { + BOOST_THROW_EXCEPTION( + InvalidConfig() << errinfo_comment( + "The value of gateway.seq_sync_period_ms must no little than 3s")); + } + // only need load grpc config when requireTransport + if (requireTransport) + { + PPCConfig_LOG(INFO) << LOG_DESC("loadGatewayConfig: load grpc config"); + // load the grpcConfig + m_grpcConfig = loadGrpcConfig("transport", _pt); + // load the GrpcServerConfig + loadEndpointConfig( + m_gatewayConfig.grpcServerConfig->mutableEndPoint(), false, "transport", _pt); + } + // the agencyID + m_agencyID = _pt.get("agency.id", ""); + if (m_agencyID.empty()) + { + BOOST_THROW_EXCEPTION(InvalidConfig() << errinfo_comment("Must set agency.id")); + } + PPCConfig_LOG(INFO) << LOG_DESC("loadGatewayConfig") + << LOG_KV("maxAllowedMsgSize", m_gatewayConfig.maxAllowedMsgSize) + << LOG_KV("reconnectTime", m_gatewayConfig.reconnectTime) + << LOG_KV("holdingMessageMinutes", m_holdingMessageMinutes); +} + +void PPCConfig::loadEndpointConfig(EndPoint& endPoint, bool requireHostIp, + std::string const& sectionName, boost::property_tree::ptree const& pt) +{ + // the host ip + auto hostIp = pt.get(sectionName + ".host_ip", "127.0.0.1"); + if (requireHostIp && hostIp.empty()) + { + BOOST_THROW_EXCEPTION( + InvalidConfig() << errinfo_comment("Must specify the " + sectionName + ".host_ip!")); + } + endPoint.setHost(hostIp); + // the listen ip + auto listenIp = pt.get(sectionName + ".listen_ip", "0.0.0.0"); + if (listenIp.empty()) + { + BOOST_THROW_EXCEPTION( + InvalidConfig() << errinfo_comment("Must specify the " + sectionName + ".listen_ip!")); + } + endPoint.setListenIp(listenIp); + // the listen port + auto listenPort = pt.get(sectionName + ".listen_port", 18000); + checkPort(sectionName + ".listen_port", listenPort); + endPoint.setPort(listenPort); +} + +void PPCConfig::loadFrontConfig(bool requireTransport, + FrontConfigBuilder::Ptr const& frontConfigBuilder, boost::property_tree::ptree const& pt) +{ + if (m_frontConfig == nullptr) + { + m_frontConfig = frontConfigBuilder->build(); + } + // the thread_count + auto threadCount = pt.get("transport.thread_count", 4); + if (threadCount == 0) + { + threadCount = 2; + } + // TODO: load from the pem file + auto nodeID = pt.get("transport.nodeid", ""); + if (nodeID.empty()) + { + BOOST_THROW_EXCEPTION( + InvalidConfig() << errinfo_comment("Must specify the transport.nodeid!")); + } + m_frontConfig->setNodeID(nodeID); + m_frontConfig->setThreadPoolSize(threadCount); + if (!requireTransport) + { + PPCConfig_LOG(INFO) << LOG_DESC("loadFrontConfig and not require the transport") + << printFrontDesc(m_frontConfig); + return; + } + + loadEndpointConfig(m_frontConfig->mutableSelfEndPoint(), true, "transport", pt); + // the gateway targets + auto gatewayTargets = pt.get("transport.gateway_target", ""); + if (gatewayTargets.empty()) + { + BOOST_THROW_EXCEPTION( + InvalidConfig() << errinfo_comment("Must specify the transport.gateway_target!")); + } + m_frontConfig->setGatewayGrpcTarget(gatewayTargets); + // the components + auto components = pt.get("transport.components", ""); + boost::split(m_frontConfig->mutableComponents(), components, boost::is_any_of(",")); + PPCConfig_LOG(INFO) << LOG_DESC("loadFrontConfig") << printFrontDesc(m_frontConfig); +} + +void PPCConfig::setPrivateKey(bcos::bytes const& _privateKey) +{ + m_privateKey = _privateKey; +} + +GrpcConfig::Ptr PPCConfig::loadGrpcConfig( + std::string const& sectionName, boost::property_tree::ptree const& pt) +{ + // the load balance config + auto loadBalancePolicy = + pt.get(sectionName + ".load_balance_policy", "round_robin"); + auto grpcConfig = std::make_shared(); + if (!loadBalancePolicy.empty()) + { + grpcConfig->setLoadBalancePolicy(loadBalancePolicy); + } + PPCConfig_LOG(INFO) << LOG_DESC("loadGrpcConfig") << LOG_KV("section", sectionName) + << LOG_KV("loadBalancePolicy", grpcConfig->loadBalancePolicy()); + return grpcConfig; +} + +int PPCConfig::loadHoldingMessageMinutes( + const boost::property_tree::ptree& _pt, std::string const& _section) +{ + auto holdingMessageMinutes = _pt.get(_section, 30); + if (holdingMessageMinutes < 0) + { + BOOST_THROW_EXCEPTION( + InvalidConfig() << errinfo_comment("The value of " + _section + " must positive")); + } + return holdingMessageMinutes; +} + +void PPCConfig::loadCachedStorageConfig( + CacheStorageConfig& _redisConfig, const boost::property_tree::ptree& _pt) +{ + _redisConfig.type = ppc::protocol::CacheType(_pt.get("cache.type", 0)); + if (_redisConfig.type > ppc::protocol::CacheType::Redis) + { + BOOST_THROW_EXCEPTION(InvalidConfig() << bcos::errinfo_comment("unsupported cache type")); + } + + _redisConfig.proxy = _pt.get("cache.proxy", ""); + _redisConfig.obServer = _pt.get("cache.obServer", ""); + _redisConfig.cluster = _pt.get("cache.cluster", ""); + _redisConfig.user = _pt.get("cache.user", ""); + _redisConfig.host = _pt.get("cache.host", "127.0.0.1"); + _redisConfig.port = _pt.get("cache.port", 6379); + _redisConfig.password = _pt.get("cache.password", ""); + _redisConfig.database = _pt.get("cache.database", 1); + _redisConfig.pool = _pt.get("cache.pool_size", 16); + + // the connection_timeout + _redisConfig.connectionTimeout = _pt.get("cache.connection_timeout", 500); + // the socket_timeout + _redisConfig.socketTimeout = _pt.get("cache.socket_timeout", 500); + PPCConfig_LOG(INFO) << LOG_DESC("initRedisConfig") << LOG_KV("type", (int)_redisConfig.type) + << LOG_KV("proxy", _redisConfig.proxy) + << LOG_KV("obServer", _redisConfig.obServer) + << LOG_KV("cluster", _redisConfig.cluster) + << LOG_KV("user", _redisConfig.user) << LOG_KV("host", _redisConfig.host) + << LOG_KV("port", _redisConfig.port) + << LOG_KV("password", _redisConfig.password) + << LOG_KV("database", _redisConfig.database) + << LOG_KV("pool", _redisConfig.pool) + << LOG_KV("connectionTimeout", _redisConfig.connectionTimeout) + << LOG_KV("socketTimeout", _redisConfig.socketTimeout); +} + + +void PPCConfig::loadNetworkConfig(NetworkConfig& _config, boost::property_tree::ptree const& _pt, + std::string const& _sectionName, int _defaultListenPort, bool _defaultDisableSSl) +{ + // the rpcListenIp + _config.listenIp = _pt.get(_sectionName + ".listen_ip", "0.0.0.0"); + // the rpcListenPort + _config.listenPort = _pt.get(_sectionName + ".listen_port", _defaultListenPort); + checkPort("rpc.listen_port", _config.listenPort); + // the rpcThreadPoolSize + _config.threadPoolSize = _pt.get(_sectionName + ".thread_count", + static_cast(std::thread::hardware_concurrency() * 0.75)); + _config.token = _pt.get(_sectionName + ".token", "ppcs_psi_apikey"); + // disable rpc-ssl or not + _config.disableSsl = _pt.get(_sectionName + ".disable_ssl", _defaultDisableSSl); + _config.protocol = _pt.get(_sectionName + ".protocol", NetworkConfig::PROTOCOL_WEBSOCKET); + if (_config.protocol == NetworkConfig::PROTOCOL_HTTP) + { + _config.url = _pt.get(_sectionName + ".url", "/api/v1/interconn/invoke"); + } + PPCConfig_LOG(INFO) << LOG_BADGE("loadNetworkConfig") << LOG_KV("section", _sectionName) + << LOG_KV("listenIp", _config.listenIp) + << LOG_KV("listenPort", _config.listenPort) + << LOG_KV("threadCount", _config.threadPoolSize) + << LOG_KV("disableSsl", _config.disableSsl) + << LOG_KV("protocol", _config.protocol) << LOG_KV("url", _config.url); + // no need to load the certificate when disable-ssl + if (_config.disableSsl) + { + return; + } + // enable sm-rpc or not + _config.enableSM = _pt.get(_sectionName + ".sm_ssl", false); + + // the cert-path + _config.certPath = _pt.get("cert.cert_path", "conf"); + + PPCConfig_LOG(INFO) << LOG_BADGE("loadNetworkConfig") << LOG_KV("section", _sectionName) + << LOG_KV("certPath", _config.certPath); + + checkFileExists(_config.certPath, true); + // load the sm-cert + if (_config.enableSM) + { + _config.smCaCertPath = _config.certPath + "/" + std::string(NetworkConfig::SM_CA_CERT_NAME); + checkFileExists(_config.smCaCertPath, false); + + _config.smSslCertPath = + _config.certPath + "/" + std::string(NetworkConfig::SM_SSL_CERT_NAME); + checkFileExists(_config.smSslCertPath, false); + + _config.smEnSslCertPath = + _config.certPath + "/" + std::string(NetworkConfig::SM_SSL_EN_CERT_NAME); + checkFileExists(_config.smEnSslCertPath, false); + + _config.smSslKeyPath = _config.certPath + "/" + std::string(NetworkConfig::SM_SSL_KEY_NAME); + checkFileExists(_config.smSslKeyPath, false); + + _config.smEnSslKeyPath = + _config.certPath + "/" + std::string(NetworkConfig::SM_SSL_EN_KEY_NAME); + checkFileExists(_config.smEnSslKeyPath, false); + PPCConfig_LOG(INFO) << LOG_BADGE("loadNetworkConfig") << LOG_DESC("load sm cert") + << LOG_KV("section", _sectionName) + << LOG_KV("caCert", _config.smCaCertPath) + << LOG_KV("sslCert", _config.smSslCertPath) + << LOG_KV("enSslCert", _config.smEnSslCertPath); + return; + } + // load the non-sm-cert + _config.caCertPath = _config.certPath + "/" + std::string(NetworkConfig::CA_CERT_NAME); + checkFileExists(_config.caCertPath, false); + + _config.sslCertPath = _config.certPath + "/" + std::string(NetworkConfig::SSL_CERT_NAME); + checkFileExists(_config.sslCertPath, false); + + _config.sslKeyPath = _config.certPath + "/" + std::string(NetworkConfig::SSL_KEY_NAME); + checkFileExists(_config.sslKeyPath, false); + + PPCConfig_LOG(INFO) << LOG_BADGE("loadNetworkConfig") << LOG_DESC("load non-sm cert") + << LOG_KV("section", _sectionName) << LOG_KV("caCert", _config.caCertPath) + << LOG_KV("sslCert", _config.sslCertPath); +} + +void PPCConfig::checkPort(std::string const& _sectionName, int _port) +{ + if (_port <= 0 || _port > MAXPORT) + { + BOOST_THROW_EXCEPTION(InvalidConfig() << errinfo_comment( + "The " + _sectionName + " must positive and no larger than" + + std::to_string(MAXPORT))); + } +} + +void PPCConfig::checkFileExists(std::string const& _filePath, bool _dir) +{ + // check for the dir + if (_dir) + { + if (!boost::filesystem::is_directory(boost::filesystem::path(_filePath))) + { + BOOST_THROW_EXCEPTION(InvalidConfig() << errinfo_comment( + "Please check the existence of directory " + _filePath)); + } + return; + } + // check for the file + if (!boost::filesystem::exists(boost::filesystem::path(_filePath))) + { + BOOST_THROW_EXCEPTION( + InvalidConfig() << errinfo_comment("Please check the existence of file " + _filePath)); + } +} + +void PPCConfig::loadRA2018Config(boost::property_tree::ptree const& _pt) +{ + m_disableRA2018 = _pt.get("agency.disable_ra2018", false); + if (m_disableRA2018) + { + PPCConfig_LOG(INFO) << LOG_DESC("The ra2018-psi has been disabled!"); + return; + } + // load the database + m_ra2018PSIConfig.dbName = _pt.get("ra2018psi.database", "ra2018"); + ///// load the cuckoo-filter-option + auto cuckooFilterOption = std::make_shared(); + // capacity, unit with MBytes + auto capacity = _pt.get( + "ra2018psi.cuckoofilter_capacity", RA2018Config::DefaultCuckooFilterCapacity); + if (capacity == 0) + { + BOOST_THROW_EXCEPTION(InvalidConfig() << errinfo_comment( + "the ra2018psi.cuckoofilter_capacity must be larger than 0")); + } + cuckooFilterOption->capacity = capacity * 1024 * 1024; + // tagBits + cuckooFilterOption->tagBits = _pt.get( + "ra2018psi.cuckoofilter_tagBits", RA2018Config::DefaultCuckooFilterTagSize); + if (cuckooFilterOption->tagBits == 0 || cuckooFilterOption->tagBits % 8 != 0 || + cuckooFilterOption->tagBits > 64) + { + BOOST_THROW_EXCEPTION(InvalidConfig() << errinfo_comment( + "the ra2018psi.cuckoofilter_tagBits must be 8/16/32/64")); + } + // bucket-size + cuckooFilterOption->tagNumPerBucket = + _pt.get("ra2018psi.cuckoofilter_buckets_num", RA2018Config::DefaultBucketSize); + if (cuckooFilterOption->tagNumPerBucket == 0) + { + BOOST_THROW_EXCEPTION( + InvalidConfig() << errinfo_comment( + "the ra2018psi.cuckoofilter_buckets_num must be larger than 0, recommend to " + + std::to_string(RA2018Config::DefaultBucketSize))); + } + // maxKickOutCount + cuckooFilterOption->maxKickOutCount = _pt.get( + "ra2018psi.cuckoofilter_max_kick_out_count", RA2018Config::DefaultMaxKickoutCount); + if (cuckooFilterOption->maxKickOutCount == 0) + { + BOOST_THROW_EXCEPTION(InvalidConfig() << errinfo_comment( + "the ra2018psi.cuckoofilter_max_kick_out_count must be larger " + "than 0, recommend to " + + std::to_string(RA2018Config::DefaultMaxKickoutCount))); + } + cuckooFilterOption->trashBucketSize = + _pt.get("ra2018psi.trash_bucket_size", RA2018Config::DefaultTrashBucketSize); + if (cuckooFilterOption->trashBucketSize == 0) + { + BOOST_THROW_EXCEPTION( + InvalidConfig() << errinfo_comment( + "the ra2018psi.trash_bucket_size must be larger than 0, recommend to " + + boost::lexical_cast(RA2018Config::DefaultTrashBucketSize))); + } + m_ra2018PSIConfig.cuckooFilterOption = std::move(cuckooFilterOption); + ///// load the cuckoo-filter-cache-size + auto cacheSize = _pt.get( + "ra2018psi.cuckoofilter_cache_size", RA2018Config::DefaultCuckooFilterCacheSize); + if (cacheSize == 0) + { + BOOST_THROW_EXCEPTION(InvalidConfig() << errinfo_comment( + "the ra2018psi.cuckoofilter_cache_size must be larger than 0" + + std::to_string(RA2018Config::DefaultCuckooFilterCacheSize))); + } + m_ra2018PSIConfig.cuckooFilterCacheSize = cacheSize * 1024 * 1024; + + ///// load the psi-cache-size + cacheSize = _pt.get("ra2018psi.psi_cache_size", RA2018Config::DefaultCacheSize); + if (cacheSize == 0) + { + BOOST_THROW_EXCEPTION( + InvalidConfig() << errinfo_comment( + "the ra2018psi.psi_cache_size must be larger than 0, recommend to " + + std::to_string(RA2018Config::DefaultCacheSize))); + } + m_ra2018PSIConfig.cacheSize = cacheSize * 1024 * 1024; + ///// load the psi-data-batch-size + auto dataBatchSize = _pt.get("ra2018psi.data_batch_size", DefaultDataBatchSize); + m_ra2018PSIConfig.dataBatchSize = getDataBatchSize("ra2018psi.data_batch_size", dataBatchSize); + + m_ra2018PSIConfig.useHDFS = _pt.get("ra2018psi.use_hdfs", false); + // Note: the cuckooFilterOption has been moved, should not be accessed here + PPCConfig_LOG(INFO) << LOG_DESC("loadRA2018Config") + << LOG_KV("database", m_ra2018PSIConfig.dbName) + << printCuckooFilterOption(m_ra2018PSIConfig.cuckooFilterOption) + << LOG_KV("cuckooFilterCacheSize", m_ra2018PSIConfig.cuckooFilterCacheSize) + << LOG_KV("psiCacheSize", m_ra2018PSIConfig.cacheSize) + << LOG_KV("dataBatchSize", m_ra2018PSIConfig.dataBatchSize) + << LOG_KV("useHDFS", m_ra2018PSIConfig.useHDFS); +} + +// load the ecdh-psi config +void PPCConfig::loadEcdhPSIConfig(boost::property_tree::ptree const& _pt) +{ + auto dataBatchSize = _pt.get("ecdh-psi.data_batch_size", DefaultDataBatchSize); + m_ecdhPSIConfig.dataBatchSize = getDataBatchSize("ecdh-psi.data_batch_size", dataBatchSize); + PPCConfig_LOG(INFO) << LOG_DESC("loadEcdhPSIConfig") + << LOG_KV("dataBatchSize", m_ecdhPSIConfig.dataBatchSize); +} + +void PPCConfig::loadCM2020PSIConfig(boost::property_tree::ptree const& _pt) +{ + m_cm2020Config.parallelism = _pt.get("cm2020-psi.parallelism", DefaultParallelism); + PPCConfig_LOG(INFO) << LOG_DESC("loadCM2020PSIConfig") + << LOG_KV("parallelism", m_cm2020Config.parallelism); +} + +void PPCConfig::loadEcdhMultiPSIConfig(boost::property_tree::ptree const& _pt) +{ + auto dataBatchSize = _pt.get("ecdh-multi-psi.data_batch_size", DefaultDataBatchSize); + m_ecdhMultiPSIConfig.dataBatchSize = + getDataBatchSize("ecdh-multi-psi.data_batch_size", dataBatchSize); + PPCConfig_LOG(INFO) << LOG_DESC("loadEcdhMultiPSIConfig") + << LOG_KV("dataBatchSize", m_ecdhMultiPSIConfig.dataBatchSize); +} + +void PPCConfig::loadEcdhConnPSIConfig(boost::property_tree::ptree const& _pt) +{ + m_ecdhConnPSIConfig.rank = _pt.get("ecdh-conn-psi.rank", 0); + m_ecdhConnPSIConfig.algos = _pt.get("ecdh-conn-psi.algos", 1); + m_ecdhConnPSIConfig.protocol_families = _pt.get("ecdh-conn-psi.protocol_families", 1); + m_ecdhConnPSIConfig.curve = _pt.get("ecdh-conn-psi.curve", 2); + m_ecdhConnPSIConfig.hashtype = _pt.get("ecdh-conn-psi.hashtype", 11); + m_ecdhConnPSIConfig.hash2curve = _pt.get("ecdh-conn-psi.hash2curve", 2); + auto dataBatchSize = _pt.get("ecdh-conn-psi.data_batch_size", DefaultDataBatchSize); + m_ecdhConnPSIConfig.dataBatchSize = + getDataBatchSize("ecdh-conn-psi.data_batch_size", dataBatchSize); + PPCConfig_LOG(INFO) << LOG_DESC("loadEcdhConnPSIConfig Success"); +} + +int64_t PPCConfig::getDataBatchSize(std::string const& _section, int64_t _dataBatchSize) +{ + int64_t dataBatchSize = _dataBatchSize; + if (dataBatchSize != -1 && dataBatchSize <= 0) + { + BOOST_THROW_EXCEPTION( + InvalidConfig() << errinfo_comment("the " + _section + + " must be larger than 0 or equal to -1(load all " + "data into memory at-once) recommend to " + + std::to_string(DefaultDataBatchSize))); + } + // in-case of the data over the max-allowed-message size + int64_t maxNetworkItems = (GatewayConfig::MaxMsgSize - 1024 * 1024) / 32; + if (dataBatchSize == -1 || dataBatchSize > maxNetworkItems) + { + dataBatchSize = std::min((uint64_t)maxNetworkItems, (uint64_t)INT_MAX); + } + PPCConfig_LOG(INFO) << LOG_DESC("getDataBatchSize") << LOG_KV("section", _section) + << LOG_KV("maxNetworkItems", maxNetworkItems) + << LOG_KV("dataBatchSize", dataBatchSize); + return dataBatchSize; +} + +void PPCConfig::loadCommonNodeConfig(boost::property_tree::ptree const& _pt) +{ + m_agencyID = _pt.get("agency.id", ""); + if (m_agencyID.empty()) + { + BOOST_THROW_EXCEPTION(InvalidConfig() << errinfo_comment("Must set agency.id")); + } + if (m_privateKeyPath.empty()) + { + m_privateKeyPath = + _pt.get("agency.private_key_path", "conf/" + std::string(NODE_PEM_NAME)); + checkFileExists(m_privateKeyPath, false); + } + // load the crypto config + m_smCrypto = _pt.get("crypto.sm_crypto", false); + + m_dataLocation = _pt.get("agency.data_location", "data"); + + m_taskTimeoutMinutes = _pt.get("agency.task_timeout_minutes", 180); + + m_threadPoolSize = _pt.get( + "agency.thread_count", static_cast(std::thread::hardware_concurrency() * 0.75)); + + m_minNeededMemoryGB = _pt.get("agency.min_needed_memory", 1); + if (m_minNeededMemoryGB == 0) + { + BOOST_THROW_EXCEPTION(InvalidConfig() << bcos::errinfo_comment( + "Invalid agency.min_needed_memory, must larger than 0")); + } + PPCConfig_LOG(INFO) << LOG_DESC("loadCommonNodeConfig success") + << LOG_KV("agencyID", m_agencyID) << LOG_KV("dataLocation", m_dataLocation) + << LOG_KV("smCrypto", m_smCrypto) + << LOG_KV("taskTimeoutMinutes", m_taskTimeoutMinutes) + << LOG_KV("threadPoolSize", m_threadPoolSize) + << LOG_KV("minNeededMemoryGB", m_minNeededMemoryGB); +} + +void PPCConfig::loadHDFSConfig(boost::property_tree::ptree const& _pt) +{ + SQLConnectionOption opt; + opt.host = _pt.get("storage.host", "127.0.0.1"); + // checkNonEmptyField("storage.host", opt.host); + + opt.port = _pt.get("storage.port", 3306); + + opt.user = _pt.get("storage.user", "ppcs"); + // checkNonEmptyField("storage.user", opt.user); + + opt.password = _pt.get("storage.password", "ppcs"); + // checkNonEmptyField("storage.password", opt.password); + + opt.database = _pt.get("storage.database", ""); + // checkNonEmptyField("storage.database", opt.database); + + m_storageConfig.sqlConnectionOpt = std::make_shared(opt); + PPCConfig_LOG(INFO) << LOG_DESC("loadStorageConfig: load sql connection option success") + << m_storageConfig.sqlConnectionOpt->desc(); + + auto option = std::make_shared(); + // the name node + option->nameNode = _pt.get("hdfs_storage.name_node", ""); + // checkNonEmptyField("hdfs_storage.name_node", option->nameNode); + // the name node port + option->nameNodePort = _pt.get("hdfs_storage.name_node_port", 8020); + // the user + option->userName = _pt.get("hdfs_storage.user", ""); + // checkNonEmptyField("hdfs_storage.user", option->userName); + // the token + option->token = _pt.get("hdfs_storage.token", ""); + // replace-datanode-on-failure + option->replaceDataNodeOnFailure = + _pt.get("hdfs_storage.replace-datanode-on-failure", false); + // connection-timeout + option->connectionTimeout = _pt.get("hdfs_storage.connection-timeout", 1000); + m_storageConfig.fileStorageConnectionOpt = option; + auto enableAuth = _pt.get("hdfs_storage.enable_krb5_auth", false); + if (enableAuth) + { + loadKrb5AuthConfig(_pt); + } + PPCConfig_LOG(INFO) << LOG_DESC("loadStorageConfig: load hdfs connection option success") + << LOG_KV("enableAuth", enableAuth) << option->desc(); +} + +void PPCConfig::loadKrb5AuthConfig(boost::property_tree::ptree const& pt) +{ + auto authConfig = std::make_shared(); + // the principal + authConfig->principal = pt.get("hdfs_storage.auth_principal", ""); + // the password + authConfig->password = pt.get("hdfs_storage.auth_password", ""); + // the ccachePath + authConfig->ccachePath = + pt.get("hdfs_storage.ccache_path", "/tmp/krb5cc_ppc_node"); + // the krb5.conf path + authConfig->authConfigFilePath = + pt.get("hdfs_storage.krb5_conf_path", "./conf/krb5.conf"); + // relative path case + if (!authConfig->authConfigFilePath.starts_with("/")) + { + auto joinedPath = + boost::filesystem::absolute(boost::filesystem::path(authConfig->authConfigFilePath)); + authConfig->authConfigFilePath = joinedPath.string(); + } + m_storageConfig.fileStorageConnectionOpt->authConfig = authConfig; + PPCConfig_LOG(INFO) << LOG_DESC("loadKrb5AuthConfig") << LOG_KV("config", authConfig->desc()); +} + +void PPCConfig::loadSQLConfig(boost::property_tree::ptree const& _pt) +{ + SQLConnectionOption opt; + opt.host = _pt.get("storage.host", "127.0.0.1"); + // checkNonEmptyField("storage.host", opt.host); + + opt.port = _pt.get("storage.port", 3306); + + opt.user = _pt.get("storage.user", "wedpr"); + // checkNonEmptyField("storage.user", opt.user); + + opt.password = _pt.get("storage.password", ""); + // checkNonEmptyField("storage.password", opt.password); + + opt.database = _pt.get("storage.database", ""); + // checkNonEmptyField("storage.database", opt.database); + + m_storageConfig.sqlConnectionOpt = std::make_shared(opt); + PPCConfig_LOG(INFO) << LOG_DESC("loadStorageConfig: load sql connection option success") + << m_storageConfig.sqlConnectionOpt->desc(); +} + + +void PPCConfig::loadStorageConfig(boost::property_tree::ptree const& _pt) +{ + loadSQLConfig(_pt); + loadHDFSConfig(_pt); +} + +void PPCConfig::loadCEMConfig(boost::property_tree::ptree const& _pt) +{ + m_cemConfig.datasetFilePath = _pt.get("cem.dataset_file_path", "./"); + m_cemConfig.datasetHDFSPath = _pt.get("cem.dataset_hdfs_path", "./"); + m_cemConfig.ciphertextSuffix = _pt.get("cem.ciphertext_suffix", "-encrypted"); + m_cemConfig.readPerBatchLines = _pt.get("cem.read_per_batch_lines", 100000); + loadHDFSConfig(_pt); +} + +void PPCConfig::loadMPCConfig(boost::property_tree::ptree const& _pt) +{ + // the agencyID + m_agencyID = _pt.get("agency.id", ""); + if (m_agencyID.empty()) + { + BOOST_THROW_EXCEPTION(InvalidConfig() << errinfo_comment("Must set agency.id")); + } + + PPCConfig_LOG(INFO) << LOG_DESC("load agency id") << LOG_KV("agencyID", m_agencyID); + + m_mpcConfig.jobPath = _pt.get("mpc.job_path", "./"); + m_mpcConfig.mpcRootPath = _pt.get("mpc.mpc_root_path", "./"); + m_mpcConfig.mpcRootPathNoGateway = _pt.get("mpc.mpc_root_path_no_gateway", "./"); + m_mpcConfig.readPerBatchLines = _pt.get("mpc.read_per_batch_lines", 100000); + m_mpcConfig.spdzConnectedPort = _pt.get("spdz.connected_port", 5894); + m_mpcConfig.spdzConnectedIP = _pt.get("transport.host_ip", ""); + + PPCConfig_LOG(INFO) << LOG_DESC("spdzConnectedPort") << LOG_KV("spdzConnectedIP", m_mpcConfig.spdzConnectedIP) << LOG_KV("spdzConnectedPort", m_mpcConfig.spdzConnectedPort); + + m_mpcConfig.threadPoolSize = _pt.get("mpc.async_thread_pool_size", -1); + if (m_mpcConfig.threadPoolSize < 0) + { + m_mpcConfig.threadPoolSize = std::thread::hardware_concurrency(); + } + loadHDFSConfig(_pt); +} \ No newline at end of file diff --git a/cpp/wedpr-helper/ppc-tools/src/config/PPCConfig.h b/cpp/wedpr-helper/ppc-tools/src/config/PPCConfig.h new file mode 100644 index 00000000..fe863f4e --- /dev/null +++ b/cpp/wedpr-helper/ppc-tools/src/config/PPCConfig.h @@ -0,0 +1,356 @@ +/* + * Copyright (C) 2022 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 PPCConfig.h + * @author: yujiechen + * @date 2022-11-4 + */ +#pragma once +#include "../cuckoo/Common.h" +#include "CEMConfig.h" +#include "Common.h" +#include "MPCConfig.h" +#include "NetworkConfig.h" +#include "ParamChecker.h" +#include "StorageConfig.h" +#include "ppc-framework/front/FrontConfig.h" +#include "ppc-framework/protocol/EndPoint.h" +#include "ppc-framework/protocol/GrpcConfig.h" +#include "ppc-framework/storage/CacheStorage.h" +#include +#include +#include +#include +#include + +namespace ppc::tools +{ +// lines +constexpr static uint64_t DefaultDataBatchSize = 1000000; +constexpr static uint16_t DefaultParallelism = 3; +constexpr static std::string_view NODE_PEM_NAME = "node.pem"; +struct RA2018Config +{ + // MBytes + constexpr static uint64_t DefaultCuckooFilterCacheSize = 256; + // MBytes + constexpr static uint64_t DefaultCacheSize = 1024; + // the default cuckoo-filter-capacity: 1MBytes + constexpr static int DefaultCuckooFilterCapacity = 1; + constexpr static uint8_t DefaultCuckooFilterTagSize = 32; + constexpr static uint8_t DefaultBucketSize = 4; + constexpr static uint16_t DefaultMaxKickoutCount = 20; + constexpr static uint64_t DefaultTrashBucketSize = 10000; + + std::string dbName; // the db used to store cuckoo-filter + ppc::tools::CuckoofilterOption::Ptr cuckooFilterOption; + uint64_t cuckooFilterCacheSize = DefaultCuckooFilterCacheSize * 1024 * 1024; + uint64_t cacheSize = DefaultCacheSize * 1024 * 1024; + // default load 100w data per-time + int64_t dataBatchSize = DefaultDataBatchSize; + // use hdfs to store cuckoo-filter or not + bool useHDFS = false; +}; + +struct GatewayConfig +{ + // the max allowed message size, default is 100MBytes + // the boostssl limit is 32MBytes + constexpr static uint64_t DefaultMaxAllowedMsgSize = 100; + constexpr static uint64_t MinMsgSize = 10 * 1024 * 1024; + // set the max msg size to 2GB + constexpr static uint64_t MaxMsgSize = uint64_t(1 << 31); + constexpr static int MinUnreachableDistance = 2; + + NetworkConfig networkConfig; + ppc::protocol::GrpcServerConfig::Ptr grpcServerConfig = + std::make_shared(); + // the file that configure the connected endpoint information + std::string nodeFileName; + // the dir that contains the connected endpoint information, e.g.nodes.json + std::string nodePath; + uint64_t maxAllowedMsgSize = DefaultMaxAllowedMsgSize; + int reconnectTime = 10000; + // the unreachable distance + int unreachableDistance = 10; +}; + +// the ecdh-psi config +struct EcdhPSIParam +{ + int64_t dataBatchSize = DefaultDataBatchSize; +}; + +struct EcdhMultiPSIParam +{ + int64_t dataBatchSize = DefaultDataBatchSize; +}; + +struct EcdhConnPSIParam +{ + int64_t dataBatchSize = DefaultDataBatchSize; + int64_t rank; + int64_t algos; + int64_t protocol_families; + int64_t curve; + int64_t hashtype; + int64_t hash2curve; +}; + +struct CM2020PSIParam +{ + uint16_t parallelism = DefaultParallelism; +}; + +struct OtPIRParam +{ + uint16_t parallelism = DefaultParallelism; +}; + +class PPCConfig +{ +public: + using Ptr = std::shared_ptr; + using ConstPtr = std::shared_ptr; + PPCConfig() = default; + virtual ~PPCConfig() = default; + // load the nodeConfig + void loadNodeConfig(bool requireTransport, + ppc::front::FrontConfigBuilder::Ptr const& frontConfigBuilder, + std::string const& _configPath) + { + PPCConfig_LOG(INFO) << LOG_DESC("loadNodeConfig") << LOG_KV("path", _configPath); + boost::property_tree::ptree iniConfig; + boost::property_tree::read_ini(_configPath, iniConfig); + // Note: must load common-config firstly since some ra-configs depends on the common-config + loadCommonNodeConfig(iniConfig); + loadFrontConfig(requireTransport, frontConfigBuilder, _configPath); + loadRA2018Config(iniConfig); + loadStorageConfig(iniConfig); + loadEcdhPSIConfig(iniConfig); + loadCM2020PSIConfig(iniConfig); + loadEcdhMultiPSIConfig(iniConfig); + loadEcdhConnPSIConfig(iniConfig); + } + + void loadRpcConfig(std::string const& _configPath) + { + PPCConfig_LOG(INFO) << LOG_DESC("loadRpcConfig") << LOG_KV("path", _configPath); + boost::property_tree::ptree iniConfig; + boost::property_tree::read_ini(_configPath, iniConfig); + loadRpcConfig(iniConfig); + } + + void loadGatewayConfig(std::string const& _configPath, bool requireTransport) + { + PPCConfig_LOG(INFO) << LOG_DESC("loadGatewayConfig") << LOG_KV("path", _configPath); + boost::property_tree::ptree iniConfig; + boost::property_tree::read_ini(_configPath, iniConfig); + loadGatewayConfig(iniConfig, requireTransport); + } + + void loadFrontConfig(bool requireTransport, + ppc::front::FrontConfigBuilder::Ptr const& frontConfigBuilder, + std::string const& _configPath) + { + PPCConfig_LOG(INFO) << LOG_DESC("loadFrontConfig") << LOG_KV("path", _configPath); + boost::property_tree::ptree iniConfig; + boost::property_tree::read_ini(_configPath, iniConfig); + loadFrontConfig(requireTransport, frontConfigBuilder, iniConfig); + // load the grpcConfig + m_grpcConfig = loadGrpcConfig("transport", iniConfig); + m_frontConfig->setGrpcConfig(m_grpcConfig); + } + + virtual void loadRpcConfig(boost::property_tree::ptree const& _pt) + { + // rpc default disable-ssl + loadNetworkConfig(m_rpcConfig, _pt, "rpc", NetworkConfig::DefaultRpcListenPort, true); + } + + virtual void loadGatewayConfig(boost::property_tree::ptree const& _pt, bool requireTransport); + + + NetworkConfig const& rpcConfig() const { return m_rpcConfig; } + // the gateway-config + GatewayConfig const& gatewayConfig() const { return m_gatewayConfig; } + + RA2018Config const& ra2018PSIConfig() const { return m_ra2018PSIConfig; } + RA2018Config& mutableRA2018PSIConfig() { return m_ra2018PSIConfig; } + + StorageConfig const& storageConfig() const { return m_storageConfig; } + CEMConfig const& cemConfig() const { return m_cemConfig; } + MPCConfig const& mpcConfig() const { return m_mpcConfig; } + std::string const& agencyID() const { return m_agencyID; } + bool smCrypto() const { return m_smCrypto; } + std::string const& endpoint() const { return m_endpoint; } + + std::string const& dataLocation() const { return m_dataLocation; } + uint32_t const& taskTimeoutMinutes() const { return m_taskTimeoutMinutes; } + uint32_t const& threadPoolSize() const { return m_threadPoolSize; } + + EcdhPSIParam const& ecdhPSIConfig() const { return m_ecdhPSIConfig; } + EcdhPSIParam& mutableEcdhPSIConfig() { return m_ecdhPSIConfig; } + + EcdhConnPSIParam const& ecdhConnPSIConfig() const { return m_ecdhConnPSIConfig; } + EcdhConnPSIParam& mutableEcdhConnPSIConfig() { return m_ecdhConnPSIConfig; } + + EcdhMultiPSIParam const& ecdhMultiPSIConfig() const { return m_ecdhMultiPSIConfig; } + EcdhMultiPSIParam& mutableEcdhMultiPSIConfig() { return m_ecdhMultiPSIConfig; } + + CM2020PSIParam const& cm2020PSIConfig() const { return m_cm2020Config; } + CM2020PSIParam& mutableCM2020PSIConfig() { return m_cm2020Config; } + + OtPIRParam const& otPIRParam() const { return m_otPIRConfig; } + OtPIRParam& mutableOtPIRParam() { return m_otPIRConfig; } + + bcos::bytes const& privateKey() const { return m_privateKey; } + void setPrivateKey(bcos::bytes const& _privateKey); + + std::string const& privateKeyPath() const { return m_privateKeyPath; } + // for pro-mode + void setPrivateKeyPath(std::string const& _privateKeyPath) + { + m_privateKeyPath = _privateKeyPath; + } + + bool disableRA2018() const { return m_disableRA2018; } + + int holdingMessageMinutes() const { return m_holdingMessageMinutes; } + + ppc::front::FrontConfig::Ptr const& frontConfig() const { return m_frontConfig; } + + ppc::protocol::GrpcConfig::Ptr const& grpcConfig() const { return m_grpcConfig; } + + // used by mpc initilizer + virtual void loadMPCConfig(boost::property_tree::ptree const& _pt); + // used by cem module + virtual void loadCEMConfig(boost::property_tree::ptree const& _pt); + + // for ut + void setAgencyID(std::string const& agencyID) { m_agencyID = agencyID; } + + uint16_t seqSyncPeriod() const { return m_seqSyncPeriod; } + + std::string accessEntrypoint() const + { + return m_frontConfig->selfEndPoint().host() + ":" + std::to_string(m_rpcConfig.listenPort); + } + + std::string spdzConnectedEndPoint() const // for mpc + { + return m_mpcConfig.spdzConnectedIP + ":" + std::to_string(m_mpcConfig.spdzConnectedPort); + } + + // load the front config + virtual void loadFrontConfig(bool requireTransport, + ppc::front::FrontConfigBuilder::Ptr const& frontConfigBuilder, + boost::property_tree::ptree const& pt); + + uint32_t minNeededMemoryGB() const { return m_minNeededMemoryGB; } + +private: + virtual void loadEndpointConfig(ppc::protocol::EndPoint& endPoint, bool requireHostIp, + std::string const& sectionName, boost::property_tree::ptree const& pt); + // load the grpc config + ppc::protocol::GrpcConfig::Ptr loadGrpcConfig( + std::string const& sectionName, boost::property_tree::ptree const& pt); + + virtual void loadHDFSConfig(boost::property_tree::ptree const& _pt); + virtual void loadKrb5AuthConfig(boost::property_tree::ptree const& pt); + virtual void loadSQLConfig(boost::property_tree::ptree const& _pt); + + + virtual void loadRA2018Config(boost::property_tree::ptree const& _pt); + virtual void loadEcdhPSIConfig(boost::property_tree::ptree const& _pt); + virtual void loadCM2020PSIConfig(boost::property_tree::ptree const& _pt); + virtual void loadEcdhMultiPSIConfig(boost::property_tree::ptree const& _pt); + virtual void loadEcdhConnPSIConfig(boost::property_tree::ptree const& _pt); + virtual void loadCommonNodeConfig(boost::property_tree::ptree const& _pt); + virtual void loadStorageConfig(boost::property_tree::ptree const& _pt); + + // Note: the gateway/rpc can share the loadNetworkConfig + void loadNetworkConfig(NetworkConfig& _config, boost::property_tree::ptree const& _pt, + std::string const& _sectionName, int _defaultListenPort, bool _defaultDisableSSl); + + void checkPort(std::string const& _sectionName, int _port); + void checkFileExists(std::string const& _filePath, bool _dir); + + inline void checkNonEmptyField(std::string const& _section, std::string const& _value) + { + if (_value.empty()) + { + BOOST_THROW_EXCEPTION(InvalidConfig() << bcos::errinfo_comment("Must set " + _section)); + } + } + + void loadCachedStorageConfig( + ppc::storage::CacheStorageConfig& _redisConfig, const boost::property_tree::ptree& _pt); + + int64_t getDataBatchSize(std::string const& _section, int64_t _dataBatchSize); + + int loadHoldingMessageMinutes( + const boost::property_tree::ptree& _pt, std::string const& _section); + +private: + // the rpc-config + NetworkConfig m_rpcConfig; + // the gateway-config + GatewayConfig m_gatewayConfig; + // the gateway holding message time, in minutes, default 30min + int m_holdingMessageMinutes = 30; + + uint16_t m_seqSyncPeriod = 5000; + + uint32_t m_minNeededMemoryGB; + // the front config + // TODO: parse the frontConfig + ppc::front::FrontConfig::Ptr m_frontConfig; + ppc::protocol::GrpcConfig::Ptr m_grpcConfig; + + // the ra2018-psi config + RA2018Config m_ra2018PSIConfig; + // the storage config + StorageConfig m_storageConfig; + // the cem config + CEMConfig m_cemConfig; + // the mpc config + MPCConfig m_mpcConfig; + + // the ecdh config + EcdhPSIParam m_ecdhPSIConfig; + + EcdhMultiPSIParam m_ecdhMultiPSIConfig; + + EcdhConnPSIParam m_ecdhConnPSIConfig; + + CM2020PSIParam m_cm2020Config; + + OtPIRParam m_otPIRConfig; + + // the agencyID/partyID + std::string m_agencyID; + bool m_smCrypto = false; + bcos::bytes m_privateKey; + std::string m_privateKeyPath; + + bool m_disableRA2018 = false; + + std::string m_endpoint; + std::string m_dataLocation; + uint32_t m_taskTimeoutMinutes; + uint32_t m_threadPoolSize; +}; +} // namespace ppc::tools \ No newline at end of file diff --git a/cpp/wedpr-helper/ppc-tools/src/config/ParamChecker.h b/cpp/wedpr-helper/ppc-tools/src/config/ParamChecker.h new file mode 100644 index 00000000..ca8f7f22 --- /dev/null +++ b/cpp/wedpr-helper/ppc-tools/src/config/ParamChecker.h @@ -0,0 +1,54 @@ +/** + * Copyright (C) 2022 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 UrlChecker.h + * @author: shawnhe + * @date 2023-04-21 + */ +#pragma once +#include "ppc-framework/Common.h" +#include + +namespace ppc::tools +{ +// ip:port or domain:port +inline bool checkEndpoint(const std::string& _endpoint) +{ + try + { + if (_endpoint.empty()) + { + return false; + } + std::vector url; + boost::split(url, _endpoint, boost::is_any_of(":"), boost::token_compress_on); + if (url.size() != 2) + { + return false; + } + + int port = std::stoi(url[1]); + if (0 > port || 65535 < port) + { + return false; + } + } + catch (std::exception& e) + { + return false; + } + return true; +} +} // namespace ppc::tools \ No newline at end of file diff --git a/cpp/wedpr-helper/ppc-tools/src/config/StorageConfig.h b/cpp/wedpr-helper/ppc-tools/src/config/StorageConfig.h new file mode 100644 index 00000000..e9bd4dce --- /dev/null +++ b/cpp/wedpr-helper/ppc-tools/src/config/StorageConfig.h @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2022 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 StorageConfig.h + * @author: yujiechen + * @date 2022-11-4 + */ +#pragma once +#include "ppc-framework/protocol/Krb5AuthConfig.h" +#include +#include +#include + +namespace ppc::tools +{ +struct StorageConfig +{ + ppc::protocol::SQLConnectionOption::Ptr sqlConnectionOpt; + ppc::protocol::FileStorageConnectionOption::Ptr fileStorageConnectionOpt; + ppc::protocol::RemoteStorageConnectionOption::Ptr remoteConnectionOpt; +}; +} // namespace ppc::tools \ No newline at end of file diff --git a/cpp/wedpr-helper/ppc-tools/src/cuckoo/Common.h b/cpp/wedpr-helper/ppc-tools/src/cuckoo/Common.h new file mode 100644 index 00000000..3cdc6494 --- /dev/null +++ b/cpp/wedpr-helper/ppc-tools/src/cuckoo/Common.h @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2022 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 Common.h + * @author: yujiechen + * @date 2022-10-26 + */ +#pragma once +#include "ppc-framework/Common.h" +#include +#include + +#define CUCKOO_LOG(LEVEL) BCOS_LOG(LEVEL) << LOG_BADGE("CUCKOO") +namespace ppc::tools +{ +DERIVE_PPC_EXCEPTION(InvalidCuckooFilterOption); +inline uint64_t upperpower2(uint64_t x) +{ + x--; + x |= x >> 1; + x |= x >> 2; + x |= x >> 4; + x |= x >> 8; + x |= x >> 16; + x |= x >> 32; + x++; + return x; +} +struct CuckoofilterOption +{ + using Ptr = std::shared_ptr; + using ConstPtr = std::shared_ptr; + // the capacity + uint64_t capacity = 0; + // the tag-size, default is 64bits + uint8_t tagBits = 64; + // the tagNumPerBucket, default is 4 + uint8_t tagNumPerBucket = 4; + // The maximum number of times an element has been kicked + uint16_t maxKickOutCount = 20; + // the trash bucket size + uint64_t trashBucketSize = 10000; + + // calculate the bucketCapacity + void calculateBucketCapacity() + { + m_bucketCapacity = upperpower2(std::max(1, capacity / tagNumPerBucket)); + } + uint64_t bucketCapacity() const { return m_bucketCapacity; } + +private: + uint64_t m_bucketCapacity = 0; +}; + +enum CuckooFilterResult : int +{ + OverLoaded, + OverMaxKickOff, + Success, +}; + +inline std::string printCuckooFilterOption(CuckoofilterOption::ConstPtr _option) +{ + std::ostringstream stringstream; + stringstream << LOG_KV("capacity", _option->capacity) + << LOG_KV("tagBits", (int)_option->tagBits) + << LOG_KV("buckets", (int)_option->tagNumPerBucket) + << LOG_KV("maxKickOutCount", _option->maxKickOutCount) + << LOG_KV("trashBucketSize", _option->trashBucketSize); + return stringstream.str(); +} + +} // namespace ppc::tools \ No newline at end of file diff --git a/cpp/wedpr-helper/ppc-tools/src/cuckoo/Cuckoofilter.h b/cpp/wedpr-helper/ppc-tools/src/cuckoo/Cuckoofilter.h new file mode 100644 index 00000000..7d78de40 --- /dev/null +++ b/cpp/wedpr-helper/ppc-tools/src/cuckoo/Cuckoofilter.h @@ -0,0 +1,339 @@ +/* + * Copyright (C) 2022 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 Cuckoofilter.h + * @author: yujiechen + * @date 2022-10-26 + */ +#pragma once +#include "Common.h" +#include "HashTable.h" +#include "ppc-crypto-core/src/hash/BitMixMurmurHash.h" +#include +#include +#include + +namespace ppc::tools +{ +template +class Cuckoofilter +{ +public: + using Ptr = std::shared_ptr; + Cuckoofilter(CuckoofilterOption::Ptr _opt) + : m_option(_opt), m_hash(std::make_shared()) + { + initCuckooFilter(_opt); + m_hashTable = std::make_shared(_opt); + } + + Cuckoofilter(bcos::bytesConstRef _data) + : m_hash(std::make_shared()), m_hashTable(std::make_shared(_data)) + { + m_option = m_hashTable->option(); + initCuckooFilter(m_option); + } + + virtual ~Cuckoofilter() = default; + + // serialize the cuckoo-filter(mainly serialize the hashTable) + virtual std::string serialize() { return m_hashTable->serialize(); } + + // insert _key into the cuckoofilter + template + CuckooFilterResult insert(T const& _key) + { + bcos::UpgradableGuard l(m_mutex); + // the key already exists + if (containsWithoutLock(_key)) + { + return CuckooFilterResult::Success; + } + bcos::UpgradeGuard ul(l); + return insertWithoutLock(_key); + } + + // return the successfully inserted key-count + template + bool batchInsert(T& _mutableKeyBatch) + { + auto startT = bcos::utcSteadyTime(); + auto orgKeySize = _mutableKeyBatch.size(); + bcos::WriteGuard l(m_mutex); + for (auto it = _mutableKeyBatch.begin(); it != _mutableKeyBatch.end();) + { + // the key already exist + if (containsWithoutLock(*it)) + { + it = _mutableKeyBatch.erase(it); + continue; + } + auto ret = insertWithoutLock(*it); + if (ret == CuckooFilterResult::Success) + { + // erase the inserted element from the _keyBatch + it = _mutableKeyBatch.erase(it); + continue; + } + // not overload, but conflict, just ignore this element + if (ret == CuckooFilterResult::OverMaxKickOff) + { + it++; + continue; + } + // overload: break + break; + } + CUCKOO_LOG(INFO) << LOG_DESC("batchInsert") << LOG_KV("inputSize", orgKeySize) + << LOG_KV("successSize", (orgKeySize - _mutableKeyBatch.size())) + << LOG_KV("left", _mutableKeyBatch.size()) << LOG_KV("load", loadFactor()) + << LOG_KV("timecost", (bcos::utcSteadyTime() - startT)); + return _mutableKeyBatch.empty(); + } + + // check the _key exists in the cuckoofilter or not + template + bool contains(T const& _key) const + { + bcos::ReadGuard l(m_mutex); + return containsWithoutLock(_key); + } + + template + std::vector batchContain(std::vector const& _batchKey) const + { + bcos::ReadGuard l(m_mutex); + std::vector result(_batchKey.size()); + for (uint64_t i = 0; i < _batchKey.size(); i++) + { + result[i] = containsWithoutLock(_batchKey.at(i)); + } + return result; + } + + // return the intersection element into _result + template + void batchIntersection(std::vector& _result, std::vector const& _batchKey) const + { + bcos::ReadGuard l(m_mutex); + for (uint64_t i = 0; i < _batchKey.size(); i++) + { + if (containsWithoutLock(_batchKey.at(i))) + { + _result.emplace_back(_batchKey.at(i)); + } + } + } + + template + std::vector batchIntersectionAndGetPos(std::vector const& _batchKey) const + { + bcos::ReadGuard l(m_mutex); + std::vector pos; + for (uint64_t i = 0; i < _batchKey.size(); i++) + { + if (containsWithoutLock(_batchKey.at(i))) + { + pos.emplace_back(i); + } + } + return pos; + } + + // delete the _key from the cuckoofilter + template + bool deleteKey(T const& _key) + { + bcos::WriteGuard l(m_mutex); + return deleteKeyWithoutLock(_key); + } + + template + std::vector batchDeleteKey(std::vector const& _keyBatch) + { + bcos::WriteGuard l(m_mutex); + std::vector result; + for (auto const& key : _keyBatch) + { + result.emplace_back(deleteKeyWithoutLock(key)); + } + return result; + } + + // delete the key from the cuckoo-filter, return the delete-failed key into _keyBatch + template + void batchDeleteAndGetRemainKeys(std::vector& _keyBatch) + { + bcos::WriteGuard l(m_mutex); + for (auto it = _keyBatch.begin(); it != _keyBatch.end();) + { + if (!deleteKeyWithoutLock(*it)) + { + it++; + continue; + } + it = _keyBatch.erase(it); + } + } + + double loadFactor() { return 1.0 * m_hashTable->occupiedCount() / m_totalTagSize; } + int64_t occupiedCount() const { return m_hashTable->occupiedCount(); } + + uint64_t capacity() const { return m_hashTable->capacity(); } + bool full() const { return m_hashTable->full(); } + +protected: + // insert the _key into cuckoo-filter + template + CuckooFilterResult insertWithoutLock(T const& _key) + { + // the cuckoo-filter is over the load-threshold + if (m_hashTable->full()) + { + return CuckooFilterResult::OverLoaded; + } + auto fingerPrintInfo = calculateIndexAndFingerPrint(_key); + uint64_t oldFingerPrint = 0; + // insert the _key-finger-print into the i1 success + if (m_hashTable->insert( + std::get<0>(fingerPrintInfo), std::get<2>(fingerPrintInfo), oldFingerPrint, false)) + { + return CuckooFilterResult::Success; + } + // insert the _key-finger-print into the i2 success + if (m_hashTable->insert( + std::get<1>(fingerPrintInfo), std::get<2>(fingerPrintInfo), oldFingerPrint, false)) + { + return CuckooFilterResult::Success; + } + // insert the occupied index + uint64_t index = std::get<0>(fingerPrintInfo); + uint64_t fingerPrint = std::get<2>(fingerPrintInfo); + for (uint16_t i = 0; i < m_option->maxKickOutCount; i++) + { + // replace the i2 fingerprint + m_hashTable->insert(index, fingerPrint, oldFingerPrint, true); + // find-out a empty position for the old-finger-print + if (oldFingerPrint != 0) + { + // find the place to hold oldFingerPrint + index = index ^ (m_hash->hash(oldFingerPrint, m_hashBitsLen) & + (m_option->bucketCapacity() - 1)); + fingerPrint = oldFingerPrint; + // reset oldFingerPrint + oldFingerPrint = 0; + continue; + } + return CuckooFilterResult::Success; + } + // insert into the trash bucket + m_hashTable->insertIntoTrash(fingerPrint); + return CuckooFilterResult::OverMaxKickOff; + } + + // check the cuckoo-filter contains _key or not + template + bool containsWithoutLock(T const& _key) const + { + auto fingerPrintInfo = calculateIndexAndFingerPrint(_key); + return m_hashTable->contains(std::get<0>(fingerPrintInfo), std::get<1>(fingerPrintInfo), + std::get<2>(fingerPrintInfo)); + } + + // delete the given _key from the cuckoo-filter + template + bool deleteKeyWithoutLock(T const& _key) + { + auto fingerprintInfo = calculateIndexAndFingerPrint(_key); + if (m_hashTable->deleteFingerPrint( + std::get<0>(fingerprintInfo), std::get<2>(fingerprintInfo))) + { + return true; + } + if (m_hashTable->deleteFingerPrint( + std::get<1>(fingerprintInfo), std::get<2>(fingerprintInfo))) + { + return true; + } + // delete from the trashBucket + if (m_hashTable->deleteFromTrashBucket(std::get<2>(fingerprintInfo))) + { + return true; + } + return false; + } + +private: + void initCuckooFilter(CuckoofilterOption::Ptr _opt) + { + m_option = _opt; + if (m_option->tagBits % 8 != 0) + { + BOOST_THROW_EXCEPTION(InvalidCuckooFilterOption() + << bcos::errinfo_comment("the tags size must be multiple of 8")); + } + if (m_option->capacity == 0) + { + BOOST_THROW_EXCEPTION(InvalidCuckooFilterOption() + << bcos::errinfo_comment("the capacity must be larger than 0")); + } + if (m_option->tagBits > 64) + { + BOOST_THROW_EXCEPTION(InvalidCuckooFilterOption() << bcos::errinfo_comment( + "the tagBits must be no larger than 64")); + } + m_hashBitsLen = (m_option->tagBits <= 32 ? 32 : 64); + m_tagBytes = m_option->tagBits >> 3; + // update the capacity to 2^n(the cuckoo-filter requires the capacity to be 2^n) + m_option->calculateBucketCapacity(); + m_totalTagSize = (uint64_t)m_option->bucketCapacity() * (uint64_t)m_option->tagNumPerBucket; + CUCKOO_LOG(INFO) << printCuckooFilterOption(_opt); + } + + uint64_t calculateFingerPrint(uint64_t _hash) const + { + auto fingerPrint = (uint64_t)(_hash >> (m_hashBitsLen - m_option->tagBits)); + // the case finger is 0 + if (0 == fingerPrint) + { + return 1; + } + return fingerPrint; + } + + template + std::tuple calculateIndexAndFingerPrint(T const _key) const + { + uint64_t hashResult = m_hash->hash(_key, m_hashBitsLen); + // calculate i1 + uint64_t i1 = hashResult & (m_option->bucketCapacity() - 1); + // calculate fingerprint + uint64_t fingerPrint = calculateFingerPrint(hashResult); + // calculate i2 + uint64_t i2 = + i1 ^ (m_hash->hash(fingerPrint, m_hashBitsLen) & (m_option->bucketCapacity() - 1)); + return std::make_tuple(i1, i2, fingerPrint); + } + +private: + CuckoofilterOption::Ptr m_option; + std::shared_ptr m_hash; + std::shared_ptr m_hashTable; + uint8_t m_tagBytes; + uint8_t m_hashBitsLen; + uint64_t m_totalTagSize = 0; + mutable bcos::SharedMutex m_mutex; +}; +} // namespace ppc::tools diff --git a/cpp/wedpr-helper/ppc-tools/src/cuckoo/HashTable.cpp b/cpp/wedpr-helper/ppc-tools/src/cuckoo/HashTable.cpp new file mode 100644 index 00000000..916d61cc --- /dev/null +++ b/cpp/wedpr-helper/ppc-tools/src/cuckoo/HashTable.cpp @@ -0,0 +1,163 @@ +/* + * Copyright (C) 2022 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 HashTable.cpp + * @author: yujiechen + * @date 2022-10-26 + */ +#include "HashTable.h" + +using namespace ppc::tools; + +std::string HashTable::serialize() +{ + std::string encodedData; + boost::iostreams::stream> outputStream( + encodedData); + boost::archive::binary_oarchive archive(outputStream, + boost::archive::no_header | boost::archive::no_codecvt | boost::archive::no_tracking); + archive << m_option->capacity; + archive << m_option->tagBits; + archive << m_option->tagNumPerBucket; + archive << m_option->maxKickOutCount; + archive << m_buckets; + // serialize the trash-bucket + archive << m_trashBucket; + outputStream.flush(); + return encodedData; +} + +void HashTable::deserialize(bcos::bytesConstRef _data) +{ + boost::iostreams::stream inputStream( + (const char*)_data.data(), _data.size()); + boost::archive::binary_iarchive archive(inputStream, + boost::archive::no_header | boost::archive::no_codecvt | boost::archive::no_tracking); + archive >> m_option->capacity; + archive >> m_option->tagBits; + archive >> m_option->tagNumPerBucket; + archive >> m_option->maxKickOutCount; + archive >> m_buckets; + // deserialize the trash-bucket + archive >> m_trashBucket; +} + +uint64_t HashTable::getFingerPrint(const uint64_t _entryIndex, const uint32_t _bucketIndex) const +{ + // empty finger-print + auto it = m_buckets.find(_entryIndex); + if (it == m_buckets.end()) + { + return 0; + } + auto const& bucket = it->second; + // empty bucket + if (bucket.size() == 0) + { + return 0; + } + // Note: use little-endian here + // get the bytes-data + int64_t fingerPrint = 0; + auto offset = _bucketIndex * m_bytesPerTag; + for (uint32_t i = offset; i < (offset + m_bytesPerTag); i++) + { + fingerPrint <<= 8; + fingerPrint |= bucket.at(i); + } + return fingerPrint; +} + +bool HashTable::insert( + const uint64_t _pos, const uint64_t _fingerPrint, uint64_t& _oldFingerPrint, bool _kickOut) +{ + // find the un-occupied bucket + for (uint32_t bucketIndex = 0; bucketIndex < m_option->tagNumPerBucket; bucketIndex++) + { + if (getFingerPrint(_pos, bucketIndex) == 0) + { + writeFingerPrint(_pos, bucketIndex, _fingerPrint); + m_occupiedCount++; + return true; + } + } + // random choose one fingerprint from the bucket to kickOut + if (_kickOut) + { + srand(bcos::utcSteadyTime()); + auto selectedBucket = rand() % (m_option->tagNumPerBucket); + _oldFingerPrint = getFingerPrint(_pos, selectedBucket); + writeFingerPrint(_pos, selectedBucket, _fingerPrint); + return true; + } + return false; +} + +bool HashTable::deleteFingerPrint(const uint64_t _pos, const uint64_t _fingerPrint) +{ + for (uint32_t bucketIndex = 0; bucketIndex < m_option->tagNumPerBucket; bucketIndex++) + { + if (getFingerPrint(_pos, bucketIndex) == _fingerPrint) + { + writeFingerPrint(_pos, bucketIndex, 0); + m_occupiedCount.store(std::max(0, m_occupiedCount.load() - 1)); + return true; + } + } + return false; +} + +void HashTable::writeFingerPrint( + const uint64_t _entryIndex, const uint32_t _bucketIndex, uint64_t const _fingerPrint) +{ + auto it = m_buckets.find(_entryIndex); + if (it == m_buckets.end()) + { + m_buckets[_entryIndex] = Bucket(); + } + auto& bucket = m_buckets[_entryIndex]; + if (bucket.size() <= m_bytesPerBucket) + { + bucket.resize(m_bytesPerBucket); + m_capacity += m_bytesPerBucket; + } + // write the fingerprint into the bucket + auto offset = _bucketIndex * m_bytesPerTag; + auto endPos = offset + (m_bytesPerTag - 1); + auto fingerPrintData = _fingerPrint; + for (int64_t i = endPos; i >= offset; i--) + { + bucket[i] = fingerPrintData & 0xff; + fingerPrintData >>= 8; + } +} + +bool HashTable::contains(const uint64_t _i1, const uint64_t _i2, const uint64_t _fingerPrint) const +{ + for (uint32_t bucketIndex = 0; bucketIndex < m_option->tagNumPerBucket; bucketIndex++) + { + if ((getFingerPrint(_i1, bucketIndex) == _fingerPrint) || + (getFingerPrint(_i2, bucketIndex) == _fingerPrint)) + { + return true; + } + } + // check the trash-bucket: hit in the trash bucket + if (m_trashBucket.count(_fingerPrint)) + { + return true; + } + return false; +} \ No newline at end of file diff --git a/cpp/wedpr-helper/ppc-tools/src/cuckoo/HashTable.h b/cpp/wedpr-helper/ppc-tools/src/cuckoo/HashTable.h new file mode 100644 index 00000000..a73ce8a4 --- /dev/null +++ b/cpp/wedpr-helper/ppc-tools/src/cuckoo/HashTable.h @@ -0,0 +1,147 @@ +/* + * Copyright (C) 2022 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 HashTable.h + * @author: yujiechen + * @date 2022-10-26 + */ +#pragma once +#include "Common.h" +#include +#include +#include +#include +#include +#include +#include +#include +namespace ppc::tools +{ +class HashTable +{ +public: + using Ptr = std::shared_ptr; + HashTable(CuckoofilterOption::Ptr _option) : m_option(_option) { initHashTableParams(); } + + HashTable(bcos::bytesConstRef _data) : m_option(std::make_shared()) + { + m_capacity = _data.size(); + deserialize(_data); + initHashTableParams(); + } + + virtual ~HashTable() = default; + /** + * @brief check the hashTable contains given finger-print in pos _i1 or _i2 + * + * @param _i1 the pos i1 + * @param _i2 the pos i2 + * @param _fingerPrint the finger-print + * @return true find the finger-print + * @return false the finger-print doesn't exist in the HashTable + */ + bool contains(const uint64_t _i1, const uint64_t _i2, const uint64_t _fingerPrint) const; + + /** + * @brief try to insert finger-print into the given pos + * + * @param _pos the pos that required to insert the finger-print + * @param _fingerPrint the finger-print to be inserted + * @param _oldFingerPrint the kickOuted finger-print + * @return true insert success + * @return false insert failed + */ + // Note: use lazy allocate policy here + bool insert(const uint64_t _pos, const uint64_t _fingerPrint, uint64_t& _oldFingerPrint, + bool _kickOut = true); + + // delete the given finger-print front the hashTable + bool deleteFingerPrint(const uint64_t _pos, const uint64_t _fingerPrint); + virtual std::string serialize(); + virtual void deserialize(bcos::bytesConstRef _data); + CuckoofilterOption::Ptr option() const { return m_option; } + int64_t occupiedCount() const { return m_occupiedCount.load(); } + + uint64_t capacity() const { return m_capacity; } + + // the hashTable is full or not + bool full() const { return m_trashBucket.size() >= m_option->trashBucketSize; } + + bool insertIntoTrash(uint64_t _fingerPrint) + { + if (m_trashBucket.count(_fingerPrint)) + { + return true; + } + if (m_trashBucket.size() >= m_option->trashBucketSize) + { + return false; + } + m_trashBucket.insert(_fingerPrint); + return true; + } + + bool deleteFromTrashBucket(uint64_t _fingerPrint) + { + auto it = m_trashBucket.find(_fingerPrint); + if (it != m_trashBucket.end()) + { + m_trashBucket.erase(it); + return true; + } + return false; + } + +protected: + void initHashTableParams() + { + m_bytesPerBucket = (uint32_t)(m_option->tagBits * m_option->tagNumPerBucket) >> 3; + // Note: the tagBits of Cuckoofilter should be multiple of 8 + m_bytesPerTag = (uint32_t)(m_option->tagBits >> 3); + // the bucket-capacity + CUCKOO_LOG(INFO) << LOG_DESC("create HashTable") + << LOG_KV("tagBits", std::to_string(m_option->tagBits)) + << LOG_KV("tagNumPerBucket", std::to_string(m_option->tagNumPerBucket)) + << LOG_KV("bucketCapacity", m_option->bucketCapacity()) + << LOG_KV("bytesPerBucket", m_bytesPerBucket) + << LOG_KV("capacity", m_option->capacity); + } + +private: + uint64_t getFingerPrint(const uint64_t _entryIndex, const uint32_t _bucketIndex) const; + // lazy-allocate + void writeFingerPrint( + const uint64_t _entryIndex, const uint32_t _bucketIndex, uint64_t const _fingerPrint); + +private: + // the option + CuckoofilterOption::Ptr m_option; + // bytes-per-bucket(determined by the tagBits and the tagNumPerBucket) + uint32_t m_bytesPerBucket; + // bytes per fingerprint + uint32_t m_bytesPerTag; + // Note: the unordered_map can't ensure all the node with the same cuckoo-filter encoded into + // the same data, so we use map here + using Bucket = bcos::bytes; + std::map m_buckets; + // trash bucket, storing elements kicked out + // Note: the trash bucket is neccessary to accept the element over max-kick-out-count + std::set m_trashBucket; + std::atomic m_capacity = {0}; + + // the occupied-count + std::atomic m_occupiedCount = {0}; +}; +} // namespace ppc::tools \ No newline at end of file diff --git a/cpp/wedpr-helper/ppc-tools/tests/CMakeLists.txt b/cpp/wedpr-helper/ppc-tools/tests/CMakeLists.txt new file mode 100644 index 00000000..9ab026cc --- /dev/null +++ b/cpp/wedpr-helper/ppc-tools/tests/CMakeLists.txt @@ -0,0 +1,10 @@ +file(GLOB_RECURSE SOURCES "*.cpp" "*.h") + +# cmake settings +set(TEST_BINARY_NAME test-ppc-tools) + +add_executable(${TEST_BINARY_NAME} ${SOURCES}) +target_include_directories(${TEST_BINARY_NAME} PRIVATE .) + +target_link_libraries(${TEST_BINARY_NAME} ${TOOLS_TARGET} ${CRYPTO_CORE_TARGET} ${BOOST_UNIT_TEST}) +add_test(NAME test-tools WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} COMMAND ${TEST_BINARY_NAME}) \ No newline at end of file diff --git a/cpp/wedpr-helper/ppc-tools/tests/TestCuckoofilter.cpp b/cpp/wedpr-helper/ppc-tools/tests/TestCuckoofilter.cpp new file mode 100644 index 00000000..e38719a0 --- /dev/null +++ b/cpp/wedpr-helper/ppc-tools/tests/TestCuckoofilter.cpp @@ -0,0 +1,220 @@ +/* + * Copyright (C) 2022 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 applicabl 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 TestCuckoofilter.cpp + * @author: yujiechen + * @date 2022-10-26 + */ +#include "ppc-crypto-core/src/hash/SM3Hash.h" +#include "ppc-crypto-core/src/hash/Sha512Hash.h" +#include "ppc-tools/src/cuckoo/Cuckoofilter.h" +#include +#include +#include + +using namespace ppc::tools; +using namespace ppc::crypto; +using namespace bcos; + +using namespace bcos::test; + +namespace ppc::test +{ +BOOST_FIXTURE_TEST_SUITE(CuckoofilterTest, TestPromptFixture) + +void testCuckoofilterFunc( + std::shared_ptr> filter, + uint64_t keySize) +{ + // check empty key + for (uint64_t i = 1; i <= keySize; i++) + { + BOOST_CHECK(filter->contains(i) == false); + } + // insert keys + for (uint64_t i = 1; i <= keySize; i++) + { + filter->insert(i); + BOOST_CHECK(filter->contains(i) == true); + } + // check the occupied-count + BOOST_CHECK((uint64_t)filter->occupiedCount() == keySize); + BOOST_CHECK(filter->loadFactor() < 1); + + // test encode/decode + auto encodedData = filter->serialize(); + auto decodedFilter = std::make_shared>( + bcos::bytesConstRef((const unsigned char*)encodedData.data(), encodedData.size())); + // check the keys + for (uint64_t i = 1; i <= keySize; i++) + { + BOOST_CHECK(decodedFilter->contains(i) == true); + } + BOOST_CHECK(decodedFilter->contains(keySize + 1) == false); +} + +void randomNumberTest(CuckoofilterOption::Ptr option, uint64_t keySize) +{ + uint64_t maxValue = 1000000000; + auto filter = std::make_shared>(option); + + std::set randomValuesSet; + std::mt19937_64 rng(bcos::utcSteadyTime()); + std::uniform_int_distribution dis(1, maxValue); + for (uint64_t i = 0; i < keySize; i++) + { + auto value = dis(rng); + randomValuesSet.insert(value); + } + std::vector randomValues(randomValuesSet.begin(), randomValuesSet.end()); + // insert and check randomValues + std::set tmpRandomValues(randomValues.begin(), randomValues.end()); + auto result = filter->batchInsert(tmpRandomValues); + BOOST_CHECK(result == true); + BOOST_CHECK(tmpRandomValues.empty()); + for (uint64_t i = 0; i < randomValues.size(); i++) + { + BOOST_CHECK(filter->contains(randomValues.at(i)) == true); + } + // batchContain + auto batchContainResult = filter->batchContain(randomValues); + BOOST_CHECK(batchContainResult.size() == randomValues.size()); + for (uint64_t i = 0; i < randomValues.size(); i++) + { + BOOST_CHECK(batchContainResult.at(i) == true); + } + // test encode/decode + auto encodedData = filter->serialize(); + auto decodedFilter = std::make_shared>( + bcos::bytesConstRef((const unsigned char*)encodedData.data(), encodedData.size())); + // check the keys + for (uint64_t i = 0; i < randomValues.size(); i++) + { + BOOST_CHECK(decodedFilter->contains(randomValues.at(i)) == true); + } + // delete and check + for (uint64_t i = 0; i < randomValues.size() / 2; i++) + { + BOOST_CHECK(filter->deleteKey(randomValues.at(i)) == true); + } + uint64_t falsePositiveCount = 0; + for (uint64_t i = 0; i < randomValues.size() / 2; i++) + { + if (filter->contains(randomValues.at(i)) == true) + { + falsePositiveCount++; + } + } + std::cout << "falsePositiveCount: " << falsePositiveCount << std::endl; + // batchDelete + filter->batchDeleteKey(randomValues); + for (uint64_t i = 0; i < randomValues.size(); i++) + { + BOOST_CHECK(filter->contains(randomValues.at(i)) == false); + } +} + +void bytesKeyTest(Hash::Ptr hashImpl, CuckoofilterOption::Ptr option, uint64_t keySize) +{ + auto filter = std::make_shared>(option); + std::vector hashList; + for (uint64_t i = 0; i < keySize; i++) + { + std::string input = std::to_string(i); + bcos::bytes inputData(input.begin(), input.end()); + hashList.emplace_back(hashImpl->hash(ref(inputData))); + } + // insert the hashList and check + std::set tmpHashList(hashList.begin(), hashList.end()); + auto result = filter->batchInsert(tmpHashList); + BOOST_CHECK(tmpHashList.empty() == true); + BOOST_CHECK(result == true); + // insert with std::string_view and std::string(insert multiple-times) + for (uint64_t i = 0; i < hashList.size(); i++) + { + std::string dataStr = std::string(hashList.at(i).begin(), hashList.at(i).end()); + filter->insert(dataStr); + filter->insert(std::string_view(dataStr)); + } + for (uint64_t i = 0; i < hashList.size(); i++) + { + BOOST_CHECK(filter->contains(hashList.at(i)) == true); + } + // batchContain + auto batchContainResult = filter->batchContain(hashList); + BOOST_CHECK(batchContainResult.size() == hashList.size()); + for (uint64_t i = 0; i < hashList.size(); i++) + { + BOOST_CHECK(batchContainResult.at(i) == true); + } + // test encode/decode + auto encodedData = filter->serialize(); + auto decodedFilter = std::make_shared>( + bcos::bytesConstRef((const unsigned char*)encodedData.data(), encodedData.size())); + // check the keys + for (uint64_t i = 0; i < hashList.size(); i++) + { + BOOST_CHECK(decodedFilter->contains(hashList.at(i)) == true); + } + // delete and check + for (uint64_t i = 0; i < hashList.size() / 2; i++) + { + BOOST_CHECK(filter->deleteKey(hashList.at(i)) == true); + } + uint64_t falsePositiveCount = 0; + for (uint64_t i = 0; i < hashList.size() / 2; i++) + { + if (filter->contains(hashList.at(i)) == true) + { + falsePositiveCount++; + } + } + std::cout << "bytesKeyTest falsePositiveCount: " << falsePositiveCount << std::endl; + // batchDelete + filter->batchDeleteKey(hashList); + for (uint64_t i = 0; i < hashList.size(); i++) + { + BOOST_CHECK(filter->contains(hashList.at(i)) == false); + } +} + +BOOST_AUTO_TEST_CASE(testCuckoofilter) +{ + auto sm3Hash = std::make_shared(); + auto sha512Hash = std::make_shared(); + // option with tagBits: 16, tagNumPerBucket: 4, maxKickOutCount: 20 + auto option = std::make_shared(); + option->capacity = 10000; + auto filter = std::make_shared>(option); + uint64_t keySize = 5000; + testCuckoofilterFunc(filter, keySize); + randomNumberTest(option, keySize); + bytesKeyTest(sm3Hash, option, keySize); + bytesKeyTest(sha512Hash, option, keySize); + + // option with tagBits: 32, tagNumPerBucket: 4, maxKickOutCount: 10 + option = std::make_shared(); + option->tagBits = 32; + option->maxKickOutCount = 10; + option->capacity = 20000; + filter = std::make_shared>(option); + keySize = 10000; + testCuckoofilterFunc(filter, keySize); + randomNumberTest(option, keySize); + bytesKeyTest(sm3Hash, option, keySize); + bytesKeyTest(sha512Hash, option, keySize); +} +BOOST_AUTO_TEST_SUITE_END() +} // namespace ppc::test \ No newline at end of file diff --git a/cpp/wedpr-helper/ppc-tools/tests/TestTransTools.cpp b/cpp/wedpr-helper/ppc-tools/tests/TestTransTools.cpp new file mode 100644 index 00000000..073275ef --- /dev/null +++ b/cpp/wedpr-helper/ppc-tools/tests/TestTransTools.cpp @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2022 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 TestTransTools.h + * @author: shawnhe + * @date 2022-11-07 + */ + +#include "ppc-tools/src/common/TransTools.h" +#include +#include + +using namespace bcos; +using namespace bcos::test; +using namespace ppc::tools; + +namespace ppc::test +{ +BOOST_FIXTURE_TEST_SUITE(TransToolsTest, TestPromptFixture) + +template +void testEncodeAndDecodeFunc(T _number) +{ + auto buffer = std::make_shared(); + encodeUnsignedNum(buffer, _number); + + T num; + decodeUnsignedNum(num, buffer); + + BOOST_CHECK(num == _number); +} + +template +void testEncodeAndDecodeStrFunc(T _number) +{ + std::string buffer = ""; + encodeUnsignedNum(buffer, _number); + + T num; + decodeUnsignedNum(num, buffer); + + BOOST_CHECK(num == _number); +} + +BOOST_AUTO_TEST_CASE(testEncodeAndDecode) +{ + testEncodeAndDecodeFunc(uint8_t(17)); + testEncodeAndDecodeFunc(uint16_t(257)); + testEncodeAndDecodeFunc(uint32_t(65537)); + + testEncodeAndDecodeStrFunc(uint8_t(17)); + testEncodeAndDecodeStrFunc(uint16_t(257)); + testEncodeAndDecodeStrFunc(uint32_t(65537)); +} + +BOOST_AUTO_TEST_SUITE_END() +} // namespace ppc::test \ No newline at end of file diff --git a/cpp/wedpr-helper/ppc-tools/tests/main.cpp b/cpp/wedpr-helper/ppc-tools/tests/main.cpp new file mode 100644 index 00000000..2c06f9b5 --- /dev/null +++ b/cpp/wedpr-helper/ppc-tools/tests/main.cpp @@ -0,0 +1,2 @@ +#define BOOST_TEST_MAIN +#include \ No newline at end of file diff --git a/cpp/wedpr-helper/ppc-utilities/Utilities.h b/cpp/wedpr-helper/ppc-utilities/Utilities.h new file mode 100644 index 00000000..9832b65d --- /dev/null +++ b/cpp/wedpr-helper/ppc-utilities/Utilities.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 Utilitiles.cpp + * @author: yujiechen + * @date 2024-08-23 + */ +#pragma once +#include "ppc-framework/Common.h" +#include +#include +#include +#include +#include +#include + +namespace ppc +{ +template +inline uint64_t decodeNetworkBuffer(T& _result, bcos::byte const* buffer, unsigned int bufferLen, + uint64_t const offset, bool largeBuffer = false) +{ + uint64_t curOffset = offset; + // Notice: operator* is higher priority than operator+, the () is essential + uint32_t dataLen = 0; + if (largeBuffer) + { + CHECK_OFFSET_WITH_THROW_EXCEPTION(curOffset + 4, bufferLen); + dataLen = boost::asio::detail::socket_ops::network_to_host_long( + *((uint32_t*)(buffer + curOffset))); + curOffset += 4; + } + else + { + CHECK_OFFSET_WITH_THROW_EXCEPTION(curOffset + 2, bufferLen); + dataLen = boost::asio::detail::socket_ops::network_to_host_short( + *((uint16_t*)(buffer + curOffset))); + curOffset += 2; + } + if (dataLen == 0) + { + return curOffset; + } + CHECK_OFFSET_WITH_THROW_EXCEPTION(curOffset + dataLen, bufferLen); + _result.assign((bcos::byte*)buffer + curOffset, (bcos::byte*)buffer + curOffset + dataLen); + curOffset += dataLen; + return curOffset; +} + +inline std::string generateUUID() +{ + static thread_local auto uuid_gen = boost::uuids::basic_random_generator(); + return boost::uuids::to_string(uuid_gen()); +} + +inline std::string getServiceName(std::string const& agencyID, std::string const& serviceID) +{ + return agencyID + "_" + serviceID; +} +template +inline std::string printVector(T const& list) +{ + std::stringstream oss; + for (auto const& it : list) + { + oss << it << ","; + } + return oss.str(); +} +} // namespace ppc \ No newline at end of file diff --git a/cpp/wedpr-initializer/CMakeLists.txt b/cpp/wedpr-initializer/CMakeLists.txt new file mode 100644 index 00000000..633aaf0b --- /dev/null +++ b/cpp/wedpr-initializer/CMakeLists.txt @@ -0,0 +1,7 @@ +file(GLOB SRC_LIST "*.cpp") + +add_library(${INIT_LIB} ${SRC_LIST}) +target_link_libraries(${INIT_LIB} PUBLIC + ${PROTOCOL_TARGET} ${CRYPTO_TARGET} ${WEDPR_TRANSPORT_SDK_TARGET} ${LABELED_PSI_TARGET} + ${RA2018_PSI_TARGET} ${CM2020_PSI_TARGET} ${ECDH_2PC_PSI_TARGET} + ${ECDH_MULTI_PSI_TARGET} ${ECDH_CONN_PSI_TARGET} ${BS_ECDH_PSI_TARGET} ${PIR_TARGET} ${IO_TARGET} ${STORAGE_TARGET}) diff --git a/cpp/wedpr-initializer/Common.h b/cpp/wedpr-initializer/Common.h new file mode 100644 index 00000000..93427dfc --- /dev/null +++ b/cpp/wedpr-initializer/Common.h @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2022 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 Common.h + * @author: yujiechen + * @date 2022-11-14 + */ + +#pragma once +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#include "ppc-tools/src/config/Common.h" +#include +#include +#include +#include +#include + +#define INIT_LOG(LEVEL) BCOS_LOG(LEVEL) << LOG_BADGE("Initializer") + +namespace ppc::initializer +{ +inline bcos::bytes loadPrivateKey(std::string const& _keyPath, unsigned _hexedPrivateKeySize) +{ + auto keyContent = bcos::readContents(boost::filesystem::path(_keyPath)); + std::shared_ptr ecKey; + try + { + std::shared_ptr bioMem(BIO_new(BIO_s_mem()), [&](BIO* p) { BIO_free(p); }); + BIO_write(bioMem.get(), keyContent->data(), keyContent->size()); + + std::shared_ptr evpPKey(PEM_read_bio_PrivateKey(bioMem.get(), NULL, NULL, NULL), + [](EVP_PKEY* p) { EVP_PKEY_free(p); }); + if (!evpPKey) + { + BOOST_THROW_EXCEPTION( + ppc::tools::InvalidConfig() << bcos::errinfo_comment( + "SecureInitializer: parse privateKey failed for empty EVP_PKEY!")); + } + ecKey.reset(EVP_PKEY_get1_EC_KEY(evpPKey.get()), [](EC_KEY* p) { EC_KEY_free(p); }); + } + catch (std::exception const& e) + { + INIT_LOG(ERROR) << LOG_BADGE("SecureInitializer") << LOG_DESC("parse privateKey failed") + << LOG_KV("EINFO", boost::diagnostic_information(e)); + BOOST_THROW_EXCEPTION(ppc::tools::InvalidConfig() << bcos::errinfo_comment( + "SecureInitializer: parse privateKey failed, error: " + + std::string(boost::diagnostic_information(e)))); + } + std::shared_ptr ecPrivateKey( + EC_KEY_get0_private_key(ecKey.get()), [](const BIGNUM*) {}); + + std::shared_ptr privateKeyData( + BN_bn2hex(ecPrivateKey.get()), [](char* p) { OPENSSL_free(p); }); + std::string keyHex(privateKeyData.get()); + if (keyHex.size() >= _hexedPrivateKeySize) + { + return *(bcos::fromHexString(keyHex)); + } + for (size_t i = keyHex.size(); i < _hexedPrivateKeySize; i++) + { + keyHex = '0' + keyHex; + } + return *(bcos::fromHexString(keyHex)); +} +} // namespace ppc::initializer +#pragma GCC diagnostic pop \ No newline at end of file diff --git a/cpp/wedpr-initializer/Initializer.cpp b/cpp/wedpr-initializer/Initializer.cpp new file mode 100644 index 00000000..a0ecaea0 --- /dev/null +++ b/cpp/wedpr-initializer/Initializer.cpp @@ -0,0 +1,516 @@ +/* + * Copyright (C) 2022 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 Initializer.cpp + * @author: yujiechen + * @date 2022-11-14 + */ +#include "Initializer.h" +#include "Common.h" +#include "ppc-crypto/src/ecc/ECDHCryptoFactoryImpl.h" +#include "ppc-crypto/src/oprf/RA2018Oprf.h" +#include "ppc-framework/protocol/Protocol.h" +#include "ppc-pir/src/OtPIRFactory.h" +#include "ppc-pir/src/OtPIRImpl.h" +#include "ppc-psi/src/bs-ecdh-psi/BsEcdhPSIFactory.h" +#include "ppc-psi/src/cm2020-psi/CM2020PSIFactory.h" +#include "protocol/src/PPCMessage.h" +#include "wedpr-transport/sdk/src/TransportBuilder.h" +#if 0 +//TODO: optimize here to implement EcdhConnPSI +#include "ppc-psi/src/ecdh-conn-psi/EcdhConnPSIFactory.h" +#endif +#include "ppc-framework/protocol/Constant.h" +#include "ppc-front/Front.h" +#include "ppc-front/FrontConfigImpl.h" +#include "ppc-psi/src/ecdh-multi-psi/EcdhMultiPSIFactory.h" +#include "ppc-psi/src/ecdh-psi/EcdhPSIFactory.h" +#include "ppc-psi/src/labeled-psi/LabeledPSIFactory.h" +#include "ppc-psi/src/ra2018-psi/RA2018PSIFactory.h" +#include "ppc-tools/src/config/PPCConfig.h" +#include "wedpr-helper/ppc-utilities/Utilities.h" +#include +#include + +using namespace ppc::initializer; +using namespace ppc::storage; +using namespace ppc::front; +using namespace ppc::psi; +using namespace ppc::pir; +using namespace ppc::tools; +using namespace ppc::crypto; +using namespace ppc::sdk; +using namespace ppc::protocol; + +Initializer::Initializer(ppc::protocol::NodeArch _arch, std::string const& _configPath) + : m_arch((uint16_t)_arch), m_configPath(_configPath) +{ + m_transportBuilder = std::make_shared(); + // load the config + m_config = std::make_shared(); + if (m_arch == (uint16_t)ppc::protocol::NodeArch::PRO) + { + INIT_LOG(INFO) << LOG_DESC("loadNodeConfig for pro node"); + m_config->loadNodeConfig(true, m_transportBuilder->frontConfigBuilder(), _configPath); + } + else + { + INIT_LOG(INFO) << LOG_DESC("loadNodeConfig for air node"); + m_config->loadNodeConfig(false, m_transportBuilder->frontConfigBuilder(), _configPath); + } +} + +void Initializer::init(ppc::gateway::IGateway::Ptr const& gateway) +{ + INIT_LOG(INFO) << LOG_DESC("init the wedpr-component") << LOG_KV("arch", m_arch); + // load the protocol + m_protocolInitializer = std::make_shared(); + m_protocolInitializer->init(m_config); + + // init the frontService + INIT_LOG(INFO) << LOG_DESC("init the frontService") << LOG_KV("agency", m_config->agencyID()); + auto frontThreadPool = std::make_shared("front", m_config->threadPoolSize()); + + // Note: must set the m_holdingMessageMinutes before init the node + TransportBuilder transportBuilder; + // register the serviceInfo + auto serviceConfig = m_serviceConfigBuilder.buildServiceConfig(); + auto entryPoint = m_serviceConfigBuilder.buildEntryPoint( + getServiceName(m_config->agencyID(), PSI_SERVICE_TYPE), m_config->accessEntrypoint()); + + serviceConfig.addEntryPoint(entryPoint); + auto serviceMeta = serviceConfig.encode(); + m_config->frontConfig()->setMeta(serviceMeta); + INIT_LOG(INFO) << LOG_DESC("register serviceMeta") << LOG_KV("serviceMeta", serviceMeta); + if (m_arch == (uint16_t)ppc::protocol::NodeArch::AIR) + { + m_transport = transportBuilder.build(SDKMode::AIR, m_config->frontConfig(), gateway); + } + else + { + m_transport = transportBuilder.build(SDKMode::PRO, m_config->frontConfig(), nullptr); + } + m_ppcFront = + std::make_shared(std::make_shared(), m_transport->getFront()); + + INIT_LOG(INFO) << LOG_DESC("init the frontService success") + << LOG_KV("frontDetail", printFrontDesc(m_config->frontConfig())) + << LOG_KV("arch", m_arch); + + auto cryptoBox = m_protocolInitializer->cryptoBox(); + SQLStorage::Ptr sqlStorage = nullptr; + if (!m_config->disableRA2018()) + { + // init the SQLStorage(without set the dbName) + auto opt = std::make_shared( + *(m_config->storageConfig().sqlConnectionOpt)); + opt->database = ""; + INIT_LOG(INFO) << LOG_DESC("init the sqlStorage for ra2018-psi") << opt->desc(); + sqlStorage = m_protocolInitializer->sqlStorageFactory()->createSQLStorage( + ppc::protocol::DataResourceType::MySQL, opt); + INIT_LOG(INFO) << LOG_DESC("init the sqlStorage for ra2018-psi success"); + } + // init the fileStorage for ra2018 + FileStorage::Ptr fileStorage = nullptr; + if (!m_config->disableRA2018() && m_config->ra2018PSIConfig().useHDFS) + { + auto const& fileStorageOption = m_config->storageConfig().fileStorageConnectionOpt; + INIT_LOG(INFO) << LOG_DESC("init the hdfs-storage for ra2018-psi") + << fileStorageOption->desc(); + fileStorage = m_protocolInitializer->fileStorageFactory()->createFileStorage( + ppc::protocol::DataResourceType::HDFS, fileStorageOption); + INIT_LOG(INFO) << LOG_DESC("init the hdfs-storage for ra2018-psi success"); + } + + // init the ra2018-psi + INIT_LOG(INFO) << LOG_DESC("init the ra2018-psi"); + auto ra2018PSIFactory = std::make_shared(); + auto oprf = std::make_shared( + m_config->privateKey(), cryptoBox->eccCrypto(), cryptoBox->hashImpl()); + m_ra2018PSI = ra2018PSIFactory->createRA2018PSI(m_config->agencyID(), m_ppcFront, m_config, + oprf, m_protocolInitializer->binHashImpl(), m_protocolInitializer->ppcMsgFactory(), + sqlStorage, fileStorage, + std::make_shared("ra2018", m_config->threadPoolSize()), + m_protocolInitializer->dataResourceLoader()); + INIT_LOG(INFO) << LOG_DESC("init the ra2018-psi success"); + + // init the labeled-psi + INIT_LOG(INFO) << LOG_DESC("init the labeled-psi"); + auto labeledPSIFactory = std::make_shared(); + m_labeledPSI = labeledPSIFactory->buildLabeledPSI(m_config->agencyID(), m_ppcFront, cryptoBox, + std::make_shared("t_labeled-psi", m_config->threadPoolSize()), + m_protocolInitializer->dataResourceLoader(), m_config->holdingMessageMinutes(), + m_config->minNeededMemoryGB()); + INIT_LOG(INFO) << LOG_DESC("init the labeled-psi success"); + + // init the cm2020-psi + INIT_LOG(INFO) << LOG_DESC("init the cm2020-psi"); + auto cm2020PSIFactory = std::make_shared(); + m_cm2020PSI = cm2020PSIFactory->buildCM2020PSI(m_config->agencyID(), m_ppcFront, cryptoBox, + std::make_shared("t_cm2020-psi", m_config->threadPoolSize()), + m_protocolInitializer->dataResourceLoader(), m_config->holdingMessageMinutes(), + m_config->cm2020PSIConfig().parallelism, m_config->minNeededMemoryGB()); + INIT_LOG(INFO) << LOG_DESC("init the cm2020-psi success"); + + // init the ecdh-psi + INIT_LOG(INFO) << LOG_DESC("create ecdh-psi"); + auto ecdhPSIFactory = std::make_shared(); + auto ecdhCryptoFactory = std::make_shared(m_config->privateKey()); + m_ecdhPSI = ecdhPSIFactory->createEcdhPSI(m_config, ecdhCryptoFactory, m_ppcFront, + m_protocolInitializer->ppcMsgFactory(), nullptr, + m_protocolInitializer->dataResourceLoader(), m_config->minNeededMemoryGB()); + INIT_LOG(INFO) << LOG_DESC("create ecdh-psi success"); + +#if 0 +// TODO: optimize here + // init the ecdh-conn-psi + INIT_LOG(INFO) << LOG_DESC("create ecdh-conn-psi"); + auto ecdhConnPSIFactory = std::make_shared(); + m_ecdhConnPSI = ecdhConnPSIFactory->createEcdhConnPSI(m_config, ecdhCryptoFactory, + m_ppcFront, m_protocolInitializer->ppcMsgFactory(), + std::make_shared("t_ecdh-conn-psi", std::thread::hardware_concurrency()), + m_protocolInitializer->dataResourceLoader()); + INIT_LOG(INFO) << LOG_DESC("create ecdh-conn-psi success"); +#endif + // init the ecdh-multi-psi + INIT_LOG(INFO) << LOG_DESC("create ecdh-multi-psi"); + auto ecdhMultiPSIFactory = std::make_shared(); + m_ecdhMultiPSI = ecdhMultiPSIFactory->createEcdhMultiPSI(m_config, m_ppcFront, cryptoBox, + std::make_shared("t_ecdh-multi-psi", std::thread::hardware_concurrency()), + m_protocolInitializer->dataResourceLoader(), m_config->minNeededMemoryGB()); + INIT_LOG(INFO) << LOG_DESC("create ecdh-multi-psi success"); + + // init the ot-pir + INIT_LOG(INFO) << LOG_DESC("create ot-pir"); + auto otPIRFactory = std::make_shared(); + m_otPIR = otPIRFactory->buildOtPIR(m_config->agencyID(), m_ppcFront, cryptoBox, + std::make_shared("t_ot-pir", std::thread::hardware_concurrency()), + m_protocolInitializer->dataResourceLoader(), m_config->holdingMessageMinutes()); + + // auto otPIRImpl = std::make_shared(); + // m_otPIR = otPIRImpl; + // init the bs mode ecdh psi + INIT_LOG(INFO) << LOG_DESC("create bs mode ecdh psi"); + auto bsEcdhPSIFactory = std::make_shared(); + m_bsEcdhPSI = bsEcdhPSIFactory->buildBsEcdhPSI( + std::make_shared("t_bs-ecdh-psi", m_config->threadPoolSize()), + m_protocolInitializer->dataResourceLoader(), m_config->taskTimeoutMinutes(), + m_config->minNeededMemoryGB()); + INIT_LOG(INFO) << LOG_DESC("create bs mode ecdh psi success"); + + initMsgHandlers(); +} + +// init the msg-handlers +void Initializer::initMsgHandlers() +{ + INIT_LOG(INFO) << LOG_DESC("initMsgHandlers for ra2018PSI"); + // register msg-handlers for ra2018-psi + auto weakRA2018PSI = std::weak_ptr(m_ra2018PSI); + m_ppcFront->registerMessageHandler((uint8_t)ppc::protocol::TaskType::PSI, + (uint8_t)ppc::protocol::TaskAlgorithmType::RA_PSI_2PC, + [weakRA2018PSI](ppc::front::PPCMessageFace::Ptr _msg) { + auto psi = weakRA2018PSI.lock(); + if (!psi) + { + return; + } + psi->onReceiveMessage(_msg); + }); + + // register msg-handlers for labeled-psi + INIT_LOG(INFO) << LOG_DESC("initMsgHandlers for labeledPSI"); + auto weakLabeledPSI = std::weak_ptr(m_labeledPSI); + m_ppcFront->registerMessageHandler((uint8_t)ppc::protocol::TaskType::PSI, + (uint8_t)ppc::protocol::TaskAlgorithmType::LABELED_PSI_2PC, + [weakLabeledPSI](ppc::front::PPCMessageFace::Ptr _msg) { + auto psi = weakLabeledPSI.lock(); + if (!psi) + { + return; + } + psi->onReceiveMessage(_msg); + }); + + // register msg-handlers for cm2020-psi + INIT_LOG(INFO) << LOG_DESC("initMsgHandlers for CM2020PSI"); + auto weakCM2020PSI = std::weak_ptr(m_cm2020PSI); + m_ppcFront->registerMessageHandler((uint8_t)ppc::protocol::TaskType::PSI, + (uint8_t)ppc::protocol::TaskAlgorithmType::CM_PSI_2PC, + [weakCM2020PSI](ppc::front::PPCMessageFace::Ptr _msg) { + auto psi = weakCM2020PSI.lock(); + if (!psi) + { + return; + } + psi->onReceiveMessage(_msg); + }); + + INIT_LOG(INFO) << LOG_DESC("initMsgHandlers for ecdh-psi"); + // register msg-handlers for ecdh-psi + auto weakEcdhPSI = std::weak_ptr(m_ecdhPSI); + m_ppcFront->registerMessageHandler((uint8_t)ppc::protocol::TaskType::PSI, + (uint8_t)ppc::protocol::TaskAlgorithmType::ECDH_PSI_2PC, + [weakEcdhPSI](ppc::front::PPCMessageFace::Ptr _msg) { + auto psi = weakEcdhPSI.lock(); + if (!psi) + { + return; + } + psi->onReceiveMessage(_msg); + }); + + // register msg-handlers for ecdh-conn-psi + /*INIT_LOG(INFO) << LOG_DESC("initMsgHandlers for ecdh-conn-psi"); + auto weakEcdhConnPSI = std::weak_ptr(m_ecdhConnPSI); + m_ppcFront->registerMessageHandler((uint8_t)ppc::protocol::TaskType::PSI, + (uint8_t)ppc::protocol::TaskAlgorithmType::ECDH_PSI_CONN, + [weakEcdhConnPSI](ppc::front::PPCMessageFace::Ptr _msg) { + auto psi = weakEcdhConnPSI.lock(); + if (!psi) + { + return; + } + psi->onReceiveMessage(_msg); + });*/ + + // register msg-handlers for ecdh-multi-psi + INIT_LOG(INFO) << LOG_DESC("initMsgHandlers for ecdh-multi-psi"); + auto weakEcdhMultiPSI = std::weak_ptr(m_ecdhMultiPSI); + m_ppcFront->registerMessageHandler((uint8_t)ppc::protocol::TaskType::PSI, + (uint8_t)ppc::protocol::TaskAlgorithmType::ECDH_PSI_MULTI, + [weakEcdhMultiPSI](ppc::front::PPCMessageFace::Ptr _msg) { + auto psi = weakEcdhMultiPSI.lock(); + if (!psi) + { + return; + } + psi->onReceiveMessage(_msg); + }); + + INIT_LOG(INFO) << LOG_DESC("initMsgHandlers for ot-pir"); + // register msg-handlers for ecdh-psi + auto weakOtPIR = std::weak_ptr(m_otPIR); + m_ppcFront->registerMessageHandler((uint8_t)ppc::protocol::TaskType::PIR, + (uint8_t)ppc::protocol::TaskAlgorithmType::OT_PIR_2PC, + [weakOtPIR](ppc::front::PPCMessageFace::Ptr _msg) { + auto pir = weakOtPIR.lock(); + if (!pir) + { + return; + } + pir->onReceiveMessage(_msg); + }); +} + +void Initializer::registerRpcHandler(ppc::rpc::RpcInterface::Ptr const& _rpc) +{ + INIT_LOG(INFO) << LOG_DESC("registerRpcHandler"); + + INIT_LOG(INFO) << LOG_DESC("registerRpcHandler for ra2018PSI"); + // register task handler for ra2018-psi + auto weakRA2018PSI = std::weak_ptr(m_ra2018PSI); + _rpc->registerTaskHandler(ppc::protocol::TaskType::PSI, + (uint8_t)ppc::protocol::TaskAlgorithmType::RA_PSI_2PC, + [weakRA2018PSI](ppc::protocol::Task::ConstPtr _task, + std::function _handler) { + auto ra2018Impl = weakRA2018PSI.lock(); + if (!ra2018Impl) + { + return; + } + ra2018Impl->asyncRunTask(_task, std::move(_handler)); + }); + + // register task handler for labeled-psi + INIT_LOG(INFO) << LOG_DESC("registerRpcHandler for labeledPSI"); + auto weakLabeledPSI = std::weak_ptr(m_labeledPSI); + _rpc->registerTaskHandler(ppc::protocol::TaskType::PSI, + (uint8_t)ppc::protocol::TaskAlgorithmType::LABELED_PSI_2PC, + [weakLabeledPSI](ppc::protocol::Task::ConstPtr _task, + std::function _handler) { + auto labeledPSI = weakLabeledPSI.lock(); + if (!labeledPSI) + { + return; + } + labeledPSI->asyncRunTask(_task, std::move(_handler)); + }); + + // register task handler for cm2020-psi + INIT_LOG(INFO) << LOG_DESC("registerRpcHandler for cm2020PSI"); + auto weakCM2020PSI = std::weak_ptr(m_cm2020PSI); + _rpc->registerTaskHandler(ppc::protocol::TaskType::PSI, + (uint8_t)ppc::protocol::TaskAlgorithmType::CM_PSI_2PC, + [weakCM2020PSI](ppc::protocol::Task::ConstPtr _task, + std::function _handler) { + auto cm2020PSI = weakCM2020PSI.lock(); + if (!cm2020PSI) + { + return; + } + cm2020PSI->asyncRunTask(_task, std::move(_handler)); + }); + + // register task handler for ecdh-psi + INIT_LOG(INFO) << LOG_DESC("registerRpcHandler for ecdhPSI"); + auto weakEcdhPSI = std::weak_ptr(m_ecdhPSI); + _rpc->registerTaskHandler(ppc::protocol::TaskType::PSI, + (uint8_t)ppc::protocol::TaskAlgorithmType::ECDH_PSI_2PC, + [weakEcdhPSI](ppc::protocol::Task::ConstPtr _task, + std::function _handler) { + auto psi = weakEcdhPSI.lock(); + if (!psi) + { + return; + } + psi->asyncRunTask(_task, std::move(_handler)); + }); + + INIT_LOG(INFO) << LOG_DESC("registerRpcHandler for ecdhMultiPSI"); + auto weakEcdhMultiPSI = std::weak_ptr(m_ecdhMultiPSI); + _rpc->registerTaskHandler(ppc::protocol::TaskType::PSI, + (uint8_t)ppc::protocol::TaskAlgorithmType::ECDH_PSI_MULTI, + [weakEcdhMultiPSI](ppc::protocol::Task::ConstPtr _task, + std::function _handler) { + auto psi = weakEcdhMultiPSI.lock(); + if (!psi) + { + return; + } + psi->asyncRunTask(_task, std::move(_handler)); + }); + + /*INIT_LOG(INFO) << LOG_DESC("registerRpcHandler for ecdhConnPSI"); + auto weakEcdhConnPSI = std::weak_ptr(m_ecdhConnPSI); + _rpc->registerTaskHandler(ppc::protocol::TaskType::PSI, + (uint8_t)ppc::protocol::TaskAlgorithmType::ECDH_PSI_CONN, + [weakEcdhConnPSI](ppc::protocol::Task::ConstPtr _task, + std::function _handler) { + auto psi = weakEcdhConnPSI.lock(); + if (!psi) + { + return; + } + psi->asyncRunTask(_task, std::move(_handler)); + });*/ + + // register task handler for ot-pir + INIT_LOG(INFO) << LOG_DESC("registerRpcHandler for otPIR"); + auto weakOtPIR = std::weak_ptr(m_otPIR); + _rpc->registerTaskHandler(ppc::protocol::TaskType::PIR, + (uint8_t)ppc::protocol::TaskAlgorithmType::OT_PIR_2PC, + [weakOtPIR](ppc::protocol::Task::ConstPtr _task, + std::function _handler) { + auto pir = weakOtPIR.lock(); + if (!pir) + { + return; + } + pir->asyncRunTask(_task, std::move(_handler)); + }); +} + +void Initializer::start() +{ + if (m_transport) + { + m_transport->start(); + } + if (m_ppcFront) + { + m_ppcFront->start(); + } + /*if (m_ecdhConnPSI) + { + m_ecdhConnPSI->start(); + }*/ + if (m_ecdhMultiPSI) + { + m_ecdhMultiPSI->start(); + } + if (m_cm2020PSI) + { + m_cm2020PSI->start(); + } + if (m_ra2018PSI) + { + m_ra2018PSI->start(); + } + if (m_labeledPSI) + { + m_labeledPSI->start(); + } + // start the ecdh-psi + if (m_ecdhPSI) + { + m_ecdhPSI->start(); + } + if (m_otPIR) + { + m_otPIR->start(); + } + + if (m_bsEcdhPSI) + { + m_bsEcdhPSI->start(); + } +} + +void Initializer::stop() +{ + if (m_transport) + { + m_transport->stop(); + } + // stop the network firstly + if (m_ppcFront) + { + m_ppcFront->stop(); + } + /*if (m_ecdhConnPSI) + { + m_ecdhConnPSI->stop(); + }*/ + if (m_ecdhMultiPSI) + { + m_ecdhMultiPSI->stop(); + } + if (m_cm2020PSI) + { + m_cm2020PSI->stop(); + } + if (m_ra2018PSI) + { + m_ra2018PSI->stop(); + } + if (m_labeledPSI) + { + m_labeledPSI->stop(); + } + // stop the ecdh-psi + if (m_ecdhPSI) + { + m_ecdhPSI->stop(); + } + if (m_otPIR) + { + m_otPIR->stop(); + } + if (m_bsEcdhPSI) + { + m_bsEcdhPSI->stop(); + } +} diff --git a/cpp/wedpr-initializer/Initializer.h b/cpp/wedpr-initializer/Initializer.h new file mode 100644 index 00000000..76d186d3 --- /dev/null +++ b/cpp/wedpr-initializer/Initializer.h @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2022 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 Initializer.h + * @author: yujiechen + * @date 2022-11-14 + */ +#pragma once +#include "ProtocolInitializer.h" +#include "ppc-framework/front/FrontInterface.h" +#include "ppc-framework/gateway/IGateway.h" +#include "ppc-framework/rpc/RpcInterface.h" +#include "ppc-framework/rpc/RpcTypeDef.h" +#include "ppc-psi/src/bs-ecdh-psi/BsEcdhPSIImpl.h" +#include "wedpr-protocol/protocol/src/ServiceConfig.h" +#include "wedpr-transport/sdk/src/Transport.h" +#include +#include + + +namespace ppc::psi +{ +class RA2018PSIImpl; +class LabeledPSIImpl; +class CM2020PSIImpl; +class EcdhPSIImpl; +class EcdhMultiPSIImpl; +// class EcdhConnPSIImpl; +} // namespace ppc::psi + +namespace ppc::pir +{ +class OtPIRImpl; +} // namespace ppc::pir + +namespace ppc::sdk +{ +class TransportBuilder; +} + +namespace ppc::tools +{ +class PPCConfig; +} +namespace ppc::initializer +{ +class Initializer : public std::enable_shared_from_this +{ +public: + using Ptr = std::shared_ptr; + Initializer(ppc::protocol::NodeArch _arch, std::string const& _configPath); + virtual ~Initializer() { stop(); } + + // init the service + virtual void init(ppc::gateway::IGateway::Ptr const& gateway); + virtual void stop(); + virtual void start(); + + std::shared_ptr config() { return m_config; } + ppc::sdk::Transport::Ptr const& transport() const { return m_transport; } + ppc::front::FrontInterface::Ptr const& ppcFront() const { return m_ppcFront; } + + std::shared_ptr const& config() const { return m_config; } + ProtocolInitializer::Ptr const& protocolInitializer() const { return m_protocolInitializer; } + ppc::psi::BsEcdhPSIImpl::Ptr const& bsEcdhPsi() const { return m_bsEcdhPSI; } + + void registerRpcHandler(ppc::rpc::RpcInterface::Ptr const& _rpc); + +protected: + virtual void initMsgHandlers(); + + +private: + uint16_t m_arch; + std::string m_configPath; + std::shared_ptr m_config; + ProtocolInitializer::Ptr m_protocolInitializer; + ppc::protocol::ServiceConfigBuilder m_serviceConfigBuilder; + + std::shared_ptr m_transportBuilder; + ppc::sdk::Transport::Ptr m_transport; + // created using transport + ppc::front::FrontInterface::Ptr m_ppcFront; + + // the ra2018-psi + std::shared_ptr m_ra2018PSI; + // the labeled-psi + std::shared_ptr m_labeledPSI; + // the cm2020-psi + std::shared_ptr m_cm2020PSI; + // the ecdh-psi + std::shared_ptr m_ecdhPSI; + // the ecdh-multi-psi + std::shared_ptr m_ecdhMultiPSI; + // the ecdh-conn-psi + // std::shared_ptr m_ecdhConnPSI; + + std::shared_ptr m_otPIR; + + std::shared_ptr m_bsEcdhPSI; +}; +} // namespace ppc::initializer \ No newline at end of file diff --git a/cpp/wedpr-initializer/ProtocolInitializer.h b/cpp/wedpr-initializer/ProtocolInitializer.h new file mode 100644 index 00000000..56200e5a --- /dev/null +++ b/cpp/wedpr-initializer/ProtocolInitializer.h @@ -0,0 +1,118 @@ +/* + * Copyright (C) 2022 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 ProtocolInitializer.h + * @author: yujiechen + * @date 2022-11-14 + */ +#pragma once +#include "Common.h" +#include "ppc-crypto-core/src/hash/MD5Hash.h" +#include "ppc-crypto-core/src/hash/SM3Hash.h" +#include "ppc-crypto-core/src/hash/Sha256Hash.h" +#include "ppc-crypto/src/ecc/Ed25519EccCrypto.h" +#include "ppc-crypto/src/ecc/OpenSSLEccCrypto.h" +#include "ppc-framework/crypto/CryptoBox.h" +#include "ppc-framework/protocol/GlobalConfig.h" +#include "ppc-framework/protocol/PPCMessageFace.h" +#include "ppc-io/src/DataResourceLoaderImpl.h" +#include "ppc-storage/src/FileStorageFactoryImpl.h" +#include "ppc-storage/src/SQLStorageFactoryImpl.h" +#include "ppc-tools/src/config/PPCConfig.h" +#include "protocol/src/PPCMessage.h" +#include +#include + +namespace ppc::initializer +{ +class ProtocolInitializer +{ +public: + using Ptr = std::shared_ptr; + ProtocolInitializer() + : m_ppcMsgFactory(std::make_shared()), + m_sqlStorageFactory(std::make_shared()), + m_fileStorageFactory(std::make_shared()) + {} + + virtual ~ProtocolInitializer() = default; + + virtual void init(ppc::tools::PPCConfig::Ptr _config) + { + m_dataResourceLoader = std::make_shared( + _config->storageConfig().sqlConnectionOpt, + _config->storageConfig().fileStorageConnectionOpt, + _config->storageConfig().remoteConnectionOpt, m_sqlStorageFactory, m_fileStorageFactory, + m_remoteStorageFactory); + + g_PPCConfig.setSMCrypto(_config->smCrypto()); + if (!_config->smCrypto()) + { + auto hashImpl = std::make_shared(); + auto eccCrypto = std::make_shared( + hashImpl, ppc::protocol::ECCCurve::P256); + m_cryptoBox = std::make_shared(hashImpl, eccCrypto); + m_binHashImpl = std::make_shared(); + } + else + { + auto hashImpl = std::make_shared(); + auto eccCrypto = std::make_shared( + hashImpl, ppc::protocol::ECCCurve::SM2); + m_cryptoBox = std::make_shared(hashImpl, eccCrypto); + m_binHashImpl = hashImpl; + } + INIT_LOG(INFO) << LOG_DESC("loadPrivateKey") + << LOG_KV("privateKeyPath", _config->privateKeyPath()); + auto privateKey = loadPrivateKey(_config->privateKeyPath(), PRIVATE_KEY_HEX_LEN); + _config->setPrivateKey(privateKey); + INIT_LOG(INFO) << LOG_DESC("loadPrivateKey success"); + } + + ppc::front::PPCMessageFaceFactory::Ptr const& ppcMsgFactory() const { return m_ppcMsgFactory; } + ppc::crypto::CryptoBox::Ptr const& cryptoBox() const { return m_cryptoBox; }; + ppc::crypto::Hash::Ptr const& binHashImpl() const { return m_binHashImpl; }; + + ppc::storage::SQLStorageFactory::Ptr const& sqlStorageFactory() const + { + return m_sqlStorageFactory; + } + ppc::io::DataResourceLoader::Ptr const& dataResourceLoader() const + { + return m_dataResourceLoader; + } + + ppc::storage::FileStorageFactory::Ptr const& fileStorageFactory() const + { + return m_fileStorageFactory; + } + + ppc::storage::RemoteStorageFactory::Ptr const& remoteStorageFactory() const + { + return m_remoteStorageFactory; + } + +private: + ppc::front::PPCMessageFaceFactory::Ptr m_ppcMsgFactory; + ppc::storage::SQLStorageFactory::Ptr m_sqlStorageFactory; + ppc::storage::FileStorageFactory::Ptr m_fileStorageFactory; + ppc::storage::RemoteStorageFactory::Ptr m_remoteStorageFactory; + ppc::io::DataResourceLoader::Ptr m_dataResourceLoader; + ppc::crypto::CryptoBox::Ptr m_cryptoBox; + ppc::crypto::Hash::Ptr m_binHashImpl; + + constexpr static unsigned PRIVATE_KEY_HEX_LEN = 64; +}; +} // namespace ppc::initializer \ No newline at end of file diff --git a/cpp/wedpr-main/CMakeLists.txt b/cpp/wedpr-main/CMakeLists.txt new file mode 100644 index 00000000..95d0d4b6 --- /dev/null +++ b/cpp/wedpr-main/CMakeLists.txt @@ -0,0 +1,11 @@ +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) +add_subdirectory(air-node) +add_subdirectory(pro-node) +add_subdirectory(gateway) + +if (BUILD_CEM) + add_subdirectory(cem-node) +endif () +add_subdirectory(mpc-node) + +unset(CMAKE_RUNTIME_OUTPUT_DIRECTORY) \ No newline at end of file diff --git a/cpp/wedpr-main/air-node/AirNodeInitializer.cpp b/cpp/wedpr-main/air-node/AirNodeInitializer.cpp new file mode 100644 index 00000000..a9636629 --- /dev/null +++ b/cpp/wedpr-main/air-node/AirNodeInitializer.cpp @@ -0,0 +1,123 @@ +/** + * Copyright (C) 2022 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 AirNodeInitializer.cpp + * @author: yujiechen + * @date 2022-11-14 + */ +#include "AirNodeInitializer.h" +#include "ppc-front/LocalFrontBuilder.h" +#include "ppc-gateway/GatewayFactory.h" +#include "ppc-rpc/src/RpcFactory.h" +#include "ppc-rpc/src/RpcMemory.h" + +using namespace ppc::protocol; +using namespace ppc::front; +using namespace ppc::node; +using namespace ppc::gateway; +using namespace ppc::rpc; +using namespace ppc::storage; +using namespace ppc::initializer; +using namespace bcos; + +AirNodeInitializer::AirNodeInitializer() +{ + m_frontBuilder = std::make_shared(); +} +void AirNodeInitializer::init(std::string const& _configPath) +{ + // init the log + boost::property_tree::ptree pt; + boost::property_tree::read_ini(_configPath, pt); + + m_logInitializer = std::make_shared(); + m_logInitializer->initLog(pt); + INIT_LOG(INFO) << LOG_DESC("initLog success"); + + // init the node + m_nodeInitializer = std::make_shared(ppc::protocol::NodeArch::AIR, _configPath); + // load the rpc config + m_nodeInitializer->config()->loadRpcConfig(pt); + + // init the gateway + initGateway(_configPath); + // init the node + m_nodeInitializer->init(m_gateway); + // set the created front to the builder + m_frontBuilder->setFront(m_nodeInitializer->transport()->getFront()); + // register the NodeInfo + m_gateway->registerNodeInfo(m_nodeInitializer->config()->frontConfig()->generateNodeInfo()); + + INIT_LOG(INFO) << LOG_DESC("init the rpc"); + // init RpcStatusInterface + RpcStatusInterface::Ptr rpcStatusInterface = + std::make_shared(m_nodeInitializer->ppcFront()); + + + auto rpcFactory = std::make_shared(m_nodeInitializer->config()->agencyID()); + m_rpc = rpcFactory->buildRpc(m_nodeInitializer->config(), m_gateway); + m_rpc->setRpcStorage(rpcStatusInterface); + m_rpc->setBsEcdhPSI(m_nodeInitializer->bsEcdhPsi()); + m_nodeInitializer->registerRpcHandler(m_rpc); + + INIT_LOG(INFO) << LOG_DESC("init the rpc success"); +} + +void AirNodeInitializer::initGateway(std::string const& _configPath) +{ + INIT_LOG(INFO) << LOG_DESC("initGateway: ") << _configPath; + // not specify the certPath in air-mode + auto config = m_nodeInitializer->config(); + config->loadGatewayConfig(_configPath, false); + + auto threadPool = std::make_shared( + "gateway", config->gatewayConfig().networkConfig.threadPoolSize); + + GatewayFactory gatewayFactory(config); + m_gateway = gatewayFactory.build(m_frontBuilder); +} + +void AirNodeInitializer::start() +{ + // start the node + if (m_nodeInitializer) + { + m_nodeInitializer->start(); + } + if (m_gateway) + { + m_gateway->start(); + } + if (m_rpc) + { + m_rpc->start(); + } +} + +void AirNodeInitializer::stop() +{ + if (m_rpc) + { + m_rpc->stop(); + } + if (m_gateway) + { + m_gateway->stop(); + } + if (m_nodeInitializer) + { + m_nodeInitializer->stop(); + } +} \ No newline at end of file diff --git a/cpp/wedpr-main/air-node/AirNodeInitializer.h b/cpp/wedpr-main/air-node/AirNodeInitializer.h new file mode 100644 index 00000000..0366a179 --- /dev/null +++ b/cpp/wedpr-main/air-node/AirNodeInitializer.h @@ -0,0 +1,58 @@ +/** + * Copyright (C) 2022 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 AirNodeInitializer.h + * @author: yujiechen + * @date 2022-11-14 + */ +#pragma once +#include "ppc-framework/front/IFront.h" +#include "ppc-framework/gateway/IGateway.h" +#include "wedpr-initializer/Common.h" +#include "wedpr-initializer/Initializer.h" +#include +#include +namespace ppc::rpc +{ +class Rpc; +} +namespace ppc::front +{ +class LocalFrontBuilder; +} +namespace ppc::node +{ +class AirNodeInitializer +{ +public: + using Ptr = std::shared_ptr; + AirNodeInitializer(); + virtual ~AirNodeInitializer() { stop(); } + + virtual void init(std::string const& _configPath); + virtual void start(); + virtual void stop(); + +protected: + virtual void initGateway(std::string const& _configPath); + +private: + bcos::BoostLogInitializer::Ptr m_logInitializer; + ppc::initializer::Initializer::Ptr m_nodeInitializer; + ppc::gateway::IGateway::Ptr m_gateway; + std::shared_ptr m_rpc; + std::shared_ptr m_frontBuilder; +}; +} // namespace ppc::node \ No newline at end of file diff --git a/cpp/wedpr-main/air-node/CMakeLists.txt b/cpp/wedpr-main/air-node/CMakeLists.txt new file mode 100644 index 00000000..263c69f8 --- /dev/null +++ b/cpp/wedpr-main/air-node/CMakeLists.txt @@ -0,0 +1,4 @@ +aux_source_directory(. SRC_LIST) + +add_executable(${AIR_BINARY_NAME} ${SRC_LIST}) +target_link_libraries(${AIR_BINARY_NAME} PUBLIC ${GATEWAY_TARGET} ${RPC_TARGET} ${INIT_LIB} ${HELPER_TARGET}) \ No newline at end of file diff --git a/cpp/wedpr-main/air-node/main.cpp b/cpp/wedpr-main/air-node/main.cpp new file mode 100644 index 00000000..ae54afee --- /dev/null +++ b/cpp/wedpr-main/air-node/main.cpp @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2022 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 main.cpp + * @author: yujiechen + * @date 2022-11-14 + */ +#include "AirNodeInitializer.h" +#include "wedpr-main/common/NodeStarter.h" + +int main(int argc, const char* argv[]) +{ + std::string binaryName = "ppc-psi"; + auto initializer = std::make_shared(); + auto ret = startProgram(argc, argv, binaryName, initializer); + initializer.reset(); + std::cout << "[" << bcos::getCurrentDateTime() << "] "; + std::cout << "The " << binaryName << " program exit normally." << std::endl; + return ret; +} \ No newline at end of file diff --git a/cpp/wedpr-main/cem-node/CEMInitializer.cpp b/cpp/wedpr-main/cem-node/CEMInitializer.cpp new file mode 100644 index 00000000..e228fa5a --- /dev/null +++ b/cpp/wedpr-main/cem-node/CEMInitializer.cpp @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2022 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 CEMInitializer.cpp + * @author: caryliao + * @date 2022-11-19 + */ +#include "CEMInitializer.h" +#include "ppc-cem/src/CEMService.h" + +using namespace ppc::rpc; +using namespace bcos; +using namespace ppc::cem; +using namespace ppc::tools; + +void CEMInitializer::init(std::string const& _configPath) +{ + // init the log + boost::property_tree::ptree pt; + boost::property_tree::read_ini(_configPath, pt); + + m_logInitializer = std::make_shared(); + m_logInitializer->initLog(pt); + INIT_LOG(INFO) << LOG_DESC("initLog success"); + + // init the rpc + INIT_LOG(INFO) << LOG_DESC("init the rpc"); + // load the rpc config + auto ppcConfig = std::make_shared(); + // not specify the certPath in air-mode + ppcConfig->loadRpcConfig(pt); + ppcConfig->loadCEMConfig(pt); + // bool useMysql = pt.get("cem.use_mysql", false); + auto storageConfig = ppcConfig->storageConfig(); + auto cemConfig = ppcConfig->cemConfig(); + auto rpcFactory = std::make_shared(ppcConfig->agencyID()); + m_rpc = rpcFactory->buildRpc(ppcConfig, nullptr); + auto cemService = std::make_shared(); + cemService->setCEMConfig(cemConfig); + cemService->setStorageConfig(storageConfig); + m_rpc->registerHandler("match", std::bind(&CEMService::makeCiphertextEqualityMatchRpc, + cemService, std::placeholders::_1, std::placeholders::_2)); + m_rpc->registerHandler("encrypt", std::bind(&CEMService::encryptDatasetRpc, cemService, + std::placeholders::_1, std::placeholders::_2)); + + INIT_LOG(INFO) << LOG_DESC("init the rpc success"); +} + +void CEMInitializer::start() +{ + // start the ppc cem + if (m_rpc) + { + m_rpc->start(); + } +} + +void CEMInitializer::stop() +{ + if (m_rpc) + { + m_rpc->stop(); + } +} diff --git a/cpp/wedpr-main/cem-node/CEMInitializer.h b/cpp/wedpr-main/cem-node/CEMInitializer.h new file mode 100644 index 00000000..1ba25899 --- /dev/null +++ b/cpp/wedpr-main/cem-node/CEMInitializer.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2022 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 CEMInitializer.h + * @author: caryliao + * @date 2022-11-19 + */ +#pragma once +#include "ppc-rpc/src/RpcFactory.h" +#include "wedpr-initializer/Common.h" +#include +#include +namespace ppc::rpc +{ +class Rpc; +} +namespace ppc::cem +{ +class CEMInitializer +{ +public: + using Ptr = std::shared_ptr; + CEMInitializer() {} + virtual ~CEMInitializer() { stop(); } + + virtual void init(std::string const& _configPath); + virtual void start(); + virtual void stop(); + +private: + bcos::BoostLogInitializer::Ptr m_logInitializer; + std::shared_ptr m_rpc; +}; +} // namespace ppc::cem \ No newline at end of file diff --git a/cpp/wedpr-main/cem-node/CMakeLists.txt b/cpp/wedpr-main/cem-node/CMakeLists.txt new file mode 100644 index 00000000..0b8957d9 --- /dev/null +++ b/cpp/wedpr-main/cem-node/CMakeLists.txt @@ -0,0 +1,4 @@ +aux_source_directory(. SRC_LIST) + +add_executable(${CEM_BINARY_NAME} ${SRC_LIST}) +target_link_libraries(${CEM_BINARY_NAME} PUBLIC ${CEM_TARGET} ${RPC_TARGET} ${HELPER_TARGET}) diff --git a/cpp/wedpr-main/cem-node/main.cpp b/cpp/wedpr-main/cem-node/main.cpp new file mode 100644 index 00000000..a34f1093 --- /dev/null +++ b/cpp/wedpr-main/cem-node/main.cpp @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2022 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 main.cpp + * @author: caryliao + * @date 2022-11-19 + */ +#include "CEMInitializer.h" +#include +#include +#include +#include +#include + +using namespace ppc; + +int main(int argc, const char* argv[]) +{ + /// set LC_ALL + setDefaultOrCLocale(); + std::set_terminate([]() { + std::cerr << "terminate handler called, print stacks" << std::endl; + void* trace_elems[20]; + int trace_elem_count(backtrace(trace_elems, 20)); + char** stack_syms(backtrace_symbols(trace_elems, trace_elem_count)); + for (int i = 0; i < trace_elem_count; ++i) + { + std::cout << stack_syms[i] << "\n"; + } + free(stack_syms); + std::cerr << "terminate handler called, print stack end" << std::endl; + abort(); + }); + // get datetime and output welcome info + ExitHandler exitHandler; + signal(SIGTERM, &ExitHandler::exitHandler); + signal(SIGABRT, &ExitHandler::exitHandler); + signal(SIGINT, &ExitHandler::exitHandler); + + // Note: the initializer must exist in the life time of the whole program + auto initializer = std::make_shared(); + try + { + auto param = initCommandLine("wedpr-cem", argc, argv); + initializer->init(param.configFilePath); + initializer->start(); + } + catch (std::exception const& e) + { + printVersion("wedpr-cem"); + std::cout << "[" << bcos::getCurrentDateTime() << "] "; + std::cout << "start ppc-cem failed, error:" << boost::diagnostic_information(e) + << std::endl; + return -1; + } + printVersion("wedpr-cem"); + std::cout << "[" << bcos::getCurrentDateTime() << "] "; + std::cout << "The ppc-cem is running..." << std::endl; + while (!exitHandler.shouldExit()) + { + std::this_thread::sleep_for(std::chrono::milliseconds(200)); + } + initializer.reset(); + std::cout << "[" << bcos::getCurrentDateTime() << "] "; + std::cout << "ppc-cem program exit normally." << std::endl; +} diff --git a/cpp/wedpr-main/common/NodeStarter.h b/cpp/wedpr-main/common/NodeStarter.h new file mode 100644 index 00000000..fd08bd41 --- /dev/null +++ b/cpp/wedpr-main/common/NodeStarter.h @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2022 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 main.cpp + * @author: yujiechen + * @date 2022-11-14 + */ + +#include +#include +#include +#include +#include +#include + +namespace ppc::node +{ +template +int startProgram( + int argc, const char* argv[], std::string const& binaryName, std::shared_ptr starter) +{ + /// set LC_ALL + setDefaultOrCLocale(); + std::set_terminate([]() { + std::cout << "terminate handler called, print stacks" << std::endl; + void* trace_elems[20]; + int trace_elem_count(backtrace(trace_elems, 20)); + char** stack_syms(backtrace_symbols(trace_elems, trace_elem_count)); + for (int i = 0; i < trace_elem_count; ++i) + { + std::cout << stack_syms[i] << "\n"; + } + free(stack_syms); + std::cout << "terminate handler called, print stack end" << std::endl; + abort(); + }); + // get datetime and output welcome info + ppc::ExitHandler exitHandler; + signal(SIGTERM, &ppc::ExitHandler::exitHandler); + signal(SIGABRT, &ppc::ExitHandler::exitHandler); + signal(SIGINT, &ppc::ExitHandler::exitHandler); + + // Note: the initializer must exist in the life time of the whole program + try + { + auto param = ppc::initCommandLine(binaryName, argc, argv); + starter->init(param.configFilePath); + starter->start(); + } + catch (std::exception const& e) + { + printVersion(binaryName); + std::cout << "[" << bcos::getCurrentDateTime() << "] "; + std::cout << "start " + binaryName + " failed, error:" << boost::diagnostic_information(e) + << std::endl; + return -1; + } + printVersion(binaryName); + std::cout << "[" << bcos::getCurrentDateTime() << "] "; + std::cout << "The " + binaryName + " is running..." << std::endl; + while (!exitHandler.shouldExit()) + { + std::this_thread::sleep_for(std::chrono::milliseconds(200)); + } + return 0; +} +} // namespace ppc::node \ No newline at end of file diff --git a/cpp/wedpr-main/gateway/CMakeLists.txt b/cpp/wedpr-main/gateway/CMakeLists.txt new file mode 100644 index 00000000..29b6af84 --- /dev/null +++ b/cpp/wedpr-main/gateway/CMakeLists.txt @@ -0,0 +1,7 @@ +include_directories(${CMAKE_SOURCE_DIR}) + + +aux_source_directory(./ SRC_LIST) +add_executable(${GATEWAY_BINARY_NAME} ${SRC_LIST}) + +target_link_libraries(${GATEWAY_BINARY_NAME} ${GATEWAY_TARGET} ${SERVICE_CLIENT_TARGET} ${SERVICE_SERVER_TARGET} ${HELPER_TARGET}) \ No newline at end of file diff --git a/cpp/wedpr-main/gateway/GatewayInitializer.cpp b/cpp/wedpr-main/gateway/GatewayInitializer.cpp new file mode 100644 index 00000000..8a2950bc --- /dev/null +++ b/cpp/wedpr-main/gateway/GatewayInitializer.cpp @@ -0,0 +1,95 @@ +/** + * Copyright (C) 2022 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 GatewayInitializer.cpp + * @author: yujiechen + * @date 2022-11-14 + */ +#include "GatewayInitializer.h" +#include "grpc/server/GatewayServer.h" +#include "grpc/server/GrpcServer.h" +#include "ppc-gateway/GatewayFactory.h" +#include "ppc-tools/src/config/PPCConfig.h" +#include "protobuf/src/NodeInfoImpl.h" +#include "wedpr-protocol/grpc/client/HealthCheckTimer.h" +#include "wedpr-protocol/grpc/client/RemoteFrontBuilder.h" +#include "wedpr-protocol/protocol/src/v1/MessageHeaderImpl.h" + +using namespace ppc::tools; +using namespace ppc::protocol; +using namespace bcos; +using namespace ppc::gateway; +using namespace ppc::front; + +void GatewayInitializer::init(std::string const& _configPath) +{ + // init the log + boost::property_tree::ptree pt; + boost::property_tree::read_ini(_configPath, pt); + + m_logInitializer = std::make_shared(); + m_logInitializer->initLog(pt); + INIT_LOG(INFO) << LOG_DESC("initLog success"); + + INIT_LOG(INFO) << LOG_DESC("initGateway: ") << _configPath; + auto config = std::make_shared(); + + config->loadGatewayConfig(_configPath, true); + auto threadPool = std::make_shared( + "gateway", config->gatewayConfig().networkConfig.threadPoolSize); + + GatewayFactory gatewayFactory(config); + // default 1min + m_healthChecker = std::make_shared(60 * 1000); + m_gateway = gatewayFactory.build( + std::make_shared(config->grpcConfig(), m_healthChecker)); + + m_server = std::make_shared(config->gatewayConfig().grpcServerConfig); + // register the gateway service + auto gatewayService = std::make_shared(m_gateway, + std::make_shared(), std::make_shared()); + m_server->registerService(gatewayService); +} + +void GatewayInitializer::start() +{ + if (m_gateway) + { + m_gateway->start(); + } + if (m_server) + { + m_server->start(); + } + if (m_healthChecker) + { + m_healthChecker->start(); + } +} +void GatewayInitializer::stop() +{ + if (m_healthChecker) + { + m_healthChecker->stop(); + } + if (m_server) + { + m_server->stop(); + } + if (m_gateway) + { + m_gateway->stop(); + } +} \ No newline at end of file diff --git a/cpp/wedpr-main/gateway/GatewayInitializer.h b/cpp/wedpr-main/gateway/GatewayInitializer.h new file mode 100644 index 00000000..2fdacded --- /dev/null +++ b/cpp/wedpr-main/gateway/GatewayInitializer.h @@ -0,0 +1,54 @@ +/** + * Copyright (C) 2022 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 GatewayInitializer.h + * @author: yujiechen + * @date 2022-11-14 + */ +#pragma once +#include "ppc-framework/gateway/IGateway.h" +#include +#include +#include + +#define INIT_LOG(LEVEL) BCOS_LOG(LEVEL) << LOG_BADGE("GATEWAYInit") +namespace ppc::protocol +{ +class GrpcServer; +} +namespace ppc::protocol +{ +class HealthCheckTimer; +}; +namespace ppc::gateway +{ +class GatewayInitializer +{ +public: + using Ptr = std::shared_ptr; + GatewayInitializer() = default; + virtual ~GatewayInitializer() { stop(); } + + virtual void init(std::string const& _configPath); + virtual void start(); + virtual void stop(); + +protected: + bcos::BoostLogInitializer::Ptr m_logInitializer; + ppc::gateway::IGateway::Ptr m_gateway; + std::shared_ptr m_healthChecker; + std::shared_ptr m_server; +}; +} // namespace ppc::gateway \ No newline at end of file diff --git a/cpp/wedpr-main/gateway/main.cpp b/cpp/wedpr-main/gateway/main.cpp new file mode 100644 index 00000000..c8795457 --- /dev/null +++ b/cpp/wedpr-main/gateway/main.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2022 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 main.cpp + * @author: yujiechen + * @date 2022-11-14 + */ +#include "GatewayInitializer.h" +#include "wedpr-main/common/NodeStarter.h" + +using namespace ppc::node; +int main(int argc, const char* argv[]) +{ + std::string binaryName = "ppc-gateway-service"; + auto initializer = std::make_shared(); + auto ret = startProgram(argc, argv, binaryName, initializer); + initializer.reset(); + std::cout << "[" << bcos::getCurrentDateTime() << "] "; + std::cout << "The " << binaryName << " program exit normally." << std::endl; + return ret; +} \ No newline at end of file diff --git a/cpp/wedpr-main/mpc-node/CMakeLists.txt b/cpp/wedpr-main/mpc-node/CMakeLists.txt new file mode 100644 index 00000000..2ca48eba --- /dev/null +++ b/cpp/wedpr-main/mpc-node/CMakeLists.txt @@ -0,0 +1,4 @@ +aux_source_directory(. SRC_LIST) + +add_executable(${MPC_BINARY_NAME} ${SRC_LIST}) +target_link_libraries(${MPC_BINARY_NAME} PUBLIC ${WEDPR_TRANSPORT_SDK_TARGET} ${MPC_TARGET} ${RPC_TARGET} ${HELPER_TARGET} TBB::tbb) diff --git a/cpp/wedpr-main/mpc-node/MPCInitializer.cpp b/cpp/wedpr-main/mpc-node/MPCInitializer.cpp new file mode 100644 index 00000000..eb3deb63 --- /dev/null +++ b/cpp/wedpr-main/mpc-node/MPCInitializer.cpp @@ -0,0 +1,136 @@ +/* + * Copyright (C) 2022 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 MPCInitializer.cpp + * @author: caryliao + * @date 2023-03-24 + */ +#include "MPCInitializer.h" +#include "ppc-framework/front/FrontConfig.h" +#include "ppc-framework/protocol/Constant.h" +#include "ppc-mpc/src/MPCService.h" +#include "ppc-tools/src/config/PPCConfig.h" +#include "wedpr-helper/ppc-utilities/Utilities.h" +#include "wedpr-protocol/protocol/src/ServiceConfig.h" +#include "wedpr-transport/sdk/src/TransportBuilder.h" + +using namespace ppc::rpc; +using namespace bcos; +using namespace ppc::sdk; +using namespace ppc::mpc; +using namespace ppc::tools; +using namespace ppc::front; +using namespace ppc::protocol; + +MPCInitializer::MPCInitializer() : m_transportBuilder(std::make_shared()) {} + +void MPCInitializer::init(std::string const& _configPath) +{ + // init the log + boost::property_tree::ptree pt; + boost::property_tree::read_ini(_configPath, pt); + + m_logInitializer = std::make_shared(); + m_logInitializer->initLog(pt); + INIT_LOG(INFO) << LOG_DESC("initLog success"); + + // init the rpc + INIT_LOG(INFO) << LOG_DESC("init the rpc"); + // load the rpc config + m_config = std::make_shared(); + m_config->loadRpcConfig(pt); + m_config->loadMPCConfig(pt); + // bool useMysql = pt.get("mpc.use_mysql", false); + auto storageConfig = m_config->storageConfig(); + auto mpcConfig = m_config->mpcConfig(); + auto rpcFactory = std::make_shared(m_config->agencyID()); + m_rpc = rpcFactory->buildRpc(m_config, nullptr); + + int threadPoolSize = mpcConfig.threadPoolSize; + auto threadPool = std::make_shared("mpc-pool", threadPoolSize); + + INIT_LOG(INFO) << LOG_DESC("init the mpc threadpool") + << LOG_KV("threadPoolSize", threadPoolSize); + + auto mpcService = std::make_shared(); + mpcService->setMPCConfig(mpcConfig); + mpcService->setStorageConfig(storageConfig); + mpcService->setThreadPool(threadPool); + + m_rpc->registerHandler("run", std::bind(&MPCService::runMpcRpc, mpcService, + std::placeholders::_1, std::placeholders::_2)); + m_rpc->registerHandler("asyncRun", std::bind(&MPCService::asyncRunMpcRpc, mpcService, + std::placeholders::_1, std::placeholders::_2)); + m_rpc->registerHandler("kill", std::bind(&MPCService::killMpcRpc, mpcService, + std::placeholders::_1, std::placeholders::_2)); + m_rpc->registerHandler("query", std::bind(&MPCService::queryMpcRpc, mpcService, + std::placeholders::_1, std::placeholders::_2)); + INIT_LOG(INFO) << LOG_DESC("init the mpc rpc success"); + // init the transport + initTransport(pt); +} + +void MPCInitializer::initTransport(boost::property_tree::ptree const& property) +{ + INIT_LOG(INFO) << LOG_DESC("initTransport: load front config"); + m_config->loadFrontConfig(true, m_transportBuilder->frontConfigBuilder(), property); + INIT_LOG(INFO) << LOG_DESC("initTransport: load front config success"); + + // add the service meta + ServiceConfigBuilder serviceConfigBuilder; + auto serviceConfig = serviceConfigBuilder.buildServiceConfig(); + + auto mpcEntryPoint = + serviceConfigBuilder.buildEntryPoint(getServiceName(m_config->agencyID(), MPC_SERVICE_TYPE), m_config->accessEntrypoint()); + serviceConfig.addEntryPoint(mpcEntryPoint); + + auto spdzEntryPoint = + serviceConfigBuilder.buildEntryPoint(getServiceName(m_config->agencyID(), SPDZ_SERVICE_TYPE), m_config->spdzConnectedEndPoint()); + serviceConfig.addEntryPoint(spdzEntryPoint); + + auto serviceMeta = serviceConfig.encode(); + m_config->frontConfig()->setMeta(serviceMeta); + INIT_LOG(INFO) << LOG_DESC("initTransport: register serviceMeta") + << LOG_KV("serviceMeta", serviceMeta); + INIT_LOG(INFO) << LOG_DESC("initTransport: buildProTransport"); + m_transport = m_transportBuilder->buildProTransport(m_config->frontConfig()); + INIT_LOG(INFO) << LOG_DESC("initTransport: buildProTransport success"); +} + +void MPCInitializer::start() +{ + // start the transport + if (m_transport) + { + m_transport->start(); + } + // start the ppc mpc + if (m_rpc) + { + m_rpc->start(); + } +} + +void MPCInitializer::stop() +{ + if (m_rpc) + { + m_rpc->stop(); + } + if (m_transport) + { + m_transport->stop(); + } +} diff --git a/cpp/wedpr-main/mpc-node/MPCInitializer.h b/cpp/wedpr-main/mpc-node/MPCInitializer.h new file mode 100644 index 00000000..7606dbce --- /dev/null +++ b/cpp/wedpr-main/mpc-node/MPCInitializer.h @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2022 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 MPCInitializer.h + * @author: caryliao + * @date 2023-03-24 + */ +#pragma once +#include "ppc-rpc/src/RpcFactory.h" +#include "wedpr-initializer/Common.h" +#include +#include +namespace ppc::rpc +{ +class Rpc; +} +namespace ppc::tools +{ +class PPCConfig; +} +namespace ppc::sdk +{ +class TransportBuilder; +class Transport; +}; // namespace ppc::sdk +namespace ppc::mpc +{ +class MPCInitializer +{ +public: + using Ptr = std::shared_ptr; + MPCInitializer(); + virtual ~MPCInitializer() { stop(); } + + virtual void init(std::string const& _configPath); + virtual void start(); + virtual void stop(); + +protected: + virtual void initTransport(boost::property_tree::ptree const& property); + +private: + std::shared_ptr m_config; + std::shared_ptr m_transportBuilder; + std::shared_ptr m_transport; + + bcos::BoostLogInitializer::Ptr m_logInitializer; + std::shared_ptr m_rpc; +}; +} // namespace ppc::mpc \ No newline at end of file diff --git a/cpp/wedpr-main/mpc-node/main.cpp b/cpp/wedpr-main/mpc-node/main.cpp new file mode 100644 index 00000000..1df02246 --- /dev/null +++ b/cpp/wedpr-main/mpc-node/main.cpp @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2022 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 main.cpp + * @author: caryliao + * @date 2023-03-24 + */ +#include "MPCInitializer.h" +#include +#include +#include +#include +#include + +using namespace ppc; + +int main(int argc, const char* argv[]) +{ + /// set LC_ALL + setDefaultOrCLocale(); + std::set_terminate([]() { + std::cerr << "terminate handler called, print stacks" << std::endl; + void* trace_elems[20]; + int trace_elem_count(backtrace(trace_elems, 20)); + char** stack_syms(backtrace_symbols(trace_elems, trace_elem_count)); + for (int i = 0; i < trace_elem_count; ++i) + { + std::cout << stack_syms[i] << "\n"; + } + free(stack_syms); + std::cerr << "terminate handler called, print stack end" << std::endl; + abort(); + }); + // get datetime and output welcome info + ExitHandler exitHandler; + signal(SIGTERM, &ExitHandler::exitHandler); + signal(SIGABRT, &ExitHandler::exitHandler); + signal(SIGINT, &ExitHandler::exitHandler); + + // Note: the initializer must exist in the life time of the whole program + auto initializer = std::make_shared(); + try + { + auto param = initCommandLine("wedpr-mpc", argc, argv); + initializer->init(param.configFilePath); + initializer->start(); + } + catch (std::exception const& e) + { + printVersion("wedpr-mpc"); + std::cout << "[" << bcos::getCurrentDateTime() << "] "; + std::cout << "start ppc-mpc failed, error:" << boost::diagnostic_information(e) + << std::endl; + return -1; + } + printVersion("wedpr-mpc"); + std::cout << "[" << bcos::getCurrentDateTime() << "] "; + std::cout << "The ppc-mpc is running..." << std::endl; + while (!exitHandler.shouldExit()) + { + std::this_thread::sleep_for(std::chrono::milliseconds(200)); + } + initializer.reset(); + std::cout << "[" << bcos::getCurrentDateTime() << "] "; + std::cout << "ppc-mpc program exit normally." << std::endl; +} diff --git a/cpp/wedpr-main/pro-node/CMakeLists.txt b/cpp/wedpr-main/pro-node/CMakeLists.txt new file mode 100644 index 00000000..b4745a32 --- /dev/null +++ b/cpp/wedpr-main/pro-node/CMakeLists.txt @@ -0,0 +1,6 @@ +include_directories(${CMAKE_SOURCE_DIR}) + +aux_source_directory(./ SRC_LIST) +add_executable(${PRO_BINARY_NAME} ${SRC_LIST}) + +target_link_libraries(${PRO_BINARY_NAME} ${RPC_TARGET} ${INIT_LIB} ${HELPER_TARGET}) diff --git a/cpp/wedpr-main/pro-node/ProNodeInitializer.cpp b/cpp/wedpr-main/pro-node/ProNodeInitializer.cpp new file mode 100644 index 00000000..f92750c8 --- /dev/null +++ b/cpp/wedpr-main/pro-node/ProNodeInitializer.cpp @@ -0,0 +1,93 @@ +/** + * Copyright (C) 2022 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 ProNodeInitializer.cpp + * @author: yujiechen + * @date 2022-11-14 + */ +#include "ProNodeInitializer.h" +#include "ppc-rpc/src/RpcFactory.h" +#include "ppc-rpc/src/RpcMemory.h" +#include "wedpr-protocol/grpc/client/RemoteFrontBuilder.h" + +using namespace ppc::protocol; +using namespace ppc::node; +using namespace ppc::gateway; +using namespace ppc::rpc; +using namespace ppc::storage; +using namespace ppc::initializer; +using namespace bcos; + +ProNodeInitializer::ProNodeInitializer() {} + +void ProNodeInitializer::init(std::string const& _configPath) +{ + // init the log + boost::property_tree::ptree pt; + boost::property_tree::read_ini(_configPath, pt); + + m_logInitializer = std::make_shared(); + m_logInitializer->initLog(pt); + INIT_LOG(INFO) << LOG_DESC("initLog success"); + + // init the node + m_nodeInitializer = std::make_shared(ppc::protocol::NodeArch::PRO, _configPath); + // load the rpc config + m_nodeInitializer->config()->loadRpcConfig(pt); + + // init the node(no need to set the gateway) + m_nodeInitializer->init(nullptr); + + + INIT_LOG(INFO) << LOG_DESC("init the rpc"); + // init RpcStatusInterface + RpcStatusInterface::Ptr rpcStatusInterface = + std::make_shared(m_nodeInitializer->ppcFront()); + + + auto rpcFactory = std::make_shared(m_nodeInitializer->config()->agencyID()); + m_rpc = rpcFactory->buildRpc( + m_nodeInitializer->config(), m_nodeInitializer->transport()->gateway()); + m_rpc->setRpcStorage(rpcStatusInterface); + m_rpc->setBsEcdhPSI(m_nodeInitializer->bsEcdhPsi()); + m_nodeInitializer->registerRpcHandler(m_rpc); + + INIT_LOG(INFO) << LOG_DESC("init the rpc success"); +} + +void ProNodeInitializer::start() +{ + // start the node + if (m_nodeInitializer) + { + m_nodeInitializer->start(); + } + if (m_rpc) + { + m_rpc->start(); + } +} + +void ProNodeInitializer::stop() +{ + if (m_rpc) + { + m_rpc->stop(); + } + if (m_nodeInitializer) + { + m_nodeInitializer->stop(); + } +} \ No newline at end of file diff --git a/cpp/wedpr-main/pro-node/ProNodeInitializer.h b/cpp/wedpr-main/pro-node/ProNodeInitializer.h new file mode 100644 index 00000000..054d1b84 --- /dev/null +++ b/cpp/wedpr-main/pro-node/ProNodeInitializer.h @@ -0,0 +1,51 @@ +/** + * Copyright (C) 2022 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 ProNodeInitializer.h + * @author: yujiechen + * @date 2022-11-14 + */ +#pragma once +#include "wedpr-initializer/Common.h" +#include "wedpr-initializer/Initializer.h" +#include +#include +namespace ppc::rpc +{ +class Rpc; +} +namespace ppc::front +{ +class RemoteFrontBuilder; +} +namespace ppc::node +{ +class ProNodeInitializer +{ +public: + using Ptr = std::shared_ptr; + ProNodeInitializer(); + virtual ~ProNodeInitializer() { stop(); } + + virtual void init(std::string const& _configPath); + virtual void start(); + virtual void stop(); + +private: + bcos::BoostLogInitializer::Ptr m_logInitializer; + ppc::initializer::Initializer::Ptr m_nodeInitializer; + std::shared_ptr m_rpc; +}; +} // namespace ppc::node \ No newline at end of file diff --git a/cpp/wedpr-main/pro-node/main.cpp b/cpp/wedpr-main/pro-node/main.cpp new file mode 100644 index 00000000..2e075403 --- /dev/null +++ b/cpp/wedpr-main/pro-node/main.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2022 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 main.cpp + * @author: yujiechen + * @date 2022-11-14 + */ +#include "ProNodeInitializer.h" +#include "wedpr-main/common/NodeStarter.h" + +using namespace ppc::node; +int main(int argc, const char* argv[]) +{ + std::string binaryName = "ppc-pro-node"; + auto initializer = std::make_shared(); + auto ret = startProgram(argc, argv, binaryName, initializer); + initializer.reset(); + std::cout << "[" << bcos::getCurrentDateTime() << "] "; + std::cout << "The " << binaryName << " program exit normally." << std::endl; + return ret; +} \ No newline at end of file diff --git a/cpp/wedpr-protocol/CMakeLists.txt b/cpp/wedpr-protocol/CMakeLists.txt new file mode 100644 index 00000000..33136407 --- /dev/null +++ b/cpp/wedpr-protocol/CMakeLists.txt @@ -0,0 +1,4 @@ +add_subdirectory(protocol) +add_subdirectory(protobuf) +add_subdirectory(tars) +add_subdirectory(grpc) diff --git a/cpp/wedpr-protocol/grpc/CMakeLists.txt b/cpp/wedpr-protocol/grpc/CMakeLists.txt new file mode 100644 index 00000000..ad8a8d16 --- /dev/null +++ b/cpp/wedpr-protocol/grpc/CMakeLists.txt @@ -0,0 +1,34 @@ +# proto generation +set(PROTO_INPUT_PATH ${CMAKE_SOURCE_DIR}/wedpr-protocol/proto/pb) + +file(GLOB_RECURSE MESSAGES_PROTOS "${PROTO_INPUT_PATH}/Service*.proto") + +# create PROTO_OUTPUT_PATH +include(grpc) +foreach(proto_file ${MESSAGES_PROTOS}) + get_filename_component(basename ${proto_file} NAME_WE) + set(generated_file ${PROTO_OUTPUT_PATH}/${basename}.grpc.pb.cc) + + list(APPEND GRPC_MESSAGES_SRCS ${generated_file}) + message("Command: ${PROTOC_BINARY} --grpc_out ${PROTO_OUTPUT_PATH} -I ${PROTO_INPUT_PATH} --plugin=protoc-gen-grpc=${GRPC_CPP_PLUGIN} ${proto_file}") + add_custom_command( + OUTPUT ${generated_file} + COMMAND ${PROTOC_BINARY} + ARGS --grpc_out ${PROTO_OUTPUT_PATH} + -I ${PROTO_INPUT_PATH} + --plugin=protoc-gen-grpc="${GRPC_CPP_PLUGIN}" + ${proto_file} DEPENDS ${proto_file} + COMMENT "Generating ${generated_file} from ${proto_file}" + ) +endforeach() + +add_library(${SERVICE_PB_TARGET} ${GRPC_MESSAGES_SRCS}) +target_link_libraries(${SERVICE_PB_TARGET} PUBLIC ${PB_PROTOCOL_TARGET} gRPC::grpc++_unsecure gRPC::grpc++_reflection) + +add_subdirectory(client) +add_subdirectory(server) +if (TESTS) + enable_testing() + set(CTEST_OUTPUT_ON_FAILURE TRUE) + add_subdirectory(tests) +endif () diff --git a/cpp/wedpr-protocol/grpc/Common.h b/cpp/wedpr-protocol/grpc/Common.h new file mode 100644 index 00000000..fe4ad928 --- /dev/null +++ b/cpp/wedpr-protocol/grpc/Common.h @@ -0,0 +1,60 @@ +/** + * Copyright (C) 2021 FISCO BCOS. + * 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 Common.h + * @author: yujiechen + * @date 2021-04-12 + */ +#pragma once +#include "ppc-framework/Common.h" +#include "ppc-framework/protocol/GrpcConfig.h" +#include +#include + +namespace ppc::protocol +{ +#define GRPC_LOG(LEVEL) BCOS_LOG(LEVEL) << "[GRPC]" + +inline grpc::ChannelArguments toChannelConfig(ppc::protocol::GrpcConfig::Ptr const& grpcConfig) +{ + grpc::ChannelArguments args; + if (grpcConfig == nullptr) + { + return args; + } + args.SetLoadBalancingPolicyName(grpcConfig->loadBalancePolicy()); + if (grpcConfig->enableHealthCheck()) + { + args.SetServiceConfigJSON( + "{\"healthCheckConfig\": " + "{\"serviceName\": \"\"}}"); + } + // disable dns lookup + if (!grpcConfig->enableDnslookup()) + { + args.SetInt("grpc.enable_dns_srv_lookup", 0); + } + else + { + args.SetInt("grpc.enable_dns_srv_lookup", 1); + } + args.SetMaxReceiveMessageSize(grpcConfig->maxReceivedMessageSize()); + args.SetMaxSendMessageSize(grpcConfig->maxSendMessageSize()); + // the compress algorithm + args.SetCompressionAlgorithm((grpc_compression_algorithm)(grpcConfig->compressAlgorithm())); + GRPC_LOG(INFO) << LOG_DESC("toChannelConfig") << printGrpcConfig(grpcConfig); + return args; +} +} // namespace ppc::protocol \ No newline at end of file diff --git a/cpp/wedpr-protocol/grpc/client/CMakeLists.txt b/cpp/wedpr-protocol/grpc/client/CMakeLists.txt new file mode 100644 index 00000000..f7926ed3 --- /dev/null +++ b/cpp/wedpr-protocol/grpc/client/CMakeLists.txt @@ -0,0 +1,3 @@ +file(GLOB_RECURSE SRCS *.cpp) +add_library(${SERVICE_CLIENT_TARGET} ${SRCS}) +target_link_libraries(${SERVICE_CLIENT_TARGET} PUBLIC ${SERVICE_PB_TARGET} ${PROTOCOL_TARGET} ${PB_PROTOCOL_TARGET}) \ No newline at end of file diff --git a/cpp/wedpr-protocol/grpc/client/Common.h b/cpp/wedpr-protocol/grpc/client/Common.h new file mode 100644 index 00000000..99a59a19 --- /dev/null +++ b/cpp/wedpr-protocol/grpc/client/Common.h @@ -0,0 +1,26 @@ +/** + * Copyright (C) 2021 FISCO BCOS. + * 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 Common.h + * @author: yujiechen + * @date 2021-04-12 + */ +#pragma once +#include "ppc-framework/Common.h" + +#define GRPC_CLIENT_LOG(LEVEL) BCOS_LOG(LEVEL) << "[GRPC][CLIENT]" +#define GATEWAY_CLIENT_LOG(LEVEL) BCOS_LOG(LEVEL) << "[GATEWAY][CLIENT]" +#define FRONT_CLIENT_LOG(LEVEL) BCOS_LOG(LEVEL) << "[FRONT][CLIENT]" +#define HEALTH_LOG(LEVEL) BCOS_LOG(LEVEL) << "[HEALTH]" \ No newline at end of file diff --git a/cpp/wedpr-protocol/grpc/client/FrontClient.cpp b/cpp/wedpr-protocol/grpc/client/FrontClient.cpp new file mode 100644 index 00000000..48c5167f --- /dev/null +++ b/cpp/wedpr-protocol/grpc/client/FrontClient.cpp @@ -0,0 +1,43 @@ +/** + * 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 FrontClient.cpp + * @author: yujiechen + * @date 2024-09-02 + */ +#include "FrontClient.h" +#include "Common.h" +#include "protobuf/src/RequestConverter.h" +#include "wedpr-protocol/protobuf/src/Common.h" + +using namespace ppc::protocol; +using namespace ppc::proto; +using namespace grpc; + +void FrontClient::onReceiveMessage(ppc::protocol::Message::Ptr const& msg, ReceiveMsgFunc callback) +{ + std::unique_ptr request(new ReceivedMessage()); + bcos::bytes encodedData; + msg->encode(encodedData); + *request->mutable_data() = + std::move(std::string_view((const char*)encodedData.data(), encodedData.size())); + // The ClientContext instance used for creating an rpc must remain alive and valid for the + // lifetime of the rpc + auto context = std::make_shared(); + auto response = std::make_shared(); + // lambda keeps the lifecycle for clientContext + m_stub->async()->onReceiveMessage(context.get(), request.get(), response.get(), + [context, response, callback](Status status) { callback(toError(status, *response)); }); +} \ No newline at end of file diff --git a/cpp/wedpr-protocol/grpc/client/FrontClient.h b/cpp/wedpr-protocol/grpc/client/FrontClient.h new file mode 100644 index 00000000..acc4e96b --- /dev/null +++ b/cpp/wedpr-protocol/grpc/client/FrontClient.h @@ -0,0 +1,41 @@ +/** + * 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 FrontClient.h + * @author: yujiechen + * @date 2024-09-02 + */ +#pragma once +#include "GrpcClient.h" +#include "ppc-framework/front/IFront.h" + +namespace ppc::protocol +{ +class FrontClient : public virtual ppc::front::IFrontClient, public GrpcClient +{ +public: + using Ptr = std::shared_ptr; + FrontClient(ppc::protocol::GrpcConfig::Ptr const& grpcConfig, std::string const& endPoints) + : GrpcClient(grpcConfig, endPoints), m_stub(ppc::proto::Front::NewStub(m_channel)) + {} + + ~FrontClient() override = default; + void onReceiveMessage( + ppc::protocol::Message::Ptr const& _msg, ppc::protocol::ReceiveMsgFunc _callback) override; + +private: + std::unique_ptr m_stub; +}; +} // namespace ppc::protocol \ No newline at end of file diff --git a/cpp/wedpr-protocol/grpc/client/GatewayClient.cpp b/cpp/wedpr-protocol/grpc/client/GatewayClient.cpp new file mode 100644 index 00000000..01ff278d --- /dev/null +++ b/cpp/wedpr-protocol/grpc/client/GatewayClient.cpp @@ -0,0 +1,209 @@ +/** + * 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 GatewayClient.h + * @author: yujiechen + * @date 2024-09-02 + */ +#include "GatewayClient.h" +#include "Common.h" +#include "Service.grpc.pb.h" +#include "protobuf/src/RequestConverter.h" + +using namespace ppc; +using namespace ppc::proto; +using namespace grpc; +using namespace ppc::gateway; +using namespace ppc::protocol; + +GatewayClient::GatewayClient(ppc::protocol::GrpcConfig::Ptr const& grpcConfig, + std::string const& endPoints, INodeInfoFactory::Ptr nodeInfoFactory) + : GrpcClient(grpcConfig, endPoints), + m_stub(ppc::proto::Gateway::NewStub(m_channel)), + m_nodeInfoFactory(std::move(nodeInfoFactory)) +{ + for (auto const& channel : m_broadcastChannels) + { + m_broadcastStubs.insert( + std::make_pair(channel.endPoint, ppc::proto::Gateway::NewStub(channel.channel))); + } +} + +void GatewayClient::asyncSendMessage(RouteType routeType, + MessageOptionalHeader::Ptr const& routeInfo, std::string const& traceID, bcos::bytes&& payload, + long timeout, ReceiveMsgFunc callback) +{ + std::unique_ptr request( + generateRequest(traceID, routeType, routeInfo, std::move(payload), timeout)); + auto context = std::make_shared(); + auto response = std::make_shared(); + // lambda keeps the lifecycle for clientContext + m_stub->async()->asyncSendMessage(context.get(), request.get(), response.get(), + [context, traceID, callback, response]( + Status status) { callback(toError(status, *response)); }); +} + +std::vector GatewayClient::selectNodesByRoutePolicy( + RouteType routeType, MessageOptionalHeader::Ptr const& routeInfo) +{ + std::unique_ptr request( + generateSelectRouteRequest(routeType, routeInfo)); + auto context = std::make_shared(); + auto response = std::make_shared(); + // lambda keeps the lifecycle for clientContext + auto status = m_stub->selectNodesByRoutePolicy(context.get(), *request, response.get()); + if (!status.ok()) + { + throw std::runtime_error( + "selectNodesByRoutePolicy failed, code: " + std::to_string(status.error_code()) + + ", msg: " + status.error_message()); + } + if (response->error().errorcode() != 0) + { + throw std::runtime_error("selectNodesByRoutePolicy failed, code: " + + std::to_string(response->error().errorcode()) + + ", msg: " + response->error().errormessage()); + } + return std::vector(response->nodelist().begin(), response->nodelist().end()); +} + +std::vector GatewayClient::getAliveNodeList() const +{ + auto request = std::make_shared(); + auto response = std::make_shared(); + auto context = std::make_shared(); + // lambda keeps the lifecycle for clientContext + auto status = m_stub->getAliveNodeList(context.get(), *request, response.get()); + if (!status.ok()) + { + throw std::runtime_error( + "getAliveNodeList failed, code: " + std::to_string(status.error_code()) + + ", msg: " + status.error_message()); + } + if (response->error().errorcode() != 0) + { + throw std::runtime_error( + "getAliveNodeList failed, code: " + std::to_string(response->error().errorcode()) + + ", msg: " + response->error().errormessage()); + } + return toNodeInfoList(m_nodeInfoFactory, *response); +} + +void GatewayClient::asyncGetPeers(std::function callback) +{ + auto response = std::make_shared(); + auto context = std::make_shared(); + auto request = std::make_shared(); + // lambda keeps the lifecycle for clientContext + m_stub->async()->asyncGetPeers( + context.get(), request.get(), response.get(), [context, callback, response](Status status) { + callback(toError(status, response->error()), response->peersinfo()); + }); +} + +void GatewayClient::asyncGetAgencies(std::vector const& components, + std::function)> callback) +{ + auto response = std::make_shared(); + auto context = std::make_shared(); + auto request = std::make_shared(); + for (auto const& it : components) + { + request->add_components(it); + } + // lambda keeps the lifecycle for clientContext + m_stub->async()->asyncGetAgencies( + context.get(), request.get(), response.get(), [context, callback, response](Status status) { + std::set agencies; + for (int i = 0; i < response->agencies_size(); i++) + { + agencies.insert(response->agencies(i)); + } + callback(toError(status, response->error()), agencies); + }); +} + +bcos::Error::Ptr GatewayClient::registerNodeInfo(INodeInfo::Ptr const& nodeInfo) +{ + std::unique_ptr request(new ppc::proto::NodeInfo()); + toNodeInfoRequest(request.get(), nodeInfo); + return broadCast([&](ChannelInfo const& channel) { + if (!m_broadcastStubs.count(channel.endPoint)) + { + return make_shared( + -1, "registerNodeInfo failed for not find stub for endPoint: " + channel.endPoint); + } + auto const& stub = m_broadcastStubs.at(channel.endPoint); + + auto context = std::make_shared(); + auto response = std::make_shared(); + auto status = stub->registerNodeInfo(context.get(), *request, response.get()); + auto result = toError(status, *response); + return result; + }); +} + +bcos::Error::Ptr GatewayClient::unRegisterNodeInfo(bcos::bytesConstRef nodeID) +{ + std::unique_ptr request(toNodeInfoRequest(nodeID, "")); + return broadCast([&](ChannelInfo const& channel) { + if (!m_broadcastStubs.count(channel.endPoint)) + { + return make_shared(-1, + "unRegisterNodeInfo failed for not find stub for endPoint: " + channel.endPoint); + } + auto const& stub = m_broadcastStubs.at(channel.endPoint); + + auto context = std::make_shared(); + auto response = std::make_shared(); + auto status = stub->unRegisterNodeInfo(context.get(), *request, response.get()); + return toError(status, *response); + }); +} +bcos::Error::Ptr GatewayClient::registerTopic(bcos::bytesConstRef nodeID, std::string const& topic) +{ + std::unique_ptr request(toNodeInfoRequest(nodeID, topic)); + return broadCast([&](ChannelInfo const& channel) { + if (!m_broadcastStubs.count(channel.endPoint)) + { + return make_shared( + -1, "registerTopic failed for not find stub for endPoint: " + channel.endPoint); + } + auto const& stub = m_broadcastStubs.at(channel.endPoint); + + auto context = std::make_shared(); + auto response = std::make_shared(); + auto status = stub->registerTopic(context.get(), *request, response.get()); + return toError(status, *response); + }); +} + +bcos::Error::Ptr GatewayClient::unRegisterTopic( + bcos::bytesConstRef nodeID, std::string const& topic) +{ + std::unique_ptr request(toNodeInfoRequest(nodeID, topic)); + return broadCast([&](ChannelInfo const& channel) { + if (!m_broadcastStubs.count(channel.endPoint)) + { + return make_shared( + -1, "unRegisterTopic failed for not find stub for endPoint: " + channel.endPoint); + } + auto const& stub = m_broadcastStubs.at(channel.endPoint); + auto context = std::make_shared(); + auto response = std::make_shared(); + auto status = stub->unRegisterTopic(context.get(), *request, response.get()); + return toError(status, *response); + }); +} \ No newline at end of file diff --git a/cpp/wedpr-protocol/grpc/client/GatewayClient.h b/cpp/wedpr-protocol/grpc/client/GatewayClient.h new file mode 100644 index 00000000..149a9052 --- /dev/null +++ b/cpp/wedpr-protocol/grpc/client/GatewayClient.h @@ -0,0 +1,80 @@ +/** + * 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 GatewayClient.h + * @author: yujiechen + * @date 2024-09-02 + */ +#pragma once +#include "GrpcClient.h" +#include "ppc-framework/gateway/IGateway.h" + +namespace ppc::protocol +{ +class GatewayClient : public ppc::gateway::IGateway, public GrpcClient +{ +public: + using Ptr = std::shared_ptr; + GatewayClient(ppc::protocol::GrpcConfig::Ptr const& grpcConfig, std::string const& endPoints, + INodeInfoFactory::Ptr nodeInfoFactory); + + ~GatewayClient() 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, + ppc::protocol::MessageOptionalHeader::Ptr const& routeInfo, std::string const& traceID, + bcos::bytes&& payload, long timeout, ppc::protocol::ReceiveMsgFunc callback) override; + + void asyncGetPeers(std::function callback) override; + void asyncGetAgencies(std::vector const& components, + std::function)> callback) override; + + void asyncSendbroadcastMessage(ppc::protocol::RouteType routeType, + ppc::protocol::MessageOptionalHeader::Ptr const& routeInfo, std::string const& traceID, + bcos::bytes&& payload) override + {} + bcos::Error::Ptr registerNodeInfo(ppc::protocol::INodeInfo::Ptr const& nodeInfo) override; + bcos::Error::Ptr unRegisterNodeInfo(bcos::bytesConstRef nodeID) override; + bcos::Error::Ptr registerTopic(bcos::bytesConstRef nodeID, std::string const& topic) override; + bcos::Error::Ptr unRegisterTopic(bcos::bytesConstRef nodeID, std::string const& topic) override; + + std::vector selectNodesByRoutePolicy(ppc::protocol::RouteType routeType, + ppc::protocol::MessageOptionalHeader::Ptr const& routeInfo) override; + + std::vector getAliveNodeList() const override; + +private: + std::unique_ptr m_stub; + std::map> m_broadcastStubs; + INodeInfoFactory::Ptr m_nodeInfoFactory; +}; +} // namespace ppc::protocol \ No newline at end of file diff --git a/cpp/wedpr-protocol/grpc/client/GrpcClient.cpp b/cpp/wedpr-protocol/grpc/client/GrpcClient.cpp new file mode 100644 index 00000000..682d2f4f --- /dev/null +++ b/cpp/wedpr-protocol/grpc/client/GrpcClient.cpp @@ -0,0 +1,113 @@ +/** + * 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 GrpcClient.cpp + * @author: yujiechen + * @date 2024-09-02 + */ +#include "GrpcClient.h" +#include "Common.h" +#include + +using namespace ppc::protocol; +using namespace ppc::proto; +using namespace grpc; +using namespace grpc::health::v1; + +GrpcClient::GrpcClient( + ppc::protocol::GrpcConfig::Ptr const& grpcConfig, std::string const& endPoints) + : m_grpcConfig(grpcConfig), + m_channel(grpc::CreateCustomChannel( + endPoints, grpc::InsecureChannelCredentials(), toChannelConfig(grpcConfig))), + m_healthCheckStub(grpc::health::v1::Health::NewStub(m_channel)) +{ + std::vector endPointList; + boost::split(endPointList, endPoints, boost::is_any_of(",")); + // create the broadcast channels + for (auto const& endPoint : endPointList) + { + GRPC_CLIENT_LOG(INFO) << LOG_DESC("create broadcast-channel, endpoint: ") << endPoint; + m_broadcastChannels.push_back( + {endPoint, grpc::CreateCustomChannel(endPoint, grpc::InsecureChannelCredentials(), + toChannelConfig(grpcConfig))}); + } +} + +bool GrpcClient::checkHealth() +{ + try + { + HEALTH_LOG(TRACE) << LOG_DESC("checkHealth"); + ClientContext context; + HealthCheckResponse response; + auto status = + m_healthCheckStub->Check(&context, HealthCheckRequest::default_instance(), &response); + if (!status.ok()) + { + GRPC_CLIENT_LOG(WARNING) + << LOG_DESC("GrpcClient check health failed") << LOG_KV("code", status.error_code()) + << LOG_KV("msg", status.error_message()); + return false; + } + return true; + } + catch (std::exception const& e) + { + GRPC_CLIENT_LOG(WARNING) << LOG_DESC("GrpcClient check health exception") + << LOG_KV("error", boost::diagnostic_information(e)); + return false; + } +} + +bcos::Error::Ptr GrpcClient::broadCast( + std::function callback) +{ + auto result = std::make_shared(0, ""); + int successCount = 0; + for (auto const& channel : m_broadcastChannels) + { + try + { + if (channel.channel->GetState(false) == GRPC_CHANNEL_SHUTDOWN) + { + GRPC_CLIENT_LOG(INFO) << LOG_DESC("Ignore unconnected channel") + << LOG_KV("endpoint", channel.endPoint); + continue; + } + auto error = callback(channel); + if (error && error->errorCode() != 0) + { + result->setErrorCode(error->errorCode()); + result->setErrorMessage(result->errorMessage() + error->errorMessage() + "; "); + } + else + { + successCount++; + } + } + catch (std::exception const& e) + { + GRPC_CLIENT_LOG(WARNING) + << LOG_DESC("GrpcClient broadCast exception") << LOG_KV("remote", channel.endPoint) + << LOG_KV("error", boost::diagnostic_information(e)); + } + } + // at least one success + if (successCount > 0) + { + return std::make_shared(0, "success"); + } + return result; +} \ No newline at end of file diff --git a/cpp/wedpr-protocol/grpc/client/GrpcClient.h b/cpp/wedpr-protocol/grpc/client/GrpcClient.h new file mode 100644 index 00000000..39d1adaa --- /dev/null +++ b/cpp/wedpr-protocol/grpc/client/GrpcClient.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 GrpcClient.h + * @author: yujiechen + * @date 2024-09-02 + */ +#pragma once +#include "Service.grpc.pb.h" +#include "ServiceHealth.grpc.pb.h" +#include "ppc-framework/protocol/GrpcConfig.h" +#include "wedpr-protocol/grpc/Common.h" +#include +#include + +namespace ppc::protocol +{ +struct ChannelInfo +{ + std::string endPoint; + std::shared_ptr channel; +}; +// refer to: https://grpc.io/docs/languages/cpp/callback/ +class GrpcClient +{ +public: + using Ptr = std::shared_ptr; + GrpcClient(ppc::protocol::GrpcConfig::Ptr const& grpcConfig, std::string const& endPoints); + + virtual ~GrpcClient() = default; + + std::shared_ptr const& channel() { return m_channel; } + + bool checkHealth(); + +protected: + virtual bcos::Error::Ptr broadCast( + std::function callback); + +protected: + ppc::protocol::GrpcConfig::Ptr m_grpcConfig; + // the channel + std::shared_ptr m_channel; + + // the broadcast channel + std::vector m_broadcastChannels; + // the healthcheck stub + std::unique_ptr m_healthCheckStub; +}; +} // namespace ppc::protocol \ No newline at end of file diff --git a/cpp/wedpr-protocol/grpc/client/HealthCheckTimer.cpp b/cpp/wedpr-protocol/grpc/client/HealthCheckTimer.cpp new file mode 100644 index 00000000..aa9f9223 --- /dev/null +++ b/cpp/wedpr-protocol/grpc/client/HealthCheckTimer.cpp @@ -0,0 +1,136 @@ +/** + * 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 HealthCheckTimer.cpp + * @author: yujiechen + * @date 2024-09-6 + */ +#include "HealthCheckTimer.h" +#include "Common.h" + +using namespace ppc::protocol; +using namespace ppc::front; + +HealthCheckTimer::HealthCheckTimer(int periodMs) : m_periodMs(periodMs) +{ + m_timer = std::make_shared(m_periodMs, "healthChecker"); +} + +void HealthCheckTimer::start() +{ + if (m_running == true) + { + HEALTH_LOG(INFO) << LOG_DESC("HealthCheckTimer has already been started!"); + return; + } + m_running = true; + + auto self = weak_from_this(); + m_timer->registerTimeoutHandler([self]() { + auto healthChecker = self.lock(); + if (!healthChecker) + { + return; + } + healthChecker->checkHealth(); + }); + if (m_timer) + { + m_timer->start(); + } + HEALTH_LOG(INFO) << LOG_DESC("start the HealthCheckTimer success"); +} + +void HealthCheckTimer::stop() +{ + if (m_running == false) + { + HEALTH_LOG(INFO) << LOG_DESC("HealthCheckTimer has already been stopped!"); + return; + } + m_running = false; + if (m_timer) + { + m_timer->stop(); + } + HEALTH_LOG(INFO) << LOG_DESC("stop the HealthCheckTimer success"); +} + + +void HealthCheckTimer::registerHealthCheckHandler(HealthCheckHandler::Ptr healthCheckHandler) +{ + if (!healthCheckHandler) + { + return; + } + bcos::WriteGuard l(x_healthCheckHandlers); + m_healthCheckHandlers[healthCheckHandler->serviceName] = healthCheckHandler; + HEALTH_LOG(INFO) << LOG_DESC("registerHealthCheckHandler for ") + << healthCheckHandler->serviceName; +} + + +void HealthCheckTimer::checkHealth() +{ + try + { + std::map handlers; + { + bcos::ReadGuard l(x_healthCheckHandlers); + handlers = m_healthCheckHandlers; + } + std::set serviceToRemove; + for (auto const& it : handlers) + { + auto handler = it.second; + bool health = true; + if (handler->checkHealthHandler) + { + health = handler->checkHealthHandler(); + } + if (health) + { + continue; + } + HEALTH_LOG(WARNING) << LOG_DESC("Detect unHealth service: ") << it.first; + if (handler->onUnHealthHandler) + { + handler->onUnHealthHandler(); + } + if (handler->removeHandlerOnUnhealth) + { + serviceToRemove.insert(it.first); + } + } + m_timer->restart(); + if (serviceToRemove.empty()) + { + return; + } + { + bcos::WriteGuard l(x_healthCheckHandlers); + for (auto const& service : serviceToRemove) + { + m_healthCheckHandlers.erase(service); + } + } + } + catch (std::exception const& e) + { + HEALTH_LOG(WARNING) << LOG_DESC("checkHealth exception, error: ") + << LOG_KV("error", boost::diagnostic_information(e)); + m_timer->restart(); + } +} diff --git a/cpp/wedpr-protocol/grpc/client/HealthCheckTimer.h b/cpp/wedpr-protocol/grpc/client/HealthCheckTimer.h new file mode 100644 index 00000000..39dc3eb1 --- /dev/null +++ b/cpp/wedpr-protocol/grpc/client/HealthCheckTimer.h @@ -0,0 +1,52 @@ +/** + * 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 HealthCheckTimer.h + * @author: yujiechen + * @date 2024-09-6 + */ +#pragma once +#include "ppc-framework/front/IFront.h" +#include +#include +#include + +namespace ppc::protocol +{ +class HealthCheckTimer : public std::enable_shared_from_this +{ +public: + using Ptr = std::shared_ptr; + HealthCheckTimer(int periodMs); + virtual ~HealthCheckTimer() = default; + + virtual void start(); + virtual void stop(); + + + void registerHealthCheckHandler(HealthCheckHandler::Ptr healthCheckHandler); + +protected: + void checkHealth(); + +private: + std::map m_healthCheckHandlers; + mutable bcos::SharedMutex x_healthCheckHandlers; + + int m_periodMs = 3000; + std::shared_ptr m_timer; + bool m_running = false; +}; +} // namespace ppc::protocol \ No newline at end of file diff --git a/cpp/wedpr-protocol/grpc/client/RemoteFrontBuilder.cpp b/cpp/wedpr-protocol/grpc/client/RemoteFrontBuilder.cpp new file mode 100644 index 00000000..05129869 --- /dev/null +++ b/cpp/wedpr-protocol/grpc/client/RemoteFrontBuilder.cpp @@ -0,0 +1,44 @@ +/** + * 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 RemoteFrontBuilder.cpp + * @author: yujiechen + * @date 2024-09-4 + */ +#include "RemoteFrontBuilder.h" +// Note: it's better not to include generated grpc files in the header, since it will slow the +// compiler speed +#include "FrontClient.h" + +using namespace ppc::protocol; +using namespace ppc::front; +using namespace ppc::protocol; + +IFrontClient::Ptr RemoteFrontBuilder::buildClient(std::string endPoint, + std::function onUnHealthHandler, bool removeHandlerOnUnhealth) const +{ + auto frontClient = std::make_shared(m_grpcConfig, endPoint); + if (m_healthChecker) + { + auto healthCheckHandler = std::make_shared("front_" + endPoint); + healthCheckHandler->checkHealthHandler = [frontClient]() { + return frontClient->checkHealth(); + }; + healthCheckHandler->onUnHealthHandler = onUnHealthHandler; + healthCheckHandler->removeHandlerOnUnhealth = removeHandlerOnUnhealth; + m_healthChecker->registerHealthCheckHandler(healthCheckHandler); + } + return frontClient; +} diff --git a/cpp/wedpr-protocol/grpc/client/RemoteFrontBuilder.h b/cpp/wedpr-protocol/grpc/client/RemoteFrontBuilder.h new file mode 100644 index 00000000..3770f6a0 --- /dev/null +++ b/cpp/wedpr-protocol/grpc/client/RemoteFrontBuilder.h @@ -0,0 +1,44 @@ +/** + * 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 RemoteFrontBuilder.h + * @author: yujiechen + * @date 2024-09-4 + */ +#pragma once +#include "HealthCheckTimer.h" +#include "ppc-framework/front/IFront.h" +#include "ppc-framework/protocol/GrpcConfig.h" + +namespace ppc::front +{ +class RemoteFrontBuilder : public IFrontBuilder +{ +public: + using Ptr = std::shared_ptr; + RemoteFrontBuilder(ppc::protocol::GrpcConfig::Ptr const& grpcConfig, + ppc::protocol::HealthCheckTimer::Ptr healthChecker) + : m_grpcConfig(grpcConfig), m_healthChecker(healthChecker) + {} + ~RemoteFrontBuilder() override = default; + + IFrontClient::Ptr buildClient(std::string endPoint, std::function onUnHealthHandler, + bool removeHandlerOnUnhealth) const override; + +private: + ppc::protocol::GrpcConfig::Ptr m_grpcConfig; + ppc::protocol::HealthCheckTimer::Ptr m_healthChecker; +}; +} // namespace ppc::front \ No newline at end of file diff --git a/cpp/wedpr-protocol/grpc/server/CMakeLists.txt b/cpp/wedpr-protocol/grpc/server/CMakeLists.txt new file mode 100644 index 00000000..aaa6c243 --- /dev/null +++ b/cpp/wedpr-protocol/grpc/server/CMakeLists.txt @@ -0,0 +1,3 @@ +file(GLOB_RECURSE SRCS *.cpp) +add_library(${SERVICE_SERVER_TARGET} ${SRCS}) +target_link_libraries(${SERVICE_SERVER_TARGET} PUBLIC ${SERVICE_PB_TARGET} ${PROTOCOL_TARGET} ${PB_PROTOCOL_TARGET}) \ No newline at end of file diff --git a/cpp/wedpr-protocol/grpc/server/Common.h b/cpp/wedpr-protocol/grpc/server/Common.h new file mode 100644 index 00000000..58fa79e2 --- /dev/null +++ b/cpp/wedpr-protocol/grpc/server/Common.h @@ -0,0 +1,25 @@ +/** + * Copyright (C) 2021 FISCO BCOS. + * 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 Common.h + * @author: yujiechen + * @date 2021-04-12 + */ +#pragma once +#include "ppc-framework/Common.h" + +#define GRPC_SERVER_LOG(LEVEL) BCOS_LOG(LEVEL) << "[GRPC][SERVER]" +#define FRONT_SERVER_LOG(LEVEL) BCOS_LOG(LEVEL) << "[FRONT][SERVER]" +#define GATEWAY_SERVER_LOG(LEVEL) BCOS_LOG(LEVEL) << "[GATEWAY][SERVER]" \ No newline at end of file diff --git a/cpp/wedpr-protocol/grpc/server/FrontServer.cpp b/cpp/wedpr-protocol/grpc/server/FrontServer.cpp new file mode 100644 index 00000000..975ff850 --- /dev/null +++ b/cpp/wedpr-protocol/grpc/server/FrontServer.cpp @@ -0,0 +1,52 @@ +/** + * 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 FrontServer.cpp + * @author: yujiechen + * @date 2024-09-03 + */ +#include "FrontServer.h" +#include "Common.h" +#include "protobuf/src/RequestConverter.h" +#include + +using namespace ppc::proto; +using namespace ppc::protocol; +using namespace grpc; + +ServerUnaryReactor* FrontServer::onReceiveMessage( + CallbackServerContext* context, const ReceivedMessage* receivedMsg, ppc::proto::Error* reply) +{ + ServerUnaryReactor* reactor(context->DefaultReactor()); + try + { + // decode the request + auto msg = m_msgBuilder->build(bcos::bytesConstRef( + (bcos::byte*)receivedMsg->data().data(), receivedMsg->data().size())); + m_front->onReceiveMessage(msg, [reactor, reply](bcos::Error::Ptr error) { + toSerializedError(reply, error); + reactor->Finish(Status::OK); + }); + } + catch (std::exception const& e) + { + FRONT_SERVER_LOG(ERROR) << LOG_DESC("onReceiveMessage exception") + << LOG_KV("error", boost::diagnostic_information(e)); + toSerializedError(reply, + std::make_shared(-1, std::string(boost::diagnostic_information(e)))); + reactor->Finish(Status::OK); + } + return reactor; +} \ No newline at end of file diff --git a/cpp/wedpr-protocol/grpc/server/FrontServer.h b/cpp/wedpr-protocol/grpc/server/FrontServer.h new file mode 100644 index 00000000..f8e0ae96 --- /dev/null +++ b/cpp/wedpr-protocol/grpc/server/FrontServer.h @@ -0,0 +1,52 @@ +/** + * 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 FrontServer.h + * @author: yujiechen + * @date 2024-09-03 + */ +#pragma once +#include "Service.grpc.pb.h" +#include +#include +#include +#include + +namespace ppc::protocol +{ +class FrontServer : public ppc::proto::Front::CallbackService +{ +public: + using Ptr = std::shared_ptr; + FrontServer(ppc::protocol::MessageBuilder::Ptr msgBuilder, ppc::front::IFront::Ptr front) + : m_msgBuilder(std::move(msgBuilder)), m_front(std::move(front)) + {} + ~FrontServer() override = default; + + grpc::ServerUnaryReactor* onReceiveMessage(grpc::CallbackServerContext* context, + const ppc::proto::ReceivedMessage* receivedMsg, ppc::proto::Error* reply) override; + + void setHealthCheckService(grpc::HealthCheckServiceInterface* healthCheckService) + { + m_healthCheckService = healthCheckService; + m_healthCheckService->SetServingStatus(true); + } + +private: + grpc::HealthCheckServiceInterface* m_healthCheckService = nullptr; + ppc::front::IFront::Ptr m_front; + ppc::protocol::MessageBuilder::Ptr m_msgBuilder; +}; +} // namespace ppc::protocol \ No newline at end of file diff --git a/cpp/wedpr-protocol/grpc/server/GatewayServer.cpp b/cpp/wedpr-protocol/grpc/server/GatewayServer.cpp new file mode 100644 index 00000000..e4eb141c --- /dev/null +++ b/cpp/wedpr-protocol/grpc/server/GatewayServer.cpp @@ -0,0 +1,255 @@ +/** + * 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 GatewayServer.cpp + * @author: yujiechen + * @date 2024-09-03 + */ +#include "GatewayServer.h" +#include "Common.h" +#include "protobuf/src/RequestConverter.h" +using namespace ppc::protocol; +using namespace grpc; + +ServerUnaryReactor* GatewayServer::asyncSendMessage(CallbackServerContext* context, + const ppc::proto::SendedMessageRequest* sendedMsg, ppc::proto::Error* reply) +{ + ServerUnaryReactor* reactor(context->DefaultReactor()); + try + { + // TODO: optimize here (since bytes of protobuf is represented with string, no zero-copy + // method has been found yet, unless the payload is stored in string) + bcos::bytes payloadData(sendedMsg->payload().begin(), sendedMsg->payload().end()); + auto routeInfo = generateRouteInfo(m_routeInfoBuilder, sendedMsg->routeinfo()); + m_gateway->asyncSendMessage((ppc::protocol::RouteType)sendedMsg->routetype(), routeInfo, + sendedMsg->traceid(), std::move(payloadData), sendedMsg->timeout(), + [reactor, reply](bcos::Error::Ptr error) { + toSerializedError(reply, error); + reactor->Finish(Status::OK); + }); + } + catch (std::exception const& e) + { + GATEWAY_SERVER_LOG(WARNING) << LOG_DESC("asyncSendMessage exception") + << LOG_KV("error", boost::diagnostic_information(e)); + toSerializedError(reply, + std::make_shared(-1, + "asyncSendMessage failed for : " + std::string(boost::diagnostic_information(e)))); + reactor->Finish(Status::OK); + } + return reactor; +} + +grpc::ServerUnaryReactor* GatewayServer::selectNodesByRoutePolicy( + grpc::CallbackServerContext* context, const ppc::proto::SelectRouteRequest* selectRouteRequest, + ppc::proto::NodeList* reply) +{ + ServerUnaryReactor* reactor(context->DefaultReactor()); + try + { + auto routeInfo = generateRouteInfo(m_routeInfoBuilder, selectRouteRequest->routeinfo()); + auto selectedNodes = m_gateway->selectNodesByRoutePolicy( + (ppc::protocol::RouteType)selectRouteRequest->routetype(), routeInfo); + for (auto const& it : selectedNodes) + { + reply->add_nodelist(it); + } + reactor->Finish(Status::OK); + } + catch (std::exception const& e) + { + GATEWAY_SERVER_LOG(WARNING) << LOG_DESC("selectNodesByRoutePolicy exception") + << LOG_KV("error", boost::diagnostic_information(e)); + toSerializedError(reply->mutable_error(), + std::make_shared(-1, "selectNodesByRoutePolicy failed for : " + + std::string(boost::diagnostic_information(e)))); + reactor->Finish(Status::OK); + } + return reactor; +} + +grpc::ServerUnaryReactor* GatewayServer::asyncGetPeers( + grpc::CallbackServerContext* context, const ppc::proto::Empty*, ppc::proto::PeersInfo* reply) +{ + ServerUnaryReactor* reactor(context->DefaultReactor()); + try + { + m_gateway->asyncGetPeers([reactor, reply](bcos::Error::Ptr error, std::string peersInfo) { + toSerializedError(reply->mutable_error(), error); + reply->set_peersinfo(std::move(peersInfo)); + reactor->Finish(Status::OK); + }); + } + catch (std::exception const& e) + { + GATEWAY_SERVER_LOG(WARNING) << LOG_DESC("asyncGetPeers exception") + << LOG_KV("error", boost::diagnostic_information(e)); + toSerializedError(reply->mutable_error(), + std::make_shared( + -1, "asyncGetPeers failed for : " + std::string(boost::diagnostic_information(e)))); + reactor->Finish(Status::OK); + } + return reactor; +} + +grpc::ServerUnaryReactor* GatewayServer::asyncGetAgencies(grpc::CallbackServerContext* context, + const ppc::proto::Condition* condition, ppc::proto::AgenciesInfo* reply) +{ + ServerUnaryReactor* reactor(context->DefaultReactor()); + try + { + std::vector components; + for (int i = 0; i < condition->components_size(); i++) + { + components.emplace_back(condition->components(i)); + } + m_gateway->asyncGetAgencies( + components, [reactor, reply](bcos::Error::Ptr error, std::set agencies) { + toSerializedError(reply->mutable_error(), error); + for (auto const& it : agencies) + { + reply->add_agencies(it); + } + reactor->Finish(Status::OK); + }); + } + catch (std::exception const& e) + { + GATEWAY_SERVER_LOG(WARNING) << LOG_DESC("asyncGetAgencies exception") + << LOG_KV("error", boost::diagnostic_information(e)); + toSerializedError(reply->mutable_error(), + std::make_shared(-1, + "asyncGetAgencies failed for : " + std::string(boost::diagnostic_information(e)))); + reactor->Finish(Status::OK); + } + return reactor; +} + + +ServerUnaryReactor* GatewayServer::registerNodeInfo(CallbackServerContext* context, + const ppc::proto::NodeInfo* serializedNodeInfo, ppc::proto::Error* reply) +{ + ServerUnaryReactor* reactor(context->DefaultReactor()); + try + { + auto nodeInfo = toNodeInfo(m_nodeInfoFactory, *serializedNodeInfo); + auto result = m_gateway->registerNodeInfo(nodeInfo); + toSerializedError(reply, result); + reactor->Finish(Status::OK); + } + catch (std::exception const& e) + { + GATEWAY_SERVER_LOG(WARNING) << LOG_DESC("registerNodeInfo exception") + << LOG_KV("error", boost::diagnostic_information(e)); + toSerializedError(reply, + std::make_shared(-1, + "registerNodeInfo failed for : " + std::string(boost::diagnostic_information(e)))); + reactor->Finish(Status::OK); + } + return reactor; +} + +grpc::ServerUnaryReactor* GatewayServer::getAliveNodeList(grpc::CallbackServerContext* context, + const ppc::proto::Empty* request, ppc::proto::NodeInfoList* reply) +{ + ServerUnaryReactor* reactor(context->DefaultReactor()); + try + { + auto result = m_gateway->getAliveNodeList(); + toRawNodeInfoList(reply, result); + reactor->Finish(Status::OK); + } + catch (std::exception const& e) + { + GATEWAY_SERVER_LOG(WARNING) << LOG_DESC("getAliveNodeList exception") + << LOG_KV("error", boost::diagnostic_information(e)); + toSerializedError(reply->mutable_error(), + std::make_shared(-1, + "getAliveNodeList failed for : " + std::string(boost::diagnostic_information(e)))); + reactor->Finish(Status::OK); + } + return reactor; +} + +ServerUnaryReactor* GatewayServer::unRegisterNodeInfo( + CallbackServerContext* context, const ppc::proto::NodeInfo* nodeInfo, ppc::proto::Error* reply) +{ + ServerUnaryReactor* reactor(context->DefaultReactor()); + try + { + auto result = m_gateway->unRegisterNodeInfo( + bcos::bytesConstRef((bcos::byte*)nodeInfo->nodeid().data(), nodeInfo->nodeid().size())); + toSerializedError(reply, result); + reactor->Finish(Status::OK); + } + catch (std::exception const& e) + { + GATEWAY_SERVER_LOG(WARNING) << LOG_DESC("unRegisterNodeInfo exception") + << LOG_KV("error", boost::diagnostic_information(e)); + toSerializedError(reply, + std::make_shared(-1, "unRegisterNodeInfo failed for : " + + std::string(boost::diagnostic_information(e)))); + reactor->Finish(Status::OK); + } + return reactor; +} + +ServerUnaryReactor* GatewayServer::registerTopic( + CallbackServerContext* context, const ppc::proto::NodeInfo* nodeInfo, ppc::proto::Error* reply) +{ + ServerUnaryReactor* reactor(context->DefaultReactor()); + try + { + auto result = m_gateway->registerTopic( + bcos::bytesConstRef((bcos::byte*)nodeInfo->nodeid().data(), nodeInfo->nodeid().size()), + nodeInfo->topic()); + toSerializedError(reply, result); + reactor->Finish(Status::OK); + } + catch (std::exception const& e) + { + GATEWAY_SERVER_LOG(WARNING) << LOG_DESC("unRegisterNodeInfo exception") + << LOG_KV("error", boost::diagnostic_information(e)); + toSerializedError(reply, + std::make_shared( + -1, "registerTopic failed for : " + std::string(boost::diagnostic_information(e)))); + reactor->Finish(Status::OK); + } + return reactor; +} + +ServerUnaryReactor* GatewayServer::unRegisterTopic( + CallbackServerContext* context, const ppc::proto::NodeInfo* nodeInfo, ppc::proto::Error* reply) +{ + ServerUnaryReactor* reactor(context->DefaultReactor()); + try + { + auto result = m_gateway->unRegisterTopic( + bcos::bytesConstRef((bcos::byte*)nodeInfo->nodeid().data(), nodeInfo->nodeid().size()), + nodeInfo->topic()); + toSerializedError(reply, result); + reactor->Finish(Status::OK); + } + catch (std::exception const& e) + { + GATEWAY_SERVER_LOG(WARNING) << LOG_DESC("unRegisterTopic exception") + << LOG_KV("error", boost::diagnostic_information(e)); + toSerializedError(reply, + std::make_shared(-1, + "unRegisterTopic failed for : " + std::string(boost::diagnostic_information(e)))); + reactor->Finish(Status::OK); + } + return reactor; +} \ No newline at end of file diff --git a/cpp/wedpr-protocol/grpc/server/GatewayServer.h b/cpp/wedpr-protocol/grpc/server/GatewayServer.h new file mode 100644 index 00000000..53436d4c --- /dev/null +++ b/cpp/wedpr-protocol/grpc/server/GatewayServer.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 GatewayServer.h + * @author: yujiechen + * @date 2024-09-03 + */ +#pragma once +#include "Service.grpc.pb.h" +#include "ppc-framework/gateway/IGateway.h" +#include + +namespace ppc::protocol +{ +class GatewayServer : public ppc::proto::Gateway::CallbackService +{ +public: + using Ptr = std::shared_ptr; + GatewayServer(ppc::gateway::IGateway::Ptr gateway, + MessageOptionalHeaderBuilder::Ptr routeInfoBuilder, INodeInfoFactory::Ptr nodeInfoFactory) + : m_gateway(std::move(gateway)), + m_routeInfoBuilder(std::move(routeInfoBuilder)), + m_nodeInfoFactory(std::move(nodeInfoFactory)) + {} + virtual ~GatewayServer() = default; + + grpc::ServerUnaryReactor* asyncSendMessage(grpc::CallbackServerContext* context, + const ppc::proto::SendedMessageRequest* sendedMsg, ppc::proto::Error* reply) override; + + grpc::ServerUnaryReactor* selectNodesByRoutePolicy(grpc::CallbackServerContext* context, + const ppc::proto::SelectRouteRequest* selectRouteRequest, + ppc::proto::NodeList* reply) override; + + grpc::ServerUnaryReactor* asyncGetPeers(grpc::CallbackServerContext* context, + const ppc::proto::Empty* request, ppc::proto::PeersInfo* reply) override; + grpc::ServerUnaryReactor* asyncGetAgencies(grpc::CallbackServerContext* context, + const ppc::proto::Condition* request, ppc::proto::AgenciesInfo* reply) override; + + grpc::ServerUnaryReactor* getAliveNodeList(grpc::CallbackServerContext* context, + const ppc::proto::Empty* request, ppc::proto::NodeInfoList* reply) override; + + grpc::ServerUnaryReactor* registerNodeInfo(grpc::CallbackServerContext* context, + const ppc::proto::NodeInfo* nodeInfo, ppc::proto::Error* reply) override; + + grpc::ServerUnaryReactor* unRegisterNodeInfo(grpc::CallbackServerContext* context, + const ppc::proto::NodeInfo* nodeInfo, ppc::proto::Error* reply) override; + + grpc::ServerUnaryReactor* registerTopic(grpc::CallbackServerContext* context, + const ppc::proto::NodeInfo* nodeInfo, ppc::proto::Error* reply) override; + + grpc::ServerUnaryReactor* unRegisterTopic(grpc::CallbackServerContext* context, + const ppc::proto::NodeInfo* nodeInfo, ppc::proto::Error* reply) override; + + +private: + ppc::gateway::IGateway::Ptr m_gateway; + MessageOptionalHeaderBuilder::Ptr m_routeInfoBuilder; + INodeInfoFactory::Ptr m_nodeInfoFactory; +}; +}; // namespace ppc::protocol \ No newline at end of file diff --git a/cpp/wedpr-protocol/grpc/server/GrpcServer.cpp b/cpp/wedpr-protocol/grpc/server/GrpcServer.cpp new file mode 100644 index 00000000..6013a920 --- /dev/null +++ b/cpp/wedpr-protocol/grpc/server/GrpcServer.cpp @@ -0,0 +1,90 @@ +/** + * 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 GrpcServer.cpp + * @author: yujiechen + * @date 2024-09-03 + */ +#include "GrpcServer.h" +#include "Common.h" +#include "grpcpp/ext/proto_server_reflection_plugin.h" + +using namespace ppc; +using namespace ppc::protocol; +using namespace grpc; + +void GrpcServer::start() +{ + if (m_running) + { + GRPC_SERVER_LOG(INFO) << LOG_DESC("GrpcServer has already been started!") + << LOG_KV("listenEndPoint", m_config->listenEndPoint()); + return; + } + m_running = true; + if (m_config->enableHealthCheck()) + { + grpc::EnableDefaultHealthCheckService(true); + } + grpc::reflection::InitProtoReflectionServerBuilderPlugin(); + grpc::ServerBuilder builder; + // disable port reuse + builder.AddChannelArgument(GRPC_ARG_ALLOW_REUSEPORT, 0); + // without authentication + builder.AddListeningPort(m_config->listenEndPoint(), grpc::InsecureServerCredentials()); + builder.SetMaxMessageSize(m_config->grpcConfig()->maxMsgSize()); + builder.SetMaxSendMessageSize(m_config->grpcConfig()->maxSendMessageSize()); + builder.SetMaxReceiveMessageSize(m_config->grpcConfig()->maxReceivedMessageSize()); + // register the service + for (auto const& service : m_bindingServices) + { + builder.RegisterService(service.get()); + } + m_server = std::unique_ptr(builder.BuildAndStart()); + if (!m_server) + { + GRPC_SERVER_LOG(INFO) << LOG_DESC( + "GrpcServer BuildAndStart failed, please check the port has " + "been occupied or not") + << LOG_KV("listenEndPoint", m_config->listenEndPoint()); + BOOST_THROW_EXCEPTION( + WeDPRException() << bcos::errinfo_comment("BuildAndStart grpcServer failed for bind " + "error, please check the listenPort, current " + "listenEndPoint: " + + m_config->listenEndPoint())); + } + GRPC_SERVER_LOG(INFO) << LOG_DESC("GrpcServer start success!") + << LOG_KV("listenEndPoint", m_config->listenEndPoint()) + << LOG_KV("maxMsgSize", m_config->grpcConfig()->maxMsgSize()) + << LOG_KV( + "maxSendMessageSize", m_config->grpcConfig()->maxSendMessageSize()) + << LOG_KV("maxReceivedMessageSize", + m_config->grpcConfig()->maxReceivedMessageSize()); +} + +void GrpcServer::stop() +{ + if (!m_running) + { + GRPC_SERVER_LOG(INFO) << LOG_DESC("GrpcServer has already been stopped!"); + return; + } + m_running = false; + if (m_server) + { + m_server->Shutdown(); + } + GRPC_SERVER_LOG(INFO) << LOG_DESC("GrpcServer stop success!"); +} \ No newline at end of file diff --git a/cpp/wedpr-protocol/grpc/server/GrpcServer.h b/cpp/wedpr-protocol/grpc/server/GrpcServer.h new file mode 100644 index 00000000..9d70f5a6 --- /dev/null +++ b/cpp/wedpr-protocol/grpc/server/GrpcServer.h @@ -0,0 +1,53 @@ +/** + * 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 GrpcServer.h + * @author: yujiechen + * @date 2024-09-03 + */ +#pragma once +#include "ppc-framework/protocol/GrpcConfig.h" +#include +#include +#include + +namespace ppc::protocol +{ +// refer to: https://grpc.io/docs/languages/cpp/callback/ +class GrpcServer +{ +public: + using Ptr = std::shared_ptr; + GrpcServer(GrpcServerConfig::Ptr const& config) : m_config(config) {} + virtual ~GrpcServer() = default; + + virtual void start(); + virtual void stop(); + + virtual void registerService(std::shared_ptr service) + { + m_bindingServices.emplace_back(std::move(service)); + } + + std::unique_ptr const& server() const { return m_server; } + +private: + bool m_running = false; + GrpcServerConfig::Ptr m_config; + + std::unique_ptr m_server; + std::vector> m_bindingServices; +}; +} // namespace ppc::protocol \ No newline at end of file diff --git a/cpp/wedpr-protocol/grpc/tests/CMakeLists.txt b/cpp/wedpr-protocol/grpc/tests/CMakeLists.txt new file mode 100644 index 00000000..321dff57 --- /dev/null +++ b/cpp/wedpr-protocol/grpc/tests/CMakeLists.txt @@ -0,0 +1,10 @@ +file(GLOB_RECURSE SOURCES "*.cpp" "*.h") + +# cmake settings +set(TEST_BINARY_NAME test-grpc-protocol) + +add_executable(${TEST_BINARY_NAME} ${SOURCES}) +target_include_directories(${TEST_BINARY_NAME} PRIVATE .) + +target_link_libraries(${TEST_BINARY_NAME} ${SERVICE_PB_TARGET} ${BCOS_UTILITIES_TARGET} ${BOOST_UNIT_TEST}) +add_test(NAME test-grpc-protocol WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} COMMAND ${TEST_BINARY_NAME}) diff --git a/cpp/wedpr-protocol/grpc/tests/TestGrpc.cpp b/cpp/wedpr-protocol/grpc/tests/TestGrpc.cpp new file mode 100644 index 00000000..6764816f --- /dev/null +++ b/cpp/wedpr-protocol/grpc/tests/TestGrpc.cpp @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2022 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 TestGrpc.cpp + * @author: yujiechen + * @date 2022-11-12 + */ + +#include "wedpr-protocol/grpc/Common.h" +#include +#include + +using namespace ppc::protocol; +using namespace bcos::test; +using namespace grpc; + +BOOST_FIXTURE_TEST_SUITE(GrpcTest, TestPromptFixture) + +BOOST_AUTO_TEST_CASE(testGrpc) +{ + grpc::ChannelArguments args; + uint64_t msgSize = INT_MAX; + int convertedMsgSize = msgSize; + std::cout << "compare with -1, result: " << (convertedMsgSize >= -1) << std::endl; + args.SetInt(GRPC_ARG_MAX_RECEIVE_MESSAGE_LENGTH, INT_MAX); + std::cout << "##### " << GRPC_ARG_MAX_RECEIVE_MESSAGE_LENGTH << ", " << INT_MAX << std::endl; +} + +BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file diff --git a/cpp/wedpr-protocol/grpc/tests/main.cpp b/cpp/wedpr-protocol/grpc/tests/main.cpp new file mode 100644 index 00000000..2c06f9b5 --- /dev/null +++ b/cpp/wedpr-protocol/grpc/tests/main.cpp @@ -0,0 +1,2 @@ +#define BOOST_TEST_MAIN +#include \ No newline at end of file diff --git a/cpp/wedpr-protocol/proto/pb/NodeInfo.proto b/cpp/wedpr-protocol/proto/pb/NodeInfo.proto new file mode 100644 index 00000000..7746697b --- /dev/null +++ b/cpp/wedpr-protocol/proto/pb/NodeInfo.proto @@ -0,0 +1,21 @@ +syntax = "proto3"; +package ppc.proto; + +message NodeInfo{ + // the nodeID + bytes nodeID = 1; + // the endPoint + string endPoint = 2; + // the components + repeated string components = 3; + string topic = 4; + // the meta information + string meta = 5; +}; + +message GatewayNodeInfo{ + string p2pNodeID = 1; + string agency = 2; + repeated NodeInfo nodeList = 3; + int32 statusSeq = 4; +}; \ No newline at end of file diff --git a/cpp/wedpr-protocol/proto/pb/Service.proto b/cpp/wedpr-protocol/proto/pb/Service.proto new file mode 100644 index 00000000..8980aa74 --- /dev/null +++ b/cpp/wedpr-protocol/proto/pb/Service.proto @@ -0,0 +1,79 @@ +syntax = "proto3"; +import "NodeInfo.proto"; +option java_package = "ppc.proto.grpc"; + +package ppc.proto; + +message Error{ + // the errorCode + int64 errorCode = 1; + // the errorMessage + string errorMessage = 2; +}; + +message ReceivedMessage{ + bytes data = 1; +}; + +message RouteInfo{ + string topic = 1; + string componentType = 2; + bytes srcNode = 3; + bytes dstNode = 4; + bytes dstInst = 5; +}; + +message SendedMessageRequest{ + int32 routeType = 1; + RouteInfo routeInfo = 2; + bytes payload = 3; + int64 timeout = 4; + string traceID = 5; +}; + +message SelectRouteRequest{ + int32 routeType = 1; + RouteInfo routeInfo = 2; +} + +message AgenciesInfo{ + Error error = 1; + repeated string agencies = 2; +}; + +message PeersInfo{ + Error error = 1; + string peersInfo = 2; +}; +message Empty{ + int32 status = 1; +}; + +message Condition{ + repeated string components = 1; +}; + +message NodeList{ + repeated string nodeList = 1; + Error error = 2; +}; + +message NodeInfoList{ + repeated NodeInfo nodeList = 1; + Error error = 2; +}; + +service Front { + rpc onReceiveMessage (ReceivedMessage) returns (Error) {} +} +service Gateway{ + rpc asyncSendMessage(SendedMessageRequest) returns(Error){} + rpc asyncGetPeers(Empty)returns(PeersInfo){} + rpc getAliveNodeList(Empty)returns(NodeInfoList){} + rpc selectNodesByRoutePolicy(SelectRouteRequest)returns(NodeList){} + rpc asyncGetAgencies(Condition)returns(AgenciesInfo){} + rpc registerNodeInfo(NodeInfo) returns(Error){} + rpc unRegisterNodeInfo(NodeInfo)returns(Error){} + rpc registerTopic(NodeInfo) returns(Error){} + rpc unRegisterTopic(NodeInfo) returns(Error){} +}; \ No newline at end of file diff --git a/cpp/wedpr-protocol/proto/pb/ServiceHealth.proto b/cpp/wedpr-protocol/proto/pb/ServiceHealth.proto new file mode 100644 index 00000000..38843ff1 --- /dev/null +++ b/cpp/wedpr-protocol/proto/pb/ServiceHealth.proto @@ -0,0 +1,63 @@ +// Copyright 2015 The gRPC Authors +// +// 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. + +// The canonical version of this proto can be found at +// https://github.com/grpc/grpc-proto/blob/master/grpc/health/v1/health.proto + +syntax = "proto3"; + +package grpc.health.v1; + +option csharp_namespace = "Grpc.Health.V1"; +option go_package = "google.golang.org/grpc/health/grpc_health_v1"; +option java_multiple_files = true; +option java_outer_classname = "HealthProto"; +option java_package = "io.grpc.health.v1"; + +message HealthCheckRequest { + string service = 1; +} + +message HealthCheckResponse { + enum ServingStatus { + UNKNOWN = 0; + SERVING = 1; + NOT_SERVING = 2; + SERVICE_UNKNOWN = 3; // Used only by the Watch method. + } + ServingStatus status = 1; +} + +service Health { + // If the requested service is unknown, the call will fail with status + // NOT_FOUND. + rpc Check(HealthCheckRequest) returns (HealthCheckResponse); + + // Performs a watch for the serving status of the requested service. + // The server will immediately send back a message indicating the current + // serving status. It will then subsequently send a new message whenever + // the service's serving status changes. + // + // If the requested service is unknown when the call is received, the + // server will send a message setting the serving status to + // SERVICE_UNKNOWN but will *not* terminate the call. If at some + // future point, the serving status of the service becomes known, the + // server will send a new message with the service's serving status. + // + // If the call terminates with status UNIMPLEMENTED, then clients + // should assume this method is not supported and should not retry the + // call. If the call terminates with any other status (including OK), + // clients should retry the call with appropriate exponential backoff. + rpc Watch(HealthCheckRequest) returns (stream HealthCheckResponse); +} diff --git a/cpp/wedpr-protocol/proto/tars/RouterTable.tars b/cpp/wedpr-protocol/proto/tars/RouterTable.tars new file mode 100644 index 00000000..48096cdd --- /dev/null +++ b/cpp/wedpr-protocol/proto/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/wedpr-protocol/protobuf/CMakeLists.txt b/cpp/wedpr-protocol/protobuf/CMakeLists.txt new file mode 100644 index 00000000..8ab6303d --- /dev/null +++ b/cpp/wedpr-protocol/protobuf/CMakeLists.txt @@ -0,0 +1,6 @@ +add_subdirectory(src) +if (TESTS) + enable_testing() + set(CTEST_OUTPUT_ON_FAILURE TRUE) + add_subdirectory(tests) +endif () diff --git a/cpp/wedpr-protocol/protobuf/src/CMakeLists.txt b/cpp/wedpr-protocol/protobuf/src/CMakeLists.txt new file mode 100644 index 00000000..8b23ec29 --- /dev/null +++ b/cpp/wedpr-protocol/protobuf/src/CMakeLists.txt @@ -0,0 +1,27 @@ +# proto generation +set(PROTO_INPUT_PATH ${CMAKE_SOURCE_DIR}/wedpr-protocol/proto/pb) + +file(GLOB_RECURSE MESSAGES_PROTOS "${PROTO_INPUT_PATH}/*.proto") + +find_program(PROTOC_BINARY protoc REQUIRED) + +# create PROTO_OUTPUT_PATH +file(MAKE_DIRECTORY ${PROTO_OUTPUT_PATH}) +foreach(proto_file ${MESSAGES_PROTOS}) + get_filename_component(basename ${proto_file} NAME_WE) + set(generated_file ${PROTO_OUTPUT_PATH}/${basename}.pb.cc) + + list(APPEND MESSAGES_SRCS ${generated_file}) + + message("Command: protoc --cpp_out ${PROTO_OUTPUT_PATH} -I ${PROTO_INPUT_PATH} ${proto_file}") + add_custom_command( + OUTPUT ${generated_file} + COMMAND ${PROTOC_BINARY} --cpp_out ${PROTO_OUTPUT_PATH} -I ${PROTO_INPUT_PATH} ${proto_file} + COMMENT "Generating ${generated_file} from ${proto_file}" + VERBATIM + ) +endforeach() + +file(GLOB_RECURSE SRCS *.cpp) +add_library(${PB_PROTOCOL_TARGET} ${SRCS} ${MESSAGES_SRCS}) +target_link_libraries(${PB_PROTOCOL_TARGET} PUBLIC ${BCOS_UTILITIES_TARGET} jsoncpp_static protobuf::libprotobuf ${CPU_FEATURES_LIB}) \ No newline at end of file diff --git a/cpp/wedpr-protocol/protobuf/src/Common.h b/cpp/wedpr-protocol/protobuf/src/Common.h new file mode 100644 index 00000000..09796003 --- /dev/null +++ b/cpp/wedpr-protocol/protobuf/src/Common.h @@ -0,0 +1,50 @@ +/** + * Copyright (C) 2021 FISCO BCOS. + * 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 Common.h + * @author: yujiechen + * @date 2021-04-12 + */ +#pragma once +#include "bcos-utilities/Common.h" +#include "ppc-framework/Common.h" + +namespace ppc::protocol +{ +DERIVE_PPC_EXCEPTION(PBObjectEncodeException); +DERIVE_PPC_EXCEPTION(PBObjectDecodeException); + +template +void encodePBObject(bcos::bytes& _encodedData, T _pbObject) +{ + auto encodedData = std::make_shared(); + _encodedData.resize(_pbObject->ByteSizeLong()); + if (!_pbObject->SerializeToArray(_encodedData.data(), _encodedData.size())) + { + BOOST_THROW_EXCEPTION(PBObjectEncodeException() + << bcos::errinfo_comment("encode PBObject into bytes data failed")); + } +} + +template +void decodePBObject(T _pbObject, bcos::bytesConstRef _data) +{ + if (!_pbObject->ParseFromArray(_data.data(), _data.size())) + { + BOOST_THROW_EXCEPTION(PBObjectDecodeException() + << bcos::errinfo_comment("decode bytes data into PBObject failed")); + } +} +} // namespace ppc::protocol diff --git a/cpp/wedpr-protocol/protobuf/src/NodeInfoImpl.cpp b/cpp/wedpr-protocol/protobuf/src/NodeInfoImpl.cpp new file mode 100644 index 00000000..131a7eda --- /dev/null +++ b/cpp/wedpr-protocol/protobuf/src/NodeInfoImpl.cpp @@ -0,0 +1,66 @@ +/** + * 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 ppc::protocol; + +void NodeInfoImpl::encode(bcos::bytes& data) const +{ + encodeFields(); + encodePBObject(data, m_rawNodeInfo); +} + +void NodeInfoImpl::encodeFields() const +{ + bcos::ReadGuard l(x_components); + // set the components + for (auto const& component : m_components) + { + m_rawNodeInfo->add_components(component); + } +} +void NodeInfoImpl::decode(bcos::bytesConstRef data) +{ + decodePBObject(m_rawNodeInfo, data); + decodeFields(); +} + +void NodeInfoImpl::decodeFields() +{ + bcos::WriteGuard l(x_components); + m_components = std::set( + m_rawNodeInfo->components().begin(), m_rawNodeInfo->components().end()); +} + +void NodeInfoImpl::toJson(Json::Value& jsonObject) const +{ + jsonObject["nodeID"] = std::string(nodeID().begin(), nodeID().end()); + jsonObject["endPoint"] = endPoint(); + Json::Value componentsInfo(Json::arrayValue); + auto componentsList = components(); + for (auto const& it : componentsList) + { + componentsInfo.append(it); + } + jsonObject["components"] = componentsInfo; + jsonObject["meta"] = meta(); +} \ No newline at end of file diff --git a/cpp/wedpr-protocol/protobuf/src/NodeInfoImpl.h b/cpp/wedpr-protocol/protobuf/src/NodeInfoImpl.h new file mode 100644 index 00000000..2d4cf90e --- /dev/null +++ b/cpp/wedpr-protocol/protobuf/src/NodeInfoImpl.h @@ -0,0 +1,177 @@ +/** + * 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 "NodeInfo.pb.h" +#include "ppc-framework/protocol/INodeInfo.h" +#include + +namespace ppc::protocol +{ +// the node information +class NodeInfoImpl : public INodeInfo +{ +public: + using Ptr = std::shared_ptr; + NodeInfoImpl() { m_rawNodeInfo = std::make_shared(); } + explicit NodeInfoImpl(std::shared_ptr rawNodeInfo) + : m_rawNodeInfo(rawNodeInfo) + { + decodeFields(); + } + NodeInfoImpl(bcos::bytesConstRef const& data) : NodeInfoImpl() { decode(data); } + + NodeInfoImpl(bcos::bytesConstRef const& nodeID, std::string const& endPoint) : NodeInfoImpl() + { + *(m_rawNodeInfo->mutable_nodeid()) = + std::string_view((const char*)nodeID.data(), nodeID.size()); + m_rawNodeInfo->set_endpoint(endPoint); + } + + ~NodeInfoImpl() override {} + + void setNodeID(bcos::bytesConstRef nodeID) override + { + *(m_rawNodeInfo->mutable_nodeid()) = + std::string_view((const char*)nodeID.data(), nodeID.size()); + } + void setEndPoint(std::string const& endPoint) override + { + m_rawNodeInfo->set_endpoint(endPoint); + } + + void setComponents(std::set const& components) override + { + bcos::WriteGuard l(x_components); + m_components = components; + } + + std::set const& components() const override + { + bcos::ReadGuard l(x_components); + return m_components; + } + bool componentExist(std::string const& component) const override + { + bcos::ReadGuard l(x_components); + return m_components.count(component); + } + + std::vector copiedComponents() const override + { + bcos::ReadGuard l(x_components); + return std::vector(m_components.begin(), m_components.end()); + } + + bool addComponent(std::string const& component) override + { + bcos::UpgradableGuard l(x_components); + if (m_components.count(component)) + { + return false; + } + bcos::UpgradeGuard ul(l); + m_components.insert(component); + return true; + } + + bool eraseComponent(std::string const& component) override + { + bcos::UpgradableGuard l(x_components); + if (!m_components.count(component)) + { + return false; + } + bcos::UpgradeGuard ul(l); + m_components.erase(component); + return true; + } + + std::string const& endPoint() const override { return m_rawNodeInfo->endpoint(); } + + bcos::bytesConstRef nodeID() const override + { + return {reinterpret_cast(m_rawNodeInfo->nodeid().data()), + m_rawNodeInfo->nodeid().size()}; + } + + void encode(bcos::bytes& data) const override; + void decode(bcos::bytesConstRef data) override; + std::shared_ptr rawNodeInfo() { return m_rawNodeInfo; } + + void setFront(std::shared_ptr&& front) override + { + bcos::WriteGuard l(x_front); + m_front = std::move(front); + } + std::shared_ptr getFront() const override + { + bcos::ReadGuard l(x_front); + return m_front; + } + + void toJson(Json::Value& jsonObject) const override; + + std::string meta() const override + { + bcos::ReadGuard l(x_rawNodeInfo); + return m_rawNodeInfo->meta(); + } + // the node meta information + void setMeta(std::string const& meta) override + { + bcos::WriteGuard l(x_rawNodeInfo); + m_rawNodeInfo->set_meta(meta); + } + + virtual void encodeFields() const; + +protected: + virtual void decodeFields(); + +private: + std::shared_ptr m_front; + mutable bcos::SharedMutex x_front; + + std::set m_components; + mutable bcos::SharedMutex x_components; + + std::shared_ptr m_rawNodeInfo; + mutable bcos::SharedMutex x_rawNodeInfo; +}; + +class NodeInfoFactory : public INodeInfoFactory +{ +public: + using Ptr = std::shared_ptr; + NodeInfoFactory() {} + ~NodeInfoFactory() override {} + + INodeInfo::Ptr build() override { return std::make_shared(); } + + INodeInfo::Ptr build(bcos::bytesConstRef data) override + { + return std::make_shared(data); + } + INodeInfo::Ptr build(bcos::bytesConstRef nodeID, std::string const& endPoint) override + { + return std::make_shared(nodeID, endPoint); + } +}; +} // namespace ppc::protocol \ No newline at end of file diff --git a/cpp/wedpr-protocol/protobuf/src/RequestConverter.h b/cpp/wedpr-protocol/protobuf/src/RequestConverter.h new file mode 100644 index 00000000..61394dde --- /dev/null +++ b/cpp/wedpr-protocol/protobuf/src/RequestConverter.h @@ -0,0 +1,176 @@ +/** + * Copyright (C) 2021 FISCO BCOS. + * 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 RequestConverter.h + * @author: yujiechen + * @date 2021-04-12 + */ +#pragma once +#include "Service.pb.h" +#include "ppc-framework/protocol/INodeInfo.h" +#include "ppc-framework/protocol/Message.h" +#include "ppc-framework/protocol/Protocol.h" +#include +#include +#include +#include + +namespace ppc::protocol +{ +inline MessageOptionalHeader::Ptr generateRouteInfo( + MessageOptionalHeaderBuilder::Ptr const& routeInfoBuilder, + ppc::proto::RouteInfo const& serializedRouteInfo) +{ + auto routeInfo = routeInfoBuilder->build(); + routeInfo->setComponentType(serializedRouteInfo.componenttype()); + routeInfo->setSrcNode( + bcos::bytes(serializedRouteInfo.srcnode().begin(), serializedRouteInfo.srcnode().end())); + routeInfo->setDstNode( + bcos::bytes(serializedRouteInfo.dstnode().begin(), serializedRouteInfo.dstnode().end())); + routeInfo->setDstInst(serializedRouteInfo.dstinst()); + routeInfo->setTopic(serializedRouteInfo.topic()); + return routeInfo; +} + +inline void setRouteInfo( + ppc::proto::RouteInfo* route_info, MessageOptionalHeader::Ptr const& routeInfo) +{ + // set the route information + route_info->set_topic(routeInfo->topic()); + route_info->set_componenttype(routeInfo->componentType()); + *(route_info->mutable_srcnode()) = + std::string((const char*)routeInfo->srcNode().data(), routeInfo->srcNode().size()); + *(route_info->mutable_dstnode()) = + std::string((const char*)routeInfo->dstNode().data(), routeInfo->dstNode().size()); + *(route_info->mutable_dstinst()) = routeInfo->dstInst(); +} + +inline ppc::proto::SendedMessageRequest* generateRequest(std::string const& traceID, + RouteType routeType, MessageOptionalHeader::Ptr const& routeInfo, bcos::bytes&& payload, + long timeout) +{ + auto request = new ppc::proto::SendedMessageRequest(); + request->set_traceid(traceID); + request->set_routetype(uint16_t(routeType)); + // set the route information + setRouteInfo(request->mutable_routeinfo(), routeInfo); + *request->mutable_payload() = + std::move(std::string_view((const char*)payload.data(), payload.size())); + request->set_timeout(timeout); + return request; +} + +inline ppc::proto::SelectRouteRequest* generateSelectRouteRequest( + RouteType routeType, MessageOptionalHeader::Ptr const& routeInfo) +{ + auto request = new ppc::proto::SelectRouteRequest(); + request->set_routetype(uint16_t(routeType)); + // set the route information + setRouteInfo(request->mutable_routeinfo(), routeInfo); + return request; +} + +inline ppc::proto::NodeInfo* toNodeInfoRequest( + bcos::bytesConstRef const& nodeID, std::string const& topic) +{ + auto request = new ppc::proto::NodeInfo(); + *(request->mutable_nodeid()) = std::string_view((const char*)nodeID.data(), nodeID.size()); + request->set_topic(topic); + return request; +} + +inline void toNodeInfoRequest(ppc::proto::NodeInfo* request, INodeInfo::Ptr const& nodeInfo) +{ + if (!nodeInfo) + { + return; + }; + *(request->mutable_nodeid()) = + std::string_view((const char*)nodeInfo->nodeID().data(), nodeInfo->nodeID().size()); + request->set_endpoint(nodeInfo->endPoint()); + auto const& components = nodeInfo->components(); + for (auto const& component : components) + { + request->add_components(component); + } + request->set_meta(nodeInfo->meta()); +} + +inline void toRawNodeInfoList( + ppc::proto::NodeInfoList* rawNodeInfoList, std::vector const& nodeInfoList) +{ + for (auto const& it : nodeInfoList) + { + auto rawNodeInfo = rawNodeInfoList->add_nodelist(); + toNodeInfoRequest(rawNodeInfo, it); + } +} + +inline INodeInfo::Ptr toNodeInfo( + INodeInfoFactory::Ptr const& nodeInfoFactory, ppc::proto::NodeInfo const& serializedNodeInfo) +{ + auto nodeInfo = nodeInfoFactory->build(); + nodeInfo->setNodeID(bcos::bytesConstRef( + (bcos::byte*)serializedNodeInfo.nodeid().data(), serializedNodeInfo.nodeid().size())); + nodeInfo->setEndPoint(serializedNodeInfo.endpoint()); + std::set componentTypeList; + for (int i = 0; i < serializedNodeInfo.components_size(); i++) + { + componentTypeList.insert(serializedNodeInfo.components(i)); + } + nodeInfo->setComponents(componentTypeList); + nodeInfo->setMeta(serializedNodeInfo.meta()); + return nodeInfo; +} + +inline std::vector toNodeInfoList(INodeInfoFactory::Ptr const& nodeInfoFactory, + ppc::proto::NodeInfoList const& serializedNodeListInfo) +{ + std::vector result; + for (int i = 0; i < serializedNodeListInfo.nodelist_size(); i++) + { + result.emplace_back(toNodeInfo(nodeInfoFactory, serializedNodeListInfo.nodelist(i))); + } + return result; +} + +inline bcos::Error::Ptr toError(grpc::Status const& status, ppc::proto::Error const& error) +{ + if (!status.ok()) + { + return std::make_shared((int32_t)status.error_code(), status.error_message()); + } + if (error.errorcode() == 0) + { + return nullptr; + } + return std::make_shared(error.errorcode(), error.errormessage()); +} + +inline void toSerializedError(ppc::proto::Error* serializedError, bcos::Error::Ptr error) +{ + if (!serializedError) + { + return; + } + if (!error) + { + serializedError->set_errorcode(PPCRetCode::SUCCESS); + return; + } + serializedError->set_errorcode(error->errorCode()); + serializedError->set_errormessage(error->errorMessage()); +} +}; // namespace ppc::protocol \ No newline at end of file diff --git a/cpp/wedpr-protocol/protobuf/tests/CMakeLists.txt b/cpp/wedpr-protocol/protobuf/tests/CMakeLists.txt new file mode 100644 index 00000000..c7310f2f --- /dev/null +++ b/cpp/wedpr-protocol/protobuf/tests/CMakeLists.txt @@ -0,0 +1,10 @@ +file(GLOB_RECURSE SOURCES "*.cpp" "*.h") + +# cmake settings +set(TEST_BINARY_NAME test-protobuf) + +add_executable(${TEST_BINARY_NAME} ${SOURCES}) +target_include_directories(${TEST_BINARY_NAME} PRIVATE .) + +target_link_libraries(${TEST_BINARY_NAME} ${PB_PROTOCOL_TARGET} TBB::tbb ${BOOST_UNIT_TEST}) +add_test(NAME test-protobuf WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} COMMAND ${TEST_BINARY_NAME}) \ No newline at end of file diff --git a/cpp/wedpr-protocol/protobuf/tests/NodeInfoImplTest.cpp b/cpp/wedpr-protocol/protobuf/tests/NodeInfoImplTest.cpp new file mode 100644 index 00000000..6d0de595 --- /dev/null +++ b/cpp/wedpr-protocol/protobuf/tests/NodeInfoImplTest.cpp @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2022 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 NodeInfoImplTest.cpp + * @author: yujiechen + * @date 2024-09-06 + */ +#include "protobuf/src/NodeInfoImpl.h" +#include "protobuf/src/RequestConverter.h" +#include +#include +#include + +using namespace ppc; +using namespace ppc::proto; +using namespace ppc::protocol; +using namespace bcos::test; + +BOOST_FIXTURE_TEST_SUITE(NodeInfoTest, TestPromptFixture) + +INodeInfo::Ptr fakeNodeInfo(INodeInfoFactory::Ptr factory, std::string const& nodeID, + std::string const& endPoint, std::set const& components) +{ + auto nodeInfo = factory->build(); + nodeInfo->setNodeID(bcos::bytesConstRef((bcos::byte*)nodeID.data(), nodeID.size())); + nodeInfo->setEndPoint(endPoint); + nodeInfo->setComponents(components); + return nodeInfo; +} + + +void testNodeInfoEncodeDecode(INodeInfoFactory::Ptr factory, INodeInfo::Ptr nodeInfo) +{ + bcos::bytes encodedData; + nodeInfo->encode(encodedData); + + auto decodedNodeInfo = factory->build(bcos::ref(encodedData)); + BOOST_CHECK(nodeInfo->nodeID().toBytes() == decodedNodeInfo->nodeID().toBytes()); + BOOST_CHECK(nodeInfo->endPoint() == decodedNodeInfo->endPoint()); + auto const& components = nodeInfo->components(); + for (auto const& decodedComp : decodedNodeInfo->components()) + { + BOOST_CHECK(components.count(decodedComp)); + } +} + +void testPayloadMove(int payloadSize, int round) +{ + bcos::bytes payload; + char tmp = 'a'; + for (int i = 0; i < payloadSize; i++) + { + payload.emplace_back((char)(tmp + 1)); + } + auto startT = bcos::utcSteadyTime(); + auto request = new ppc::proto::SendedMessageRequest(); + for (int i = 0; i < round; i++) + { + std::unique_ptr request( + new ppc::proto::SendedMessageRequest()); + //*request->mutable_payload() = std::move(std::string_view((const char*)payload.data(), + //payload.size())); + *request->mutable_payload() = std::string_view((const char*)payload.data(), payload.size()); + // request->set_payload((const char*)payload.data(), payload.size()); + // std::cout << "#### request size: " << request->payload().size() << ", origin payload + // size: " << payloadSize << std::endl; + BOOST_CHECK(*request->mutable_payload() == std::string(payload.begin(), payload.end())); + } + std::cout << "### testPayloadMove, timecost: " << (bcos::utcSteadyTime() - startT) << std::endl; +} + +BOOST_AUTO_TEST_CASE(testNodeInfo) +{ + auto nodeInfoFactory = std::make_shared(); + std::string nodeID = "testn+NodeID"; + std::string endPoint = "testEndpoint"; + std::set components; + for (int i = 0; i < 100; i++) + { + components.insert("component_" + std::to_string(i)); + } + auto nodeInfo = fakeNodeInfo(nodeInfoFactory, nodeID, endPoint, components); + testNodeInfoEncodeDecode(nodeInfoFactory, nodeInfo); +} + +BOOST_AUTO_TEST_CASE(payloadMoveTest) +{ + testPayloadMove(10, 1); + testPayloadMove(100000, 10); + testPayloadMove(10000000, 10); +} + +BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file diff --git a/cpp/wedpr-protocol/protobuf/tests/main.cpp b/cpp/wedpr-protocol/protobuf/tests/main.cpp new file mode 100644 index 00000000..2c06f9b5 --- /dev/null +++ b/cpp/wedpr-protocol/protobuf/tests/main.cpp @@ -0,0 +1,2 @@ +#define BOOST_TEST_MAIN +#include \ No newline at end of file diff --git a/cpp/wedpr-protocol/protocol/CMakeLists.txt b/cpp/wedpr-protocol/protocol/CMakeLists.txt new file mode 100644 index 00000000..8ab6303d --- /dev/null +++ b/cpp/wedpr-protocol/protocol/CMakeLists.txt @@ -0,0 +1,6 @@ +add_subdirectory(src) +if (TESTS) + enable_testing() + set(CTEST_OUTPUT_ON_FAILURE TRUE) + add_subdirectory(tests) +endif () diff --git a/cpp/wedpr-protocol/protocol/src/CMakeLists.txt b/cpp/wedpr-protocol/protocol/src/CMakeLists.txt new file mode 100644 index 00000000..60a80615 --- /dev/null +++ b/cpp/wedpr-protocol/protocol/src/CMakeLists.txt @@ -0,0 +1,4 @@ +file(GLOB_RECURSE SRCS *.cpp) +add_library(${PROTOCOL_TARGET} ${SRCS}) + +target_link_libraries(${PROTOCOL_TARGET} PUBLIC ${CPU_FEATURES_LIB} jsoncpp_static) diff --git a/cpp/wedpr-protocol/protocol/src/Common.h b/cpp/wedpr-protocol/protocol/src/Common.h new file mode 100644 index 00000000..9875b303 --- /dev/null +++ b/cpp/wedpr-protocol/protocol/src/Common.h @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2022 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 Common.h + * @author: yujiechen + * @date 2024-9-6 + */ + +#pragma once + +#include "ppc-framework/Common.h" +#include + +namespace ppc::gateway +{ +#define PROTOCOL_LOG(LEVEL) BCOS_LOG(LEVEL) << "[PROTOCOL]" +} // namespace ppc::gateway \ No newline at end of file diff --git a/cpp/wedpr-protocol/protocol/src/JsonTaskImpl.cpp b/cpp/wedpr-protocol/protocol/src/JsonTaskImpl.cpp new file mode 100644 index 00000000..a0052b37 --- /dev/null +++ b/cpp/wedpr-protocol/protocol/src/JsonTaskImpl.cpp @@ -0,0 +1,443 @@ +/* + * Copyright (C) 2022 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 JsonTaskImpl.cpp + * @author: yujiechen + * @date 2022-10-18 + */ +#include "JsonTaskImpl.h" +#include +#include + +using namespace ppc; +using namespace bcos; +using namespace ppc::protocol; + + +void JsonTaskImpl::decode(std::string_view _taskData) +{ + Json::Value root; + Json::Reader jsonReader; + + if (!jsonReader.parse(std::string(_taskData), root)) + { + BOOST_THROW_EXCEPTION(InvalidParameter() << errinfo_comment( + "The task information must be valid json string.")); + } + decodeJsonValue(root); +} + +void JsonTaskImpl::decodeJsonValue(Json::Value const& root) +{ + // the taskID + if (!root.isMember("taskID")) + { + BOOST_THROW_EXCEPTION(InvalidParameter() << errinfo_comment("Must specify the taskID")); + } + checkNull(root["taskID"], "taskID"); + m_id = root["taskID"].asString(); + + // the taskType + if (!root.isMember("type")) + { + BOOST_THROW_EXCEPTION(InvalidParameter() << errinfo_comment("Must specify the taskType")); + } + if (root.isMember("enableOutputExists")) + { + m_enableOutputExists = root["enableOutputExists"].asBool(); + } + checkNull(root["type"], "taskType"); + m_type = root["type"].asUInt(); + // the taskAlgorithm + if (!root.isMember("algorithm")) + { + BOOST_THROW_EXCEPTION( + InvalidParameter() << errinfo_comment("Must specify the taskAlgorithm")); + } + checkNull(root["algorithm"], "taskAlgorithm"); + m_algorithm = root["algorithm"].asUInt(); + + // the parameters + if (root.isMember("params") && !root["params"].isNull()) + { + m_param = root["params"].asString(); + } + // sync result to peer or not + if (root.isMember("syncResult") && !root["syncResult"].isNull()) + { + m_syncResultToPeer = root["syncResult"].asBool(); + } + if (root.isMember("lowBandwidth") && !root["lowBandwidth"].isNull()) + { + m_lowBandwidth = root["lowBandwidth"].asBool(); + } + if (root.isMember("receiverList") && !root["receiverList"].isNull() && + root["receiverList"].isArray()) + { + Json::Value _receivers = root["receiverList"]; + for (const auto& r : _receivers) + { + if (r.isString()) + { + m_receiverLists.push_back(r.asString()); + } + } + } + + checkNull(root["parties"], "parties"); + // the peer-parties-info + if (!root.isMember("parties")) + { + return; + } + auto const& peersPartyEntry = root["parties"]; + for (Json::ArrayIndex i = 0; i < peersPartyEntry.size(); i++) + { + auto partyInfo = std::make_shared(); + decodePartyInfo(partyInfo, peersPartyEntry[i]); + // obtain the self-party + if (partyInfo->id() == m_selfPartyID) + { + m_self = partyInfo; + } + else + { + m_peerParties[partyInfo->id()] = partyInfo; + } + } + if (!m_self) + { + BOOST_THROW_EXCEPTION( + InvalidParameter() << errinfo_comment("Must specify the self-party-info")); + } +} + +// decode the party-info +void JsonTaskImpl::decodePartyInfo(PartyResource::Ptr _partyInfo, Json::Value const& _root) +{ + // the partyIndex + if (_root.isMember("partyIndex") && !_root["partyIndex"].isNull()) + { + _partyInfo->setPartyIndex(_root["partyIndex"].asUInt()); + } + // the partyID + if (!_root.isMember("id")) + { + BOOST_THROW_EXCEPTION(InvalidParameter() << errinfo_comment("Must specify the partyID")); + } + checkNull(_root["id"], "partyID"); + _partyInfo->setId(_root["id"].asString()); + // the desc + if (_root.isMember("desc")) + { + _partyInfo->setDesc(_root["desc"].asString()); + } + // the data-resource + if (_root.isMember("data") && !_root["data"].isNull()) + { + _partyInfo->setDataResource(decodeDataResource(_root["data"])); + } +} + +// decode the data-resource-info +DataResource::Ptr JsonTaskImpl::decodeDataResource(Json::Value const& _root) +{ + auto dataResource = std::make_shared(); + // the resourceID + if (!_root.isMember("id")) + { + BOOST_THROW_EXCEPTION( + InvalidParameter() << errinfo_comment("Must specify the id for the data-resource")); + } + checkNull(_root["id"], "data-resource-id"); + dataResource->setResourceID(_root["id"].asString()); + // the resource-desc + if (_root.isMember("input") && !_root["input"].isNull()) + { + // decode the input + auto const& descEntry = _root["input"]; + auto dataDesc = std::make_shared(); + decodeDataResourceDesc(dataDesc, descEntry); + dataResource->setDesc(dataDesc); + } + // decode the output + if (_root.isMember("output") && !_root["output"].isNull()) + { + auto outputDesc = std::make_shared(); + decodeDataResourceDesc(outputDesc, _root["output"]); + dataResource->setOutputDesc(outputDesc); + } + // decode the rawData + if (_root.isMember("rawData") && !_root["rawData"].isNull()) + { + DataResource::OriginData originData; + for (auto& members : _root["rawData"]) + { + std::vector data; + for (auto& member : members) + { + data.emplace_back(member.asString()); + } + originData.emplace_back(data); + } + dataResource->setRawData(originData); + } + return dataResource; +} + +void JsonTaskImpl::decodeDataResourceDesc(DataResourceDesc::Ptr _desc, Json::Value const& _value) +{ + // the dataResourceType + // Note: the data-resource is not required for the psi-server + if (_value.isMember("type")) + { + _desc->setType(_value["type"].asUInt()); + } + if (_value.isMember("path")) + { + auto path = _value["path"].asString(); + if (_desc->type() == (int)DataResourceType::FILE) + { + if (path.find("..") != std::string::npos) + { + BOOST_THROW_EXCEPTION( + InvalidParameter() << errinfo_comment("The \"..\" cannot be in the path")); + } + if (path.rfind("/", 0) == 0) + { + _desc->setPath(path); + } + else + { + boost::filesystem::path prePath(m_prePath); + boost::filesystem::path inputPath(path); + boost::filesystem::path filePath(prePath / inputPath); + _desc->setPath(filePath.string()); + } + } + else + { + _desc->setPath(_value["path"].asString()); + } + } + if (_value.isMember("command")) + { + _desc->setAccessCommand(_value["command"].asString()); + } + if (_value.isMember("fileID")) + { + _desc->setFileID(_value["fileID"].asString()); + } + if (_value.isMember("fileMd5")) + { + _desc->setFileMd5(_value["fileMd5"].asString()); + } + if (_value.isMember("bizSeqNo")) + { + _desc->setBizSeqNo(_value["bizSeqNo"].asString()); + } + + // decode the connection option + if (_desc->type() == (int)DataResourceType::MySQL) + { + if (!_value.isMember("source")) + { + return; + // BOOST_THROW_EXCEPTION(InvalidParameter() << errinfo_comment( + // "The MySQL type resource must define the + // source")); + } + auto const& connectionOption = _value["source"]; + SQLConnectionOption option; + option.host = connectionOption["host"].asString(); + checkNonEmptyField("host", option.host); + + option.port = connectionOption["port"].asUInt(); + option.user = connectionOption["user"].asString(); + checkNonEmptyField("user", option.user); + + option.password = connectionOption["password"].asString(); + checkNonEmptyField("password", option.password); + + option.database = connectionOption["database"].asString(); + checkNonEmptyField("database", option.database); + + _desc->setSQLConnectionOption(std::make_shared(option)); + } + // decode the hdfs + if (_desc->type() == (int)DataResourceType::HDFS) + { + if (!_value.isMember("source")) + { + return; + // BOOST_THROW_EXCEPTION(InvalidParameter() << errinfo_comment( + // "The HDFS type resource must define the + // source")); + } + auto option = std::make_shared(); + auto const& fileStorageOpt = _value["source"]; + option->nameNode = fileStorageOpt["nameNode"].asString(); + checkNonEmptyField("nameNode", option->nameNode); + option->nameNodePort = fileStorageOpt["nameNodePort"].asUInt(); + option->userName = fileStorageOpt["user"].asString(); + checkNonEmptyField("user", option->userName); + + option->token = fileStorageOpt["token"].asString(); + _desc->setFileStorageConnectOption(option); + } +} + +std::string JsonTaskImpl::encode() const +{ + Json::Value taskInfo; + // the taskID + taskInfo["taskID"] = m_id; + // the taskType + taskInfo["type"] = m_type; + // the task-algorithm + taskInfo["algorithm"] = m_algorithm; + // params + taskInfo["params"] = m_param; + // sync-result or not + taskInfo["syncResult"] = m_syncResultToPeer; + taskInfo["lowBandwidth"] = m_lowBandwidth; + taskInfo["enableOutputExists"] = m_enableOutputExists; + + Json::Value receiverList; + for (auto const& it : m_receiverLists) + { + receiverList.append(it); + } + taskInfo["receiverList"] = receiverList; + + Json::Value partiesInfo(Json::arrayValue); + // encode the partyInfo + if (m_self) + { + Json::Value selfPartyInfo; + encodePartyInfo(selfPartyInfo, m_self); + partiesInfo.append(selfPartyInfo); + } + for (auto const& it : m_peerParties) + { + Json::Value partyInfo; + encodePartyInfo(partyInfo, it.second); + partiesInfo.append(partyInfo); + } + taskInfo["parties"] = partiesInfo; + Json::FastWriter fastWriter; + return fastWriter.write(taskInfo); +} + +void JsonTaskImpl::encodePartyInfo(Json::Value& _value, PartyResource::Ptr _party) const +{ + // the partyIndex + _value["partyIndex"] = _party->partyIndex(); + // the partyID + _value["id"] = _party->id(); + // the desc + _value["desc"] = _party->desc(); + // the dataResource + encodeDataResource(_value["data"], _party->dataResource()); +} + +void JsonTaskImpl::encodeDataResource( + Json::Value& _value, DataResource::ConstPtr _dataResource) const +{ + // the dataID + _value["id"] = _dataResource->resourceID(); + // the desc + if (_dataResource->desc()) + { + // the type + _value["input"] = encodeDataResourceDesc(_dataResource->desc()); + } + if (_dataResource->outputDesc()) + { + _value["output"] = encodeDataResourceDesc(_dataResource->outputDesc()); + } + if (!_dataResource->rawData().empty()) + { + Json::Value jsonOriginData; + for (auto& dataVector : _dataResource->rawData()) + { + Json::Value jsonData; + for (auto& data : dataVector) + { + jsonData.append(data); + } + jsonOriginData.append(jsonData); + } + _value["rawData"] = jsonOriginData; + } +} + +Json::Value JsonTaskImpl::encodeDataResourceDesc(DataResourceDesc::ConstPtr _desc) const +{ + Json::Value result; + result["type"] = _desc->type(); + result["path"] = _desc->path(); + result["command"] = _desc->accessCommand(); + // encode the sql connection option + Json::Value connectOption; + if (_desc->sqlConnectionOption()) + { + connectOption["host"] = _desc->sqlConnectionOption()->host; + connectOption["port"] = _desc->sqlConnectionOption()->port; + connectOption["user"] = _desc->sqlConnectionOption()->user; + connectOption["password"] = _desc->sqlConnectionOption()->password; + connectOption["database"] = _desc->sqlConnectionOption()->database; + } + // encode the file-storage-connection-option + auto const& fileStorageOpt = _desc->fileStorageConnectionOption(); + if (fileStorageOpt) + { + connectOption["nameNode"] = fileStorageOpt->nameNode; + connectOption["nameNodePort"] = fileStorageOpt->nameNodePort; + connectOption["user"] = fileStorageOpt->userName; + connectOption["token"] = fileStorageOpt->token; + } + result["source"] = connectOption; + return result; +} + +PartyResource::ConstPtr JsonTaskImpl::getPartyByID(std::string const& _partyID) const +{ + if (m_self && m_self->id() == _partyID) + { + return m_self; + } + if (m_peerParties.count(_partyID)) + { + return m_peerParties.at(_partyID); + } + return nullptr; +} + +PartyResource::ConstPtr JsonTaskImpl::getPartyByIndex(uint16_t _partyIndex) const +{ + if (m_self->partyIndex() == _partyIndex) + { + return m_self; + } + for (const auto& peerParty : m_peerParties) + { + if (peerParty.second->partyIndex() == _partyIndex) + { + return peerParty.second; + } + } + return nullptr; +} diff --git a/cpp/wedpr-protocol/protocol/src/JsonTaskImpl.h b/cpp/wedpr-protocol/protocol/src/JsonTaskImpl.h new file mode 100644 index 00000000..b0883b31 --- /dev/null +++ b/cpp/wedpr-protocol/protocol/src/JsonTaskImpl.h @@ -0,0 +1,177 @@ +/* + * Copyright (C) 2022 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 JsonTaskImpl.h + * @author: yujiechen + * @date 2022-10-18 + */ +#pragma once +#include "ppc-framework/protocol/Task.h" +#include +#include + +#include + +namespace ppc::protocol +{ +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_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) + { + decodeJsonValue(_taskJson); + } + + ~JsonTaskImpl() override = default; + + // the taskID + std::string const& id() const override { return m_id; } + // the taskType, e.g. PSI + uint8_t type() const override { return m_type; } + // the task algorithm, e.g.CM_PSI_2PC/RA_PSI_2PC + uint8_t algorithm() const override { return m_algorithm; } + + // information of the local party + PartyResource::ConstPtr selfParty() const override { return m_self; } + PartyResource::Ptr mutableSelfParty() const override { return m_self; } + + // information of the peer party(not thread-safe) + PartyResource::ConstPtr getPartyByID(std::string const& _partyID) const override; + PartyResource::ConstPtr getPartyByIndex(uint16_t _partyIndex) const override; + // get all peer-parties(not thread-safe) + std::map const& getAllPeerParties() const override + { + return m_peerParties; + } + + 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; } + + // sync the psi result to peer or not + bool syncResultToPeer() const override { return m_syncResultToPeer; } + bool lowBandwidth() const override { return m_lowBandwidth; } + + void setId(std::string const& _id) override { m_id = _id; } + void setType(uint8_t _type) override { m_type = _type; } + void setAlgorithm(uint8_t _algorithm) override { m_algorithm = _algorithm; } + void setSelf(PartyResource::Ptr _self) override { m_self = _self; } + + // Note: not thread-safe here + void addParty(PartyResource::Ptr _party) override { m_peerParties[_party->id()] = _party; } + void setParam(std::string const& _param) override { m_param = _param; } + + void setSyncResultToPeer(bool _syncResultToPeer) override + { + m_syncResultToPeer = _syncResultToPeer; + } + 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); + // encode the task into json + std::string encode() const override; + +public: + void decodePartyInfo(PartyResource::Ptr _partyInfo, Json::Value const& _root); + DataResource::Ptr decodeDataResource(Json::Value const& _root); + void decodeDataResourceDesc(DataResourceDesc::Ptr _desc, Json::Value const& _value); + + void encodePartyInfo(Json::Value& _value, PartyResource::Ptr _party) const; + void encodeDataResource(Json::Value& _value, DataResource::ConstPtr _dataResource) const; + Json::Value encodeDataResourceDesc(DataResourceDesc::ConstPtr _desc) const; + + void checkNonEmptyField(std::string const& _field, std::string const& _value) + { + if (_value.empty()) + { + BOOST_THROW_EXCEPTION(bcos::InvalidParameter() << bcos::errinfo_comment( + "The value of " + _field + " must be non-empty")); + } + } + + void checkNull(Json::Value const& _value, std::string const& _field) + { + if (!_value.isNull()) + { + return; + } + BOOST_THROW_EXCEPTION(bcos::InvalidParameter() << bcos::errinfo_comment( + "The value of " + _field + " must be not null!")); + } + +private: + std::string m_selfPartyID; + std::string m_prePath; + std::string m_id; + // the task type + uint8_t m_type; + // the task-algorithm + uint8_t m_algorithm; + PartyResource::Ptr m_self; + // the partyID to PartyResource + std::map m_peerParties; + std::vector m_receiverLists; + // parameters + std::string m_param; + bool m_syncResultToPeer = false; + bool m_lowBandwidth = false; +}; + +class JsonTaskFactory : public TaskFactory +{ +public: + using Ptr = std::shared_ptr; + using ConstPtr = std::shared_ptr; + JsonTaskFactory(std::string const& _selfPartyID, const std::string& _prePath = "data") + : m_selfPartyID(_selfPartyID), m_prePath(_prePath) + {} + ~JsonTaskFactory() override = default; + + Task::Ptr createTask(std::string_view _taskInfo) override + { + return std::make_shared(m_selfPartyID, _taskInfo, m_prePath); + } + + virtual Task::Ptr createTask(Json::Value const& _taskInfo) + { + return std::make_shared(m_selfPartyID, _taskInfo, m_prePath); + } + + Task::Ptr createTask() override + { + return std::make_shared(m_selfPartyID, m_prePath); + } + +private: + std::string m_selfPartyID; + std::string m_prePath; +}; +} // namespace ppc::protocol \ No newline at end of file diff --git a/cpp/wedpr-protocol/protocol/src/PPCMessage.cpp b/cpp/wedpr-protocol/protocol/src/PPCMessage.cpp new file mode 100644 index 00000000..efb7861f --- /dev/null +++ b/cpp/wedpr-protocol/protocol/src/PPCMessage.cpp @@ -0,0 +1,199 @@ +/** + * Copyright (C) 2022 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 PPCMessage.cpp + * @author: shawnhe + * @date 2022-10-19 + */ +#include "PPCMessage.h" +#include "Common.h" +#include +#include + +using namespace bcos; +using namespace ppc::front; +using namespace ppc::protocol; + +void PPCMessage::encode(bytes& _buffer) +{ + _buffer.clear(); + + uint32_t dataLength = boost::asio::detail::socket_ops::host_to_network_long(m_data->size()); + + _buffer.insert(_buffer.end(), (byte*)&m_version, (byte*)&m_version + 1); + _buffer.insert(_buffer.end(), (byte*)&m_taskType, (byte*)&m_taskType + 1); + _buffer.insert(_buffer.end(), (byte*)&m_algorithmType, (byte*)&m_algorithmType + 1); + _buffer.insert(_buffer.end(), (byte*)&m_messageType, (byte*)&m_messageType + 1); + // encode the data: dataLen, dataData + _buffer.insert(_buffer.end(), (byte*)&dataLength, (byte*)&dataLength + 4); + if (dataLength > 0) + { + _buffer.insert(_buffer.end(), m_data->begin(), m_data->end()); + } + _buffer.insert(_buffer.end(), m_header.begin(), m_header.end()); + m_length = _buffer.size(); +} + +int64_t PPCMessage::decode(bcos::bytesPointer _buffer) +{ + return decode(_buffer->size(), _buffer->data()); +} + +int64_t PPCMessage::decode(bytesConstRef _buffer) +{ + return decode(_buffer.size(), (bcos::byte*)_buffer.data()); +} + +int64_t PPCMessage::decode(uint32_t _length, bcos::byte* _data) +{ + size_t minLen = MESSAGE_MIN_LENGTH; + if (_length < minLen) + { + return -1; + } + + m_data->clear(); + auto p = _data; + + // version field + m_version = *((uint8_t*)p); + p += 1; + + // task type field + m_taskType = *((uint8_t*)p); + p += 1; + + // algorithm type field + m_algorithmType = *((uint8_t*)p); + p += 1; + + // message type field + m_messageType = *((uint8_t*)p); + p += 1; + + // dataLength + uint32_t dataLength = boost::asio::detail::socket_ops::network_to_host_long(*((uint32_t*)p)); + p += 4; + minLen += dataLength; + if (_length < minLen) + { + return -1; + } + if (dataLength > 0) + { + // data field + m_data->insert(m_data->begin(), p, p + dataLength); + p += dataLength; + } + + if (p < _data + _length) + { + m_header.insert(m_header.begin(), p, _data + _length); + } + m_length = _length; + return _length; +} + +// map -> json(string) +std::string PPCMessage::encodeMap(const std::map& _map) +{ + Json::Value pObj; + for (std::map::const_iterator iter = _map.begin(); iter != _map.end(); + ++iter) + { + pObj[iter->first] = iter->second; + } + return Json::FastWriter().write(pObj); +} + +// json(string) -> map +std::map PPCMessage::decodeMap(const std::string& _encval) +{ + Json::Reader reader; + Json::Value value; + std::map maps; + + if (_encval.length() > 0) + { + if (reader.parse(_encval, value)) + { + Json::Value::Members members = value.getMemberNames(); + for (Json::Value::Members::iterator it = members.begin(); it != members.end(); it++) + { + maps.insert(std::pair(*it, value[*it].asString())); + } + } + } + + return maps; +} + +// Note: this interface is used after the MessagePayload(frontMessage) has been decoded; this +// interface passed some meta information to the ppcMessage +PPCMessageFace::Ptr PPCMessageFactory::decodePPCMessage(Message::Ptr msg) +{ + auto ppcMsg = buildPPCMessage(); + auto frontMsg = msg->frontMessage(); + // Note: this field is been setted when onReceiveMessage + if (frontMsg) + { + ppcMsg->decode(bcos::ref(frontMsg->data())); + ppcMsg->setSeq(frontMsg->seq()); + ppcMsg->setUuid(frontMsg->traceID()); + if (frontMsg->isRespPacket()) + { + ppcMsg->setResponse(); + } + } + if (msg->header() && msg->header()->optionalField()) + { + auto const& routeInfo = msg->header()->optionalField(); + ppcMsg->setTaskID(routeInfo->topic()); + ppcMsg->setSender(routeInfo->srcInst()); + ppcMsg->setSenderNode(routeInfo->srcNode()); + } + return ppcMsg; +} + +Message::Ptr PPCMessageFactory::buildMessage(MessageBuilder::Ptr const& msgBuilder, + MessagePayloadBuilder::Ptr const& msgPayloadBuilder, PPCMessageFace::Ptr const& ppcMessage) +{ + auto msg = msgBuilder->build(); + msg->header()->optionalField()->setTopic(ppcMessage->taskID()); + msg->header()->optionalField()->setSrcInst(ppcMessage->sender()); + + auto payload = buildMessage(msgPayloadBuilder, ppcMessage); + auto payloadData = std::make_shared(); + payload->encode(*payloadData); + msg->setPayload(std::move(payloadData)); + return msg; +} + +MessagePayload::Ptr PPCMessageFactory::buildMessage( + MessagePayloadBuilder::Ptr const& msgPayloadBuilder, PPCMessageFace::Ptr const& ppcMessage) +{ + auto payload = msgPayloadBuilder->build(); + payload->setSeq(ppcMessage->seq()); + if (ppcMessage->response()) + { + payload->setRespPacket(); + } + payload->setTraceID(ppcMessage->uuid()); + + bcos::bytes ppcMsgData; + ppcMessage->encode(ppcMsgData); + payload->setData(std::move(ppcMsgData)); + return payload; +} \ No newline at end of file diff --git a/cpp/wedpr-protocol/protocol/src/PPCMessage.h b/cpp/wedpr-protocol/protocol/src/PPCMessage.h new file mode 100644 index 00000000..c6cc6978 --- /dev/null +++ b/cpp/wedpr-protocol/protocol/src/PPCMessage.h @@ -0,0 +1,180 @@ +/** + * Copyright (C) 2022 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. + * + * @brief ppc network message interface + * @file PPCMessage.h + * @author: shawnhe + * @date 2022-10-19 + */ + +#pragma once + +#include +#include +#include +#include + +#include "ppc-framework/protocol/PPCMessageFace.h" + +namespace ppc +{ +namespace front +{ +// the message format for ppc protocol +class PPCMessage : public PPCMessageFace +{ +public: + // version(1) + taskType(1) + algorithmType(1) + messageType(1) + // + dataLen(4) + data(N) + // + header(M) + const static size_t MESSAGE_MIN_LENGTH = 8; + + using Ptr = std::shared_ptr; + PPCMessage() { m_data = std::make_shared(); } + // Note: the payload passed in by the upper layer cannot be released at will + ~PPCMessage() override = default; + + uint8_t version() const override { return m_version; } + void setVersion(uint8_t _version) override { m_version = _version; } + uint8_t taskType() const override { return m_taskType; } + void setTaskType(uint8_t _taskType) override { m_taskType = _taskType; } + uint8_t algorithmType() const override { return m_algorithmType; } + void setAlgorithmType(uint8_t _algorithmType) override { m_algorithmType = _algorithmType; } + uint8_t messageType() const override { return m_messageType; } + void setMessageType(uint8_t _messageType) override { m_messageType = _messageType; } + uint32_t seq() const override { return m_seq; } + void setSeq(uint32_t _seq) override { m_seq = _seq; } + std::string const& taskID() const override { return m_taskID; } + void setTaskID(std::string const& _taskID) override { m_taskID = _taskID; } + std::string const& sender() const override { return m_sender; } + void setSender(std::string const& _sender) override { m_sender = _sender; } + 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); } + void setHeader(std::map _header) override + { + m_header = encodeMap(_header); + } + + std::string uuid() const override { return m_uuid; } + void setUuid(std::string const& _uuid) override { m_uuid = _uuid; } + + void encode(bcos::bytes& _buffer) override; + int64_t decode(bcos::bytesPointer _buffer) override; + int64_t decode(bcos::bytesConstRef _buffer) override; + int64_t decode(uint32_t _length, bcos::byte* _data); + + uint32_t length() const override { return m_length; } + + // determine the message is response or not + bool response() const override { return m_isResponse; } + // set the message to be response + void setResponse() override { m_isResponse = true; } + + void setSenderNode(bcos::bytes const& senderNode) override { m_senderNode = senderNode; } + + bcos::bytes const& senderNode() const override { return m_senderNode; } + + void releasePayload() override + { + if (!m_data) + { + return; + } + m_data->clear(); + bcos::bytes().swap(*m_data); + } + +protected: + std::string encodeMap(const std::map& _map); + std::map decodeMap(const std::string& _encval); + +private: + uint8_t m_version = 0; + uint8_t m_taskType = 0; + uint8_t m_algorithmType = 0; + uint8_t m_messageType = 0; + uint32_t m_seq = 0; + std::string m_taskID; + std::string m_sender; + bcos::bytes m_senderNode; + + bool m_isResponse; + // the uuid used to find the response-callback + std::string m_uuid; + std::shared_ptr m_data; + std::string m_header; + + uint32_t m_length = MESSAGE_MIN_LENGTH; +}; + +class PPCMessageFactory : public PPCMessageFaceFactory +{ +public: + using Ptr = std::shared_ptr; + PPCMessageFactory() = default; + virtual ~PPCMessageFactory() {} + +public: + PPCMessageFace::Ptr buildPPCMessage() override { return std::make_shared(); } + + PPCMessageFace::Ptr buildPPCMessage(uint8_t _taskType, uint8_t _algorithmType, + std::string const& _taskID, std::shared_ptr _data) override + { + auto msg = std::make_shared(); + msg->setTaskType(_taskType); + msg->setAlgorithmType(_algorithmType); + msg->setTaskID(_taskID); + msg->setData(std::move(_data)); + return msg; + } + + + PPCMessageFace::Ptr buildPPCMessage(bcos::bytesConstRef _buffer) override + { + auto msg = std::make_shared(); + int64_t length = msg->decode(_buffer); + if (length == -1) + { + return nullptr; + } + return msg; + } + + PPCMessageFace::Ptr buildPPCMessage(bcos::bytesPointer _buffer) override + { + auto msg = std::make_shared(); + int64_t length = msg->decode(std::move(_buffer)); + if (length == -1) + { + return nullptr; + } + return msg; + } + + PPCMessageFace::Ptr decodePPCMessage(ppc::protocol::Message::Ptr msg) override; + + ppc::protocol::Message::Ptr buildMessage(ppc::protocol::MessageBuilder::Ptr const& msgBuilder, + ppc::protocol::MessagePayloadBuilder::Ptr const& msgPayloadBuilder, + PPCMessageFace::Ptr const& ppcMessage) override; + + ppc::protocol::MessagePayload::Ptr buildMessage( + ppc::protocol::MessagePayloadBuilder::Ptr const& msgPayloadBuilder, + PPCMessageFace::Ptr const& ppcMessage) override; +}; + +} // namespace front +} // namespace ppc diff --git a/cpp/wedpr-protocol/protocol/src/ServiceConfig.cpp b/cpp/wedpr-protocol/protocol/src/ServiceConfig.cpp new file mode 100644 index 00000000..bf5367cb --- /dev/null +++ b/cpp/wedpr-protocol/protocol/src/ServiceConfig.cpp @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2022 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 ServiceConfig.cpp + * @author: yujiechen + * @date 2022-11-4 + */ +#include "ServiceConfig.h" +#include "ppc-framework/Common.h" + +using namespace ppc::protocol; + + +void EntryPointInfo::encode(Json::Value& json) const +{ + json["serviceName"] = m_serviceName; + json["entryPoint"] = m_entryPoint; +} + +void EntryPointInfo::decode(Json::Value const& jsonObject) +{ + if (jsonObject.isMember("serviceName")) + { + m_serviceName = jsonObject["serviceName"].asString(); + } + if (jsonObject.isMember("entryPoint")) + { + m_entryPoint = jsonObject["entryPoint"].asString(); + } +} + + +void ServiceConfig::addEntryPoint(EntryPointInfo entryPoint) +{ + m_serviceInfos.emplace_back(std::move(entryPoint)); +} + +// encode the serviceConfig +std::string ServiceConfig::encode() const +{ + Json::Value result; + Json::Value serviceInfos(Json::arrayValue); + for (auto const& it : m_serviceInfos) + { + Json::Value entryPointInfo; + it.encode(entryPointInfo); + serviceInfos.append(entryPointInfo); + } + result["serviceInfos"] = serviceInfos; + Json::FastWriter fastWriter; + return fastWriter.write(result); +} + +// decode the serviceConfig +void ServiceConfig::decode(std::string const& data) +{ + Json::Value root; + Json::Reader jsonReader; + if (!jsonReader.parse(std::string(data), root)) + { + BOOST_THROW_EXCEPTION(WeDPRException() << bcos::errinfo_comment( + "The task information must be valid json string.")); + } + if (!root.isMember("serviceInfos")) + { + return; + } + for (const auto& serviceInfo : root["serviceInfos"]) + { + m_serviceInfos.emplace_back(EntryPointInfo(serviceInfo)); + } +} \ No newline at end of file diff --git a/cpp/wedpr-protocol/protocol/src/ServiceConfig.h b/cpp/wedpr-protocol/protocol/src/ServiceConfig.h new file mode 100644 index 00000000..ae6d84b3 --- /dev/null +++ b/cpp/wedpr-protocol/protocol/src/ServiceConfig.h @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2022 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 ServiceConfig.h + * @author: yujiechen + * @date 2022-11-4 + */ +#pragma once +#include +#include +#include +#include + +namespace ppc::protocol +{ +class EntryPointInfo +{ +public: + EntryPointInfo(std::string const& serviceName, std::string const& entryPoint) + : m_serviceName(serviceName), m_entryPoint(entryPoint) + {} + + EntryPointInfo(Json::Value const& jsonObject) { decode(jsonObject); } + + virtual ~EntryPointInfo() = default; + + virtual void encode(Json::Value& json) const; + + virtual void decode(Json::Value const& jsonObject); + + std::string const& serviceName() const { return m_serviceName; } + std::string const& entryPoint() const { return m_entryPoint; } + +private: + std::string m_serviceName; + std::string m_entryPoint; +}; + +class ServiceConfig +{ +public: + using Ptr = std::shared_ptr; + ServiceConfig() = default; + ServiceConfig(std::string const& data) { decode(data); } + virtual ~ServiceConfig() = default; + + void addEntryPoint(EntryPointInfo entryPoint); + + // encode the serviceConfig + virtual std::string encode() const; + + // decode the serviceConfig + virtual void decode(std::string const& data); + std::vector const& serviceInfos() const { return m_serviceInfos; } + +private: + std::vector m_serviceInfos; +}; + +class ServiceConfigBuilder +{ +public: + using Ptr = std::shared_ptr; + ServiceConfigBuilder() = default; + virtual ~ServiceConfigBuilder() = default; + + EntryPointInfo buildEntryPoint(std::string const& serviceName, std::string const& entryPoint) + { + return EntryPointInfo(serviceName, entryPoint); + } + + ServiceConfig buildServiceConfig() const { return ServiceConfig(); } + ServiceConfig populateServiceConfig(std::string const& data) { return ServiceConfig(data); } +}; +} // namespace ppc::protocol \ No newline at end of file diff --git a/cpp/wedpr-protocol/protocol/src/v1/MessageHeaderImpl.cpp b/cpp/wedpr-protocol/protocol/src/v1/MessageHeaderImpl.cpp new file mode 100644 index 00000000..00d0c78d --- /dev/null +++ b/cpp/wedpr-protocol/protocol/src/v1/MessageHeaderImpl.cpp @@ -0,0 +1,209 @@ +/** + * 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 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); + buffer.insert(buffer.end(), m_srcNode.begin(), m_srcNode.end()); + // the source agency + uint16_t srcInstLen = boost::asio::detail::socket_ops::host_to_network_short(m_srcInst.size()); + buffer.insert(buffer.end(), (byte*)&srcInstLen, (byte*)&srcInstLen + 2); + buffer.insert(buffer.end(), m_srcInst.begin(), m_srcInst.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()); + // 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()); + // the 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()); +} + + +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)); + bcos::bytes componentType; + offset = decodeNetworkBuffer( + componentType, data.data(), data.size(), (pointer - data.data()), false); + m_componentType = std::string(componentType.begin(), componentType.end()); + // srcNode + offset = decodeNetworkBuffer(m_srcNode, data.data(), data.size(), offset, false); + // source inst + offset = decodeNetworkBuffer(m_srcInst, data.data(), data.size(), offset, false); + // dstNode + offset = decodeNetworkBuffer(m_dstNode, data.data(), data.size(), offset, false); + // dstInst + offset = decodeNetworkBuffer(m_dstInst, data.data(), data.size(), offset, false); + // topic + offset = decodeNetworkBuffer(m_topic, data.data(), data.size(), offset, false); + 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); + if (m_traceID.size() > 0) + { + 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); + if (m_srcGwNode.size() > 0) + { + 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); + if (m_dstGwNode.size() > 0) + { + buffer.insert(buffer.end(), m_dstGwNode.begin(), m_dstGwNode.end()); + } + if (!hasOptionalField()) + { + m_length = buffer.size(); + 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 + auto offset = + decodeNetworkBuffer(m_traceID, data.data(), data.size(), (pointer - data.data()), false); + // srcGwNode + offset = decodeNetworkBuffer(m_srcGwNode, data.data(), data.size(), offset, false); + // dstGwNode + offset = decodeNetworkBuffer(m_dstGwNode, data.data(), data.size(), offset, false); + // optionalField + if (hasOptionalField()) + { + offset = m_optionalField->decode(data, offset); + } + m_length = offset; + return offset; +} + +uint16_t MessageHeaderImpl::routeType() const +{ + if (m_ext & (uint16_t)ppc::gateway::GatewayMsgExtFlag::RouteByNodeID) + { + return (uint16_t)RouteType::ROUTE_THROUGH_NODEID; + } + 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::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/wedpr-protocol/protocol/src/v1/MessageHeaderImpl.h b/cpp/wedpr-protocol/protocol/src/v1/MessageHeaderImpl.h new file mode 100644 index 00000000..0212c20b --- /dev/null +++ b/cpp/wedpr-protocol/protocol/src/v1/MessageHeaderImpl.h @@ -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 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(MessageOptionalHeader::Ptr const& optionalHeader) + { + if (!optionalHeader) + { + return; + } + setTopic(optionalHeader->topic()); + setComponentType(optionalHeader->componentType()); + setSrcNode(optionalHeader->srcNode()); + setDstNode(optionalHeader->dstNode()); + setDstInst(optionalHeader->dstInst()); + } + 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) + { + m_optionalField = std::make_shared(); + decode(data); + } + ~MessageHeaderImpl() override {} + + void encode(bcos::bytes& buffer) const override; + int64_t decode(bcos::bytesConstRef data) override; + + bool hasOptionalField() const override + { + 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; } + + 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; +}; + +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(); } + MessageOptionalHeader::Ptr build(MessageOptionalHeader::Ptr const& optionalHeader) override + { + return std::make_shared(optionalHeader); + } +}; +class MessageOptionalHeaderBuilderImpl : public MessageOptionalHeaderBuilder +{ +public: + using Ptr = std::shared_ptr; + MessageOptionalHeaderBuilderImpl() = default; + ~MessageOptionalHeaderBuilderImpl() override = default; + + MessageOptionalHeader::Ptr build(MessageOptionalHeader::Ptr const& optionalHeader) override + { + return std::make_shared(optionalHeader); + } + + MessageOptionalHeader::Ptr build() override + { + return std::make_shared(); + } +}; +} // namespace ppc::protocol \ No newline at end of file diff --git a/cpp/wedpr-protocol/protocol/src/v1/MessageImpl.cpp b/cpp/wedpr-protocol/protocol/src/v1/MessageImpl.cpp new file mode 100644 index 00000000..637209e4 --- /dev/null +++ b/cpp/wedpr-protocol/protocol/src/v1/MessageImpl.cpp @@ -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 MessageImpl.cpp + * @author: yujiechen + * @date 2024-08-23 + */ + +#include "MessageImpl.h" +#include "../Common.h" + +using namespace bcos; +using namespace ppc::protocol; + +bool MessageImpl::encode(bcos::bytes& _buffer) +{ + // encode the header + m_header->encode(_buffer); + // encode the payload + if (m_payload && m_payload->size() > 0) + { + _buffer.insert(_buffer.end(), m_payload->begin(), m_payload->end()); + } + return true; +} + +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); + // no payload case + if (buffer.size() <= m_header->length()) + { + return buffer.size(); + } + // 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()); + return buffer.size(); +} \ No newline at end of file diff --git a/cpp/wedpr-protocol/protocol/src/v1/MessageImpl.h b/cpp/wedpr-protocol/protocol/src/v1/MessageImpl.h new file mode 100644 index 00000000..c16c040a --- /dev/null +++ b/cpp/wedpr-protocol/protocol/src/v1/MessageImpl.h @@ -0,0 +1,102 @@ +/** + * 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" +#include +#include +#include + +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) + { + m_header = m_headerBuilder->build(); + } + MessageImpl( + MessageHeaderBuilder::Ptr headerBuilder, size_t maxMessageLen, bcos::bytesConstRef buffer) + : MessageImpl(headerBuilder, maxMessageLen) + { + decode(buffer); + } + + ~MessageImpl() override = default; + + bool encode(bcos::bytes& _buffer) override; + int64_t decode(bcos::bytesConstRef _buffer) override; + +protected: + 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); + } + + virtual MessageOptionalHeader::Ptr build(MessageOptionalHeader::Ptr const& optionalHeader) + { + return m_msgHeaderBuilder->build(optionalHeader); + } + + Message::Ptr build(ppc::protocol::RouteType routeType, + ppc::protocol::MessageOptionalHeader::Ptr const& routeInfo, bcos::bytes&& payload) override + { + auto msg = build(); + msg->header()->setRouteType(routeType); + msg->header()->setOptionalField(routeInfo); + msg->setPayload(std::make_shared(std::move(payload))); + return msg; + } + +protected: + MessageHeaderBuilder::Ptr m_msgHeaderBuilder; + // default max message length is 100MB + size_t m_maxMessageLen = 100 * 1024 * 1024; +}; +} // namespace ppc::protocol diff --git a/cpp/wedpr-protocol/protocol/src/v1/MessagePayloadImpl.cpp b/cpp/wedpr-protocol/protocol/src/v1/MessagePayloadImpl.cpp new file mode 100644 index 00000000..67653c3c --- /dev/null +++ b/cpp/wedpr-protocol/protocol/src/v1/MessagePayloadImpl.cpp @@ -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 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); + // seq + uint16_t seq = boost::asio::detail::socket_ops::host_to_network_short(m_seq); + buffer.insert(buffer.end(), (byte*)&seq, (byte*)&seq + 2); + // ext field + uint16_t ext = boost::asio::detail::socket_ops::host_to_network_short(m_ext); + buffer.insert(buffer.end(), (byte*)&ext, (byte*)&ext + 2); + // traceID + 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()); + // data + uint32_t dataLen = boost::asio::detail::socket_ops::host_to_network_long(m_dataPtr.size()); + buffer.insert(buffer.end(), (byte*)&dataLen, (byte*)&dataLen + 4); + buffer.insert(buffer.end(), m_dataPtr.begin(), m_dataPtr.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!")); + } + m_length = buffer.size(); + auto pointer = buffer.data(); + // the version + m_version = boost::asio::detail::socket_ops::network_to_host_short(*((uint16_t*)pointer)); + pointer += 2; + // 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; + // the ext + CHECK_OFFSET_WITH_THROW_EXCEPTION((pointer - buffer.data()), buffer.size()); + m_ext = boost::asio::detail::socket_ops::network_to_host_short(*((uint16_t*)pointer)); + pointer += 2; + // the traceID + auto offset = + decodeNetworkBuffer(m_traceID, buffer.data(), buffer.size(), (pointer - buffer.data())); + // data + auto ret = decodeNetworkBuffer(m_data, buffer.data(), buffer.size(), offset, true); + // reset the dataPtr + m_dataPtr = bcos::bytesConstRef((bcos::byte*)m_data.data(), m_data.size()); + return ret; +} \ No newline at end of file diff --git a/cpp/wedpr-protocol/protocol/src/v1/MessagePayloadImpl.h b/cpp/wedpr-protocol/protocol/src/v1/MessagePayloadImpl.h new file mode 100644 index 00000000..c85c0589 --- /dev/null +++ b/cpp/wedpr-protocol/protocol/src/v1/MessagePayloadImpl.h @@ -0,0 +1,55 @@ +/** + * 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: + // version + seq + dataLen + 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/wedpr-protocol/protocol/tests/CMakeLists.txt b/cpp/wedpr-protocol/protocol/tests/CMakeLists.txt new file mode 100644 index 00000000..3248c2ec --- /dev/null +++ b/cpp/wedpr-protocol/protocol/tests/CMakeLists.txt @@ -0,0 +1,10 @@ +file(GLOB_RECURSE SOURCES "*.cpp" "*.h") + +# cmake settings +set(TEST_BINARY_NAME test-protocol) + +add_executable(${TEST_BINARY_NAME} ${SOURCES}) +target_include_directories(${TEST_BINARY_NAME} PRIVATE .) + +target_link_libraries(${TEST_BINARY_NAME} ${PROTOCOL_TARGET} ${BCOS_UTILITIES_TARGET} TBB::tbb ${BOOST_UNIT_TEST}) +add_test(NAME test-protocol WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} COMMAND ${TEST_BINARY_NAME}) \ No newline at end of file diff --git a/cpp/wedpr-protocol/protocol/tests/MessageTest.cpp b/cpp/wedpr-protocol/protocol/tests/MessageTest.cpp new file mode 100644 index 00000000..ea262f9d --- /dev/null +++ b/cpp/wedpr-protocol/protocol/tests/MessageTest.cpp @@ -0,0 +1,159 @@ +/* + * Copyright (C) 2022 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 MessageTest.cpp + * @author: shawnhe + * @date 2022-10-28 + */ + +#include "protocol/src/v1/MessageHeaderImpl.h" +#include "protocol/src/v1/MessageImpl.h" +#include +#include + +using namespace ppc; +using namespace ppc::protocol; +using namespace bcos::test; + +BOOST_FIXTURE_TEST_SUITE(MessageTest, TestPromptFixture) + +void checkMsg(Message::Ptr msg, Message::Ptr decodedMsg) +{ + if (msg->header()) + { + BOOST_CHECK(msg->header()->version() == decodedMsg->header()->version()); + BOOST_CHECK(msg->header()->traceID() == decodedMsg->header()->traceID()); + BOOST_CHECK(msg->header()->srcGwNode() == decodedMsg->header()->srcGwNode()); + BOOST_CHECK(msg->header()->dstGwNode() == decodedMsg->header()->dstGwNode()); + BOOST_CHECK(msg->header()->packetType() == decodedMsg->header()->packetType()); + BOOST_CHECK(msg->header()->ttl() == decodedMsg->header()->ttl()); + BOOST_CHECK(msg->header()->ext() == decodedMsg->header()->ext()); + } + auto routeInfo = msg->header()->optionalField(); + auto decodedRouteInfo = decodedMsg->header()->optionalField(); + if (routeInfo) + { + BOOST_CHECK(routeInfo->topic() == decodedRouteInfo->topic()); + BOOST_CHECK(routeInfo->componentType() == decodedRouteInfo->componentType()); + BOOST_CHECK(routeInfo->srcNode() == decodedRouteInfo->srcNode()); + BOOST_CHECK(routeInfo->srcInst() == decodedRouteInfo->srcInst()); + BOOST_CHECK(routeInfo->dstNode() == decodedRouteInfo->dstNode()); + BOOST_CHECK(routeInfo->dstInst() == decodedRouteInfo->dstInst()); + } + if (msg->payload()) + { + BOOST_CHECK(*(msg->payload()) == *(decodedMsg->payload())); + } +} + +Message::Ptr fakeMsg(MessageBuilder::Ptr msgBuilder, int version, std::string const& traceID, + std::string const& srcGwNode, std::string const& dstGwNode, int packetType, int ttl, int ext, + std::string topic, std::string const& componentType, bcos::bytes const& srcNode, + std::string const& srcInst, bcos::bytes const& dstNode, std::string const& dstInst, + std::shared_ptr payload) +{ + auto msg = msgBuilder->build(); + msg->header()->setVersion(version); + msg->header()->setTraceID(traceID); + msg->header()->setSrcGwNode(srcGwNode); + msg->header()->setDstGwNode(dstGwNode); + msg->header()->setPacketType(packetType); + msg->header()->setTTL(ttl); + msg->header()->setExt(ext); + msg->header()->optionalField()->setTopic(topic); + msg->header()->optionalField()->setComponentType(componentType); + msg->header()->optionalField()->setSrcNode(srcNode); + msg->header()->optionalField()->setSrcInst(srcInst); + msg->header()->optionalField()->setDstNode(dstNode); + msg->header()->optionalField()->setDstInst(dstInst); + msg->setPayload(payload); + return msg; +} + +void checkEncodeDecode(MessageBuilder::Ptr msgBuilder, Message::Ptr const& msg) +{ + // encode + bcos::bytes encodedData; + msg->encode(encodedData); + + // decode + auto decodedMsg = msgBuilder->build(bcos::ref(encodedData)); + checkMsg(msg, decodedMsg); +} + +BOOST_AUTO_TEST_CASE(testMessage) +{ + auto msgBuilder = + std::make_shared(std::make_shared()); + int version = 1000; + int packetType = 2344; + int ttl = 123; + int ext = 1000; + std::string traceID = ""; + std::string srcGwNode = ""; + std::string dstGwNode = ""; + std::string topic = ""; + std::string componentType = ""; + bcos::bytes srcNode; + bcos::bytes dstNode; + std::string srcInst; + std::string dstInst; + std::shared_ptr payload = nullptr; + + auto msg = fakeMsg(msgBuilder, version, traceID, srcGwNode, dstGwNode, packetType, ttl, ext, + topic, componentType, srcNode, srcInst, dstNode, dstInst, payload); + checkEncodeDecode(msgBuilder, msg); + // with payload + std::string payloadData = "payloadf@#$@#$sdfs234"; + payload = std::make_shared(payloadData.begin(), payloadData.end()); + msg = fakeMsg(msgBuilder, version, traceID, srcGwNode, dstGwNode, packetType, ttl, ext, topic, + componentType, srcNode, srcInst, dstNode, dstInst, payload); + checkEncodeDecode(msgBuilder, msg); + + // with payload over 65535 + for (uint32_t i = 0; i < 10000000; i++) + { + payload->emplace_back(i); + } + msg = fakeMsg(msgBuilder, version, traceID, srcGwNode, dstGwNode, packetType, ttl, ext, topic, + componentType, srcNode, srcInst, dstNode, dstInst, payload); + checkEncodeDecode(msgBuilder, msg); + + + // with header router + traceID = "1233"; + srcGwNode = "srcGwNode"; + dstGwNode = "dstGwNode"; + msg = fakeMsg(msgBuilder, version, traceID, srcGwNode, dstGwNode, packetType, ttl, ext, topic, + componentType, srcNode, srcInst, dstNode, dstInst, payload); + checkEncodeDecode(msgBuilder, msg); + + // with optional field + std::string srcNodeData = "sdwerwer"; + srcNode = bcos::bytes(srcNodeData.begin(), srcNodeData.end()); + std::string dstNodeData = "dstswerwer"; + dstNode = bcos::bytes(dstNodeData.begin(), dstNodeData.end()); + dstInst = "dstInst"; + srcInst = "srcInst"; + componentType = "compp,ad"; + topic = "topcisdf"; + + msg = fakeMsg(msgBuilder, version, traceID, srcGwNode, dstGwNode, packetType, ttl, ext, topic, + componentType, srcNode, srcInst, dstNode, dstInst, payload); + msg->setPacketType((uint16_t)ppc::gateway::GatewayPacketType::P2PMessage); + checkEncodeDecode(msgBuilder, msg); +} + +BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file diff --git a/cpp/wedpr-protocol/protocol/tests/PPCMessageTest.cpp b/cpp/wedpr-protocol/protocol/tests/PPCMessageTest.cpp new file mode 100644 index 00000000..f478eae2 --- /dev/null +++ b/cpp/wedpr-protocol/protocol/tests/PPCMessageTest.cpp @@ -0,0 +1,162 @@ +/* + * Copyright (C) 2022 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 PPCMessageTest.cpp + * @author: shawnhe + * @date 2022-10-28 + */ + +#include "protocol/src/PPCMessage.h" +#include "ppc-framework/protocol/Protocol.h" +#include "protocol/src/v1/MessageHeaderImpl.h" +#include "protocol/src/v1/MessageImpl.h" +#include "protocol/src/v1/MessagePayloadImpl.h" +#include +#include +#include +#include + +using namespace ppc; +using namespace ppc::front; +using namespace bcos::test; +using namespace ppc::protocol; + +BOOST_FIXTURE_TEST_SUITE(PPCMessageTest, TestPromptFixture) + +void checkPPCMessage(PPCMessageFace::Ptr _message, PPCMessageFace::Ptr newMsg) +{ + BOOST_CHECK(newMsg->version() == _message->version()); + BOOST_CHECK(newMsg->taskType() == _message->taskType()); + BOOST_CHECK(newMsg->algorithmType() == _message->algorithmType()); + BOOST_CHECK(newMsg->messageType() == _message->messageType()); + BOOST_CHECK(newMsg->seq() == _message->seq()); + BOOST_CHECK(newMsg->taskID() == _message->taskID()); + BOOST_CHECK(newMsg->sender() == _message->sender()); + BOOST_CHECK(newMsg->uuid() == _message->uuid()); + BOOST_CHECK(newMsg->data()->size() == _message->data()->size()); + auto newMsgHeader = newMsg->header(); + auto messageHeader = _message->header(); + BOOST_CHECK(newMsgHeader.size() == messageHeader.size()); + BOOST_CHECK(newMsgHeader["x-http-session"] == "111111"); + BOOST_CHECK(messageHeader["x-http-session"] == "111111"); + BOOST_CHECK(newMsgHeader["x-http-request"] == "2222222"); + BOOST_CHECK(messageHeader["x-http-request"] == "2222222"); +} + +void checkPayloadMsg(MessagePayload::Ptr payloadMsg, MessagePayload::Ptr decodedPayload) +{ + BOOST_CHECK(payloadMsg->version() == decodedPayload->version()); + BOOST_CHECK(payloadMsg->seq() == decodedPayload->seq()); + BOOST_CHECK(payloadMsg->traceID() == decodedPayload->traceID()); + BOOST_CHECK(payloadMsg->data() == decodedPayload->data()); + BOOST_CHECK(payloadMsg->ext() == decodedPayload->ext()); +} + +void checkMsg(Message::Ptr msg, Message::Ptr decodedMsg) +{ + if (msg->header()) + { + BOOST_CHECK(msg->header()->version() == decodedMsg->header()->version()); + BOOST_CHECK(msg->header()->traceID() == decodedMsg->header()->traceID()); + BOOST_CHECK(msg->header()->srcGwNode() == decodedMsg->header()->srcGwNode()); + BOOST_CHECK(msg->header()->dstGwNode() == decodedMsg->header()->dstGwNode()); + BOOST_CHECK(msg->header()->packetType() == decodedMsg->header()->packetType()); + BOOST_CHECK(msg->header()->ttl() == decodedMsg->header()->ttl()); + BOOST_CHECK(msg->header()->ext() == decodedMsg->header()->ext()); + } + auto routeInfo = msg->header()->optionalField(); + auto decodedRouteInfo = decodedMsg->header()->optionalField(); + if (routeInfo) + { + BOOST_CHECK(routeInfo->topic() == decodedRouteInfo->topic()); + BOOST_CHECK(routeInfo->componentType() == decodedRouteInfo->componentType()); + BOOST_CHECK(routeInfo->srcNode() == decodedRouteInfo->srcNode()); + BOOST_CHECK(routeInfo->srcInst() == decodedRouteInfo->srcInst()); + BOOST_CHECK(routeInfo->dstNode() == decodedRouteInfo->dstNode()); + BOOST_CHECK(routeInfo->dstInst() == decodedRouteInfo->dstInst()); + } +} + +PPCMessageFace::Ptr fakePPCMessage(PPCMessageFactory::Ptr messageFactory, int version, int taskType, + int algorithmType, int messageType, std::string const& taskID, int seq, std::string const& uuid, + std::string const& srcInst, std::shared_ptr data, + std::map const& header) +{ + auto message = messageFactory->buildPPCMessage(); + message->setVersion(version); + message->setTaskType(taskType); + message->setAlgorithmType(algorithmType); + message->setMessageType(messageType); + message->setTaskID(taskID); + message->setSeq(seq); + message->setUuid(uuid); + message->setSender(srcInst); + message->setData(data); + message->setHeader(header); + return message; +} + + +BOOST_AUTO_TEST_CASE(test_ppcMesage) +{ + int version = 1; + int taskType = uint8_t(protocol::TaskType::PSI); + int algorithmType = uint8_t(protocol::TaskAlgorithmType::CM_PSI_2PC); + int messageType = 4; + std::string taskID = "12345678"; + int seq = 5; + std::string uuid = "uuid1245"; + std::string srcInst = "from"; + std::string dstInst = "dst"; + auto data = std::make_shared(10, 'a'); + std::map head = { + {"x-http-session", "111111"}, {"x-http-request", "2222222"}}; + + auto messageFactory = std::make_shared(); + auto ppcMessage = fakePPCMessage(messageFactory, version, taskType, algorithmType, messageType, + taskID, seq, uuid, srcInst, data, head); + + auto payloadBuilder = std::make_shared(); + auto msgBuilder = + std::make_shared(std::make_shared()); + + auto msg = messageFactory->buildMessage(msgBuilder, payloadBuilder, ppcMessage); + auto payloadMsg = messageFactory->buildMessage(payloadBuilder, ppcMessage); + bcos::bytes payloadData; + payloadMsg->encode(payloadData); + + auto decodedPayload = payloadBuilder->build(bcos::ref(payloadData)); + checkPayloadMsg(payloadMsg, decodedPayload); + + auto decodedPayload2 = payloadBuilder->build(bcos::ref(*(msg->payload()))); + checkPayloadMsg(payloadMsg, decodedPayload); + + bcos::bytes msgData; + msg->encode(msgData); + + auto decodedMsg = msgBuilder->build(bcos::ref(msgData)); + checkMsg(msg, decodedMsg); + + decodedMsg->setFrontMessage(decodedPayload2); + auto decodedPPCMsg = messageFactory->decodePPCMessage(decodedMsg); + checkPPCMessage(ppcMessage, decodedPPCMsg); + + // invalid case + std::string invalidStr = "sdfsinvalidsfwre"; + bcos::bytes invalidData(invalidStr.begin(), invalidStr.end()); + BOOST_CHECK_THROW(msgBuilder->build(bcos::ref(invalidData)), std::exception); +} + +BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file diff --git a/cpp/wedpr-protocol/protocol/tests/TestTaskImpl.cpp b/cpp/wedpr-protocol/protocol/tests/TestTaskImpl.cpp new file mode 100644 index 00000000..dbe5c8ce --- /dev/null +++ b/cpp/wedpr-protocol/protocol/tests/TestTaskImpl.cpp @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2022 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 applicabl 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 TestTaskImpl.cpp + * @author: yujiechen + * @date 2022-10-19 + */ + +#include "protocol/src/JsonTaskImpl.h" +#include "test-utils/TaskMock.h" +#include +#include +#include + +using namespace ppc; +using namespace ppc::protocol; +using namespace bcos::test; + +namespace ppc::test +{ +BOOST_FIXTURE_TEST_SUITE(taskImplTest, TestPromptFixture) + +inline void testTask(TaskFactory::Ptr _taskFactory, std::string _selfPartyID, int _peerPartySize) +{ + auto task = _taskFactory->createTask(); + task->setId("testTask"); + task->setType((uint8_t)ppc::protocol::TaskType::PSI); + task->setParam("taskParam"); + task->setSyncResultToPeer(true); + + // mock self-party + auto party = mockParty((uint16_t)ppc::protocol::PartyType::Server, _selfPartyID, "selfParty", + "dataSelf", ppc::protocol::DataResourceType::FILE, "testPath"); + + std::vector> rawData(2); + for (uint32_t i = 0; i < 10; i++) + { + rawData[0].emplace_back(std::to_string(i)); + rawData[1].emplace_back(std::to_string(i)); + } + party->mutableDataResource()->setRawData(rawData); + + task->setSelf(party); + // mock peers-party + for (int i = 0; i < _peerPartySize; i++) + { + std::string partyID = "party" + std::to_string(i); + party = mockParty((uint16_t)ppc::protocol::PartyType::Server, partyID, partyID, "dataParty", + ppc::protocol::DataResourceType::FILE, "testPath"); + task->addParty(party); + } + // encode + auto encodeData = task->encode(); + // decode + auto decodedTask = _taskFactory->createTask(encodeData); + // check the result + checkTask(decodedTask, task); + + // invalid case + task->setSelf(nullptr); + encodeData = task->encode(); + // decode exception for without selfParty + BOOST_CHECK_THROW(_taskFactory->createTask(encodeData), bcos::InvalidParameter); +} + +BOOST_AUTO_TEST_CASE(testJsonTaskImpl) +{ + std::string selfPartyID = "selfParty"; + auto factory = std::make_shared(selfPartyID); + testTask(factory, selfPartyID, 10); +} +BOOST_AUTO_TEST_SUITE_END() +} // namespace ppc::test diff --git a/cpp/wedpr-protocol/protocol/tests/main.cpp b/cpp/wedpr-protocol/protocol/tests/main.cpp new file mode 100644 index 00000000..2c06f9b5 --- /dev/null +++ b/cpp/wedpr-protocol/protocol/tests/main.cpp @@ -0,0 +1,2 @@ +#define BOOST_TEST_MAIN +#include \ No newline at end of file diff --git a/cpp/wedpr-protocol/tars/CMakeLists.txt b/cpp/wedpr-protocol/tars/CMakeLists.txt new file mode 100644 index 00000000..ebee8479 --- /dev/null +++ b/cpp/wedpr-protocol/tars/CMakeLists.txt @@ -0,0 +1,36 @@ +# for tars generator +set(TARS_HEADER_DIR ${CMAKE_BINARY_DIR}/generated/tars) +find_program(TARS_TARS2CPP tars2cpp REQUIRED) + +set(PROTO_INPUT_PATH ${CMAKE_SOURCE_DIR}/wedpr-protocol/proto/tars) +file(GLOB_RECURSE TARS_INPUT "${PROTO_INPUT_PATH}/*.tars") + +# generate tars +if (TARS_INPUT) + foreach (TARS_FILE ${TARS_INPUT}) + get_filename_component(TARS_NAME ${TARS_FILE} NAME_WE) + get_filename_component(TARS_PATH ${TARS_FILE} PATH) + add_custom_command( + OUTPUT ${TARS_HEADER_DIR}/${TARS_NAME}.h + WORKING_DIRECTORY ${TARS_PATH} + COMMAND ${TARS_TARS2CPP} ${TARS_FILE} --unjson --without-trace --dir=${TARS_HEADER_DIR} + COMMENT "generating ${TARS_FILE} to ${TARS_HEADER_DIR}" + VERBATIM + ) + + list(APPEND OUT_TARS_H_LIST ${TARS_HEADER_DIR}/${TARS_NAME}.h) + endforeach () +endif () + +set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${OUT_TARS_H_LIST}") + +file(GLOB_RECURSE SRC_LIST *.cpp) + +find_package(tarscpp REQUIRED) +add_library(${TARS_PROTOCOL_TARGET} ${SRC_LIST} ${OUT_TARS_H_LIST}) +target_include_directories(${TARS_PROTOCOL_TARGET} PUBLIC + $ + $ + $ + $) +target_link_libraries(${TARS_PROTOCOL_TARGET} PUBLIC ${BCOS_UTILITIES_TARGET} tarscpp::tarsutil) diff --git a/cpp/wedpr-protocol/tars/Common.h b/cpp/wedpr-protocol/tars/Common.h new file mode 100644 index 00000000..90f62d33 --- /dev/null +++ b/cpp/wedpr-protocol/tars/Common.h @@ -0,0 +1,301 @@ +/** + * Copyright (C) 2022 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 Common.h + * @author: shawnhe + * @date 2022-10-20 + */ + +#pragma once + +#include "TarsServantProxyCallback.h" +#include "ppc-framework/protocol/Task.h" +#include "ppc-tools/src/config/ParamChecker.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace ppctars +{ +namespace serialize +{ +template +class BufferWriter +{ +protected: + using ByteType = typename Container::value_type; + using SizeType = typename Container::size_type; + + mutable Container _buffer; + ByteType* _buf; + SizeType _len; + SizeType _buf_len; + std::function _reserve; + +private: + BufferWriter(const BufferWriter&); + BufferWriter& operator=(const BufferWriter& buf); + +public: + BufferWriter() : _buf(NULL), _len(0), _buf_len(0), _reserve({}) + { +#ifndef GEN_PYTHON_MASK + _reserve = [](BufferWriter& os, size_t len) { + os._buffer.resize(len); + return os._buffer.data(); + }; +#endif + } + + ~BufferWriter() {} + + void reset() { _len = 0; } + + void writeBuf(const ByteType* buf, size_t len) + { + TarsReserveBuf(*this, _len + len); + memcpy(_buf + _len, buf, len); + _len += len; + } + + const Container& getByteBuffer() const + { + _buffer.resize(_len); + return _buffer; + } + Container& getByteBuffer() + { + _buffer.resize(_len); + return _buffer; + } + const ByteType* getBuffer() const { return _buf; } + size_t getLength() const { return _len; } + void swap(std::vector& v) + { + _buffer.resize(_len); + v.swap(_buffer); + _buf = NULL; + _buf_len = 0; + _len = 0; + } + void swap(BufferWriter& buf) + { + buf._buffer.swap(_buffer); + std::swap(_buf, buf._buf); + std::swap(_buf_len, buf._buf_len); + std::swap(_len, buf._len); + } +}; + +using BufferWriterByteVector = BufferWriter>; +using BufferWriterStdByteVector = BufferWriter>; +using BufferWriterString = BufferWriter; +} // namespace serialize + +inline std::string getProxyDesc(std::string const& _servantName) +{ + std::string desc = + tars::ServerConfig::Application + "." + tars::ServerConfig::ServerName + "." + _servantName; + return desc; +} + +inline std::string getLogPath() +{ + return tars::ServerConfig::LogPath + "/" + tars::ServerConfig::Application + "/" + + tars::ServerConfig::ServerName; +} + +inline tars::TC_Endpoint string2TarsEndPoint(const std::string& _strEndPoint) +{ + std::vector temp; + boost::split(temp, _strEndPoint, boost::is_any_of(":"), boost::token_compress_on); + + if (temp.size() != 2) + { + BOOST_THROW_EXCEPTION(bcos::InvalidParameter() << bcos::errinfo_comment( + "incorrect string endpoint, it should be in IP:Port format")); + } + + tars::TC_Endpoint ep(temp[0], boost::lexical_cast(temp[1]), 60000); + return ep; +} + +inline std::vector toTarsEndPoints(std::vector const& _endPoints) +{ + std::vector tarsEndPoints; + for (auto const& it : _endPoints) + { + tarsEndPoints.emplace_back(string2TarsEndPoint(it)); + } + return tarsEndPoints; +} + +inline std::string endPointToString(std::string const& _serviceName, const std::string& _endpoint) +{ + std::vector url; + boost::split(url, _endpoint, boost::is_any_of(":"), boost::token_compress_on); + return _serviceName + "@tcp -h " + url[0] + " -p " + url[1]; +} + +inline std::string endPointToString( + std::string const& _serviceName, const std::string& _host, uint16_t _port) +{ + return _serviceName + "@tcp -h " + _host + " -p " + boost::lexical_cast(_port); +} + +inline std::string endPointToString( + std::string const& _serviceName, tars::TC_Endpoint const& _endPoint) +{ + return endPointToString(_serviceName, _endPoint.getHost(), _endPoint.getPort()); +} + +inline std::string endPointToString( + std::string const& _serviceName, const std::vector& _eps) +{ + if (_eps.empty()) + { + BOOST_THROW_EXCEPTION( + bcos::InvalidParameter() << bcos::errinfo_comment( + "vector should not be empty in endPointToString")); + } + + bool first = true; + std::string endPointStr = _serviceName; + for (const auto& _ep : _eps) + { + endPointStr += (first ? "@" : ":"); + endPointStr += + ("tcp -h " + _ep.getHost() + " -p " + boost::lexical_cast(_ep.getPort())); + + first = false; + } + return endPointStr; +} + +inline std::pair getEndPointDescByAdapter(tars::Application* _application, + std::string const& _servantName, std::string const& _endpoint = "") +{ + auto adapters = _application->getEpollServer()->getBindAdapters(); + if (adapters.size() == 0) + { + return std::make_pair(false, ""); + } + auto prxDesc = getProxyDesc(_servantName); + if (!_endpoint.empty()) + { + if (!ppc::tools::checkEndpoint(_endpoint)) + { + BOOST_THROW_EXCEPTION(bcos::InvalidParameter() << bcos::errinfo_comment( + "incorrect string endpoint, it should be in IP:Port format")); + } + return std::make_pair(true, endPointToString(prxDesc, _endpoint)); + } + + auto adapterName = prxDesc + "Adapter"; + for (auto const& adapter : adapters) + { + if (adapter->getName() == adapterName) + { + return std::make_pair(true, endPointToString(prxDesc, adapter->getEndpoint())); + } + } + return std::make_pair(false, ""); +} + +template +S createServantProxy(tars::Communicator* communicator, std::string const& _endPointStr, + TarsServantProxyOnConnectHandler _connectHandler = TarsServantProxyOnConnectHandler(), + TarsServantProxyOnCloseHandler _closeHandler = TarsServantProxyOnCloseHandler()) +{ + auto prx = communicator->stringToProxy(_endPointStr); + + BCOS_LOG(DEBUG) << LOG_DESC("createServantProxy ") << _endPointStr; + + if (!prx->tars_get_push_callback()) + { + auto proxyCallback = new ppctars::TarsServantProxyCallback(_endPointStr, *prx); + + if (_connectHandler) + { + proxyCallback->setOnConnectHandler(_connectHandler); + } + + if (_closeHandler) + { + proxyCallback->setOnCloseHandler(_closeHandler); + } + + prx->tars_set_push_callback(proxyCallback); + proxyCallback->startTimer(); + } + return prx; +} + +template +S createServantProxy(std::string const& _endPointStr) +{ + return createServantProxy(tars::Application::getCommunicator().get(), _endPointStr, + TarsServantProxyOnConnectHandler(), TarsServantProxyOnCloseHandler()); +} + +template +S createServantProxy(std::string const& _serviceName, const std::string& _host, uint16_t _port) +{ + auto endPointStr = endPointToString(_serviceName, _host, _port); + return createServantProxy(endPointStr); +} + +template +S createServantProxy(std::string const& _serviceName, const tars::TC_Endpoint& _ep) +{ + auto endPointStr = endPointToString(_serviceName, _ep); + return createServantProxy(endPointStr); +} + +template +S createServantProxy(std::string const& _serviceName, const std::vector& _eps) +{ + std::string endPointStr = endPointToString(_serviceName, _eps); + + return createServantProxy(endPointStr); +} + +template +S createServantProxy(bool _withEndPoints, std::string const& _serviceName, + const std::vector& _eps = std::vector{}) +{ + std::string serviceParams; + if (_withEndPoints) + { + serviceParams = endPointToString(_serviceName, _eps); + } + else + { + serviceParams = _serviceName; + } + + return createServantProxy(serviceParams); +} +} // namespace ppctars \ No newline at end of file diff --git a/cpp/wedpr-protocol/tars/TarsSerialize.h b/cpp/wedpr-protocol/tars/TarsSerialize.h new file mode 100644 index 00000000..51bb4591 --- /dev/null +++ b/cpp/wedpr-protocol/tars/TarsSerialize.h @@ -0,0 +1,42 @@ +/** + * Copyright (C) 2022 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 TarsSerializable.h + * @author: shawnhe + * @date 2022-11-4 + */ + +#pragma once + +#include "Common.h" +#include "TarsStruct.h" + +namespace ppctars::serialize +{ +void encode(TarsStruct auto const& object, bcos::bytes& out) +{ + tars::TarsOutputStream output; + object.writeTo(output); + output.getByteBuffer().swap(out); +} + +void decode(const bcos::bytes& in, TarsStruct auto& out) +{ + tars::TarsInputStream input; + input.setBuffer((const char*)in.data(), in.size()); + out.readFrom(input); +} + +} // namespace ppctars::serialize diff --git a/cpp/wedpr-protocol/tars/TarsServantProxyCallback.h b/cpp/wedpr-protocol/tars/TarsServantProxyCallback.h new file mode 100644 index 00000000..16521ee4 --- /dev/null +++ b/cpp/wedpr-protocol/tars/TarsServantProxyCallback.h @@ -0,0 +1,242 @@ +/** + * Copyright (C) 2022 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. + * + * @brief tars implementation for tars ServantProxyCallback + * @file TarsServantProxyCallback.h + * @author: shawnhe + * @date 2022-10-20 + */ + +#pragma once + +#include "bcos-utilities/BoostLog.h" +#include "bcos-utilities/Error.h" +#include "bcos-utilities/Timer.h" +#include "servant/ServantProxy.h" +#include +#include +#include +#include +#include +#include +#include + +#define TARS_PING_PERIOD (3000) + +namespace ppctars +{ +struct TC_EndpointCompare +{ + bool operator()(const tars::TC_Endpoint& lhs, const tars::TC_Endpoint& rhs) const + { + return lhs.toString() < rhs.toString(); + } +}; + +using EndpointSet = std::set; + +using TarsServantProxyOnConnectHandler = std::function; +using TarsServantProxyOnCloseHandler = std::function; + +class TarsServantProxyCallback : public tars::ServantProxyCallback + +{ +public: + using Ptr = std::shared_ptr; + using ConstPtr = std::shared_ptr; + using UniquePtr = std::unique_ptr; + +public: + TarsServantProxyCallback(const std::string& _serviceName, tars::ServantProxy& _servantProxy) + : m_serviceName(_serviceName), m_servantProxy(_servantProxy) + { + m_timer = std::make_shared(TARS_PING_PERIOD, "tars_ping"); + + BCOS_LOG(INFO) << LOG_BADGE("[NEWOBJ][TarsServantProxyCallback]") + << LOG_KV("_serviceName", _serviceName) << LOG_KV("this", this); + } + + TarsServantProxyCallback(TarsServantProxyCallback&&) = delete; + TarsServantProxyCallback(const TarsServantProxyCallback&) = delete; + const TarsServantProxyCallback& operator=(const TarsServantProxyCallback&) = delete; + TarsServantProxyCallback& operator=(TarsServantProxyCallback&&) = delete; + + ~TarsServantProxyCallback() override + { + if (m_timer) + { + m_timer->stop(); + } + } + +public: + int onDispatch(tars::ReqMessagePtr) override { return 0; } + + void onClose(const tars::TC_Endpoint& ep) override + { + try + { + auto p = addInactiveEndpoint(ep); + BCOS_LOG(INFO) << LOG_DESC("ServantProxyCallback::onClose:") << m_serviceName + << LOG_KV("endpoint", ep.toString()) + << LOG_KV("inActiveEndPointSize", p.second); + if (p.first && m_onCloseHandler) + { + m_onCloseHandler(ep); + } + } + catch (const std::exception& e) + { + std::cout << "[TarsServantProxyCallback::onClose] " + << "exception: " << boost::diagnostic_information(e) << std::endl; + } + } + + void onConnect(const tars::TC_Endpoint& ep) override + { + auto p = addActiveEndpoint(ep); + BCOS_LOG(INFO) << LOG_BADGE("ServantProxyCallback::onConnect") << LOG_KV("this", this) + << LOG_KV("serviceName", m_serviceName) << LOG_KV("endpoint", ep.toString()) + << LOG_KV("result", p.first) << LOG_KV("activeEndpoints size", p.second); + + if (p.first && m_onConnectHandler) + { + m_onConnectHandler(ep); + } + } + +public: + void startTimer() + { + if (!m_timer) + { + return; + } + + m_timer->registerTimeoutHandler([this]() { + ping(); + restart(); + }); + + m_timer->start(); + } + + const std::string& serviceName() const { return m_serviceName; } + + auto activeEndpoints() + { + std::shared_lock l(x_endpoints); + return m_activeEndpoints; + } + + EndpointSet inactiveEndpoints() + { + std::shared_lock l(x_endpoints); + return m_inactiveEndpoints; + } + + std::pair addActiveEndpoint(const tars::TC_Endpoint& ep) + { + std::unique_lock l(x_endpoints); + auto result = m_activeEndpoints.insert(ep); + m_inactiveEndpoints.erase(ep); + return std::make_pair(result.second, m_activeEndpoints.size()); + } + + std::pair addInactiveEndpoint(const tars::TC_Endpoint& ep) + { + { + std::shared_lock l(x_endpoints); + if (m_inactiveEndpoints.find(ep) != m_inactiveEndpoints.end()) + { + return std::make_pair(false, m_inactiveEndpoints.size()); + } + } + + { + std::unique_lock l(x_endpoints); + auto result = m_inactiveEndpoints.insert(ep); + m_activeEndpoints.erase(ep); + + BCOS_LOG(INFO) << LOG_BADGE("ServantProxyCallback::addInactiveEndpoint") + << LOG_KV("this", this) << LOG_KV("result", result.second) + << LOG_KV("endpoint", ep.toString()); + + return std::make_pair(result.second, m_inactiveEndpoints.size()); + } + } + + TarsServantProxyOnConnectHandler onConnectHandler() const { return m_onConnectHandler; } + TarsServantProxyOnCloseHandler onCloseHandler() const { return m_onCloseHandler; } + + void setOnConnectHandler(TarsServantProxyOnConnectHandler _handler) + { + m_onConnectHandler = _handler; + } + + void setOnCloseHandler(TarsServantProxyOnCloseHandler _handler) { m_onCloseHandler = _handler; } + + bool available() { return !activeEndpoints().empty(); } + + void ping() + { + try + { + m_servantProxy.tars_async_ping(); + } + catch (const std::exception& _e) + { + BCOS_LOG(ERROR) << LOG_BADGE("ServantProxyCallback::tars_async_ping") + << LOG_KV("serviceName", m_serviceName) + << LOG_KV("e", boost::diagnostic_information(_e)); + } + } + + void restart() + { + if (m_timer) + { + m_timer->restart(); + } + } + +private: + std::string m_serviceName; + + // tars ServantProxy which the TarsServantProxyCallback belongs to + tars::ServantProxy& m_servantProxy; + + // timer for ping + std::shared_ptr m_timer; + + // lock for m_activeEndpoints and m_inactiveEndpoints + mutable std::shared_mutex x_endpoints; + // all active tars endpoints + EndpointSet m_activeEndpoints; + // all inactive tars endpoints + EndpointSet m_inactiveEndpoints; + + std::function m_onConnectHandler; + std::function m_onCloseHandler; +}; + +template +auto tarsProxyActiveEndPoints(const T& prx) +{ + auto cb = prx->tars_get_push_callback(); + assert(cb); + return ((TarsServantProxyCallback*)cb.get())->activeEndpoints(); +} +} // namespace ppctars \ No newline at end of file diff --git a/cpp/wedpr-protocol/tars/TarsStruct.cpp b/cpp/wedpr-protocol/tars/TarsStruct.cpp new file mode 100644 index 00000000..064378c9 --- /dev/null +++ b/cpp/wedpr-protocol/tars/TarsStruct.cpp @@ -0,0 +1,21 @@ +/** + * Copyright (C) 2022 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 TarsStruct.cpp + * @author: shawnhe + * @date 2022-11-4 + */ + +#include "TarsStruct.h" \ No newline at end of file diff --git a/cpp/wedpr-protocol/tars/TarsStruct.h b/cpp/wedpr-protocol/tars/TarsStruct.h new file mode 100644 index 00000000..4818237d --- /dev/null +++ b/cpp/wedpr-protocol/tars/TarsStruct.h @@ -0,0 +1,29 @@ +/** + * Copyright (C) 2022 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 TarsStruct.h + * @author: shawnhe + * @date 2022-11-4 + */ + +#pragma once +#include +#include + +namespace ppctars::serialize +{ +template +concept TarsStruct = std::derived_from; +} // namespace ppctars::serialize diff --git a/cpp/wedpr-storage/ppc-io/CMakeLists.txt b/cpp/wedpr-storage/ppc-io/CMakeLists.txt new file mode 100644 index 00000000..f4ffe9dd --- /dev/null +++ b/cpp/wedpr-storage/ppc-io/CMakeLists.txt @@ -0,0 +1,10 @@ +add_subdirectory(src) +if (DEMO) + add_subdirectory(demo) +endif() + +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-storage/ppc-io/demo/CMakeLists.txt b/cpp/wedpr-storage/ppc-io/demo/CMakeLists.txt new file mode 100644 index 00000000..0b3611d8 --- /dev/null +++ b/cpp/wedpr-storage/ppc-io/demo/CMakeLists.txt @@ -0,0 +1,11 @@ +file(GLOB_RECURSE SOURCES "*.cpp" "*.h") + +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) +# cmake settings +set(BINARY_NAME io-demo) + +add_executable(${BINARY_NAME} ${SOURCES}) +target_include_directories(${BINARY_NAME} PRIVATE .) + +target_link_libraries(${BINARY_NAME} ${IO_TARGET}) +unset(CMAKE_RUNTIME_OUTPUT_DIRECTORY) \ No newline at end of file diff --git a/cpp/wedpr-storage/ppc-io/demo/io_demo.cpp b/cpp/wedpr-storage/ppc-io/demo/io_demo.cpp new file mode 100644 index 00000000..4a1b1e42 --- /dev/null +++ b/cpp/wedpr-storage/ppc-io/demo/io_demo.cpp @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2022 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 io_demo.cpp + * @desc: demo for io + * @author: yujiechen + * @date 2022-10-19 + */ +#include "ppc-io/src/FileLineReader.h" +#include "ppc-io/src/FileLineWriter.h" +#include + +using namespace bcos; +using namespace ppc::io; + +int main(int argc, char* argv[]) +{ + if (argc < 2) + { + std::cout << "Usage: " << argv[0] + << ": \n - [fileToRead(required)]\n - mmapGranularity: default is 500MB \n - " + "readPerBatch(default read all)\n - writeLines: default is 1000w"; + return -1; + } + std::string fileToRead = argv[1]; + uint64_t mmapGranularity = 500 * 1024 * 1024; + if (argc == 3) + { + mmapGranularity = atol(argv[2]); + } + int16_t readPerBatch = -1; + if (argc == 4) + { + readPerBatch = atoi(argv[3]); + } + uint64_t dataToWrite = 10000000; + if (argc == 5) + { + dataToWrite = atoi(argv[4]); + } + std::cout << "fileToRead:\t" << fileToRead << std::endl; + std::cout << "mmapGranularity:\t" << mmapGranularity << std::endl; + if (readPerBatch == -1) + { + std::cout << "readPerBatch:\t readAll" << std::endl; + } + else + { + std::cout << "readPerBatch:\t" << readPerBatch << std::endl; + } + + std::cout << "----- parseFileBegin----------"; + auto factory = std::make_shared(); + auto lineReader = factory->createLineReader(fileToRead, mmapGranularity); + auto startT = utcSteadyTime(); + uint64_t lineSize = 0; + while (true) + { + auto dataBatch = lineReader->next(readPerBatch); + if (!dataBatch) + { + break; + } + lineSize += dataBatch->size(); + } + std::cout << "timecost:\t" << (utcSteadyTime() - startT) << "ms " << std::endl; + std::cout << "fileSize:\t" << lineReader->capacity() << std::endl; + std::cout << "lines:\t\t" << lineSize << std::endl; + std::cout << "----- parseFileFinished----------"; + std::cout << "------ test writer --------------)"; + uint64_t batchSize = 10; + uint64_t dataGranularity = dataToWrite / batchSize; + std::vector dataVec; + for (uint64_t j = 0; j < dataGranularity; j++) + { + std::string data = "234k9lwekrwejrlewkrjwe"; + dataVec.emplace_back(bcos::bytes(data.begin(), data.end())); + } + for (uint64_t i = 0; i < 10; i++) + { + auto writer = std::make_shared("output.txt", false); + auto dataBatch = std::make_shared(); + auto tmpData = dataVec; + dataBatch->setData(std::move(tmpData)); + writer->writeLine(dataBatch, DataSchema::Bytes, "\n"); + writer->flush(); + writer->close(); + } +} diff --git a/cpp/wedpr-storage/ppc-io/src/BaseFileLineReader.cpp b/cpp/wedpr-storage/ppc-io/src/BaseFileLineReader.cpp new file mode 100644 index 00000000..a16a5875 --- /dev/null +++ b/cpp/wedpr-storage/ppc-io/src/BaseFileLineReader.cpp @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2022 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 BaseFileLineReader.cpp + * @author: yujiechen + * @date 2022-10-19 + */ + +#include "BaseFileLineReader.h" +#include "Common.h" +#include +#include +#include +#include +#include +#include +using namespace ppc::io; +using namespace bcos; +// get the next _size line data +DataBatch::Ptr BaseFileLineReader::next(int64_t _size, DataSchema schema) +{ + // the file has already been read-finished + if (readFinished()) + { + return nullptr; + } + switch (schema) + { + case DataSchema::String: + { + if (-1 == _size) + { + return readAllData(DataSchema::String); + } + else if (_size <= 0) + { + BOOST_THROW_EXCEPTION(InvalidParam() << bcos::errinfo_comment( + "The read-size parameter must be -1 or positive")); + } + else + { + return readLineData(_size, DataSchema::String); + } + } + case DataSchema::Bytes: + { + if (-1 == _size) + { + return readAllData(DataSchema::Bytes); + } + else if (_size <= 0) + { + BOOST_THROW_EXCEPTION(InvalidParam() << bcos::errinfo_comment( + "The read-size parameter must be -1 or positive")); + } + else + { + return readLineData(_size, DataSchema::Bytes); + } + } + default: + { + BOOST_THROW_EXCEPTION( + UnsupportedDataSchema() << errinfo_comment("unsupported data schema")); + } + } +} + +// read all bytes from the file, without parse +bcos::bytes BaseFileLineReader::readBytes() +{ + bcos::bytes result; + while (allocateCurrentBlock()) + { + m_currentBlockParser->readAll(result); + m_offset = result.size(); + } + IO_LOG(INFO) << LOG_DESC("readBytes") << LOG_KV("result", result.size()) + << LOG_KV("length", m_length); + return result; +} \ No newline at end of file diff --git a/cpp/wedpr-storage/ppc-io/src/BaseFileLineReader.h b/cpp/wedpr-storage/ppc-io/src/BaseFileLineReader.h new file mode 100644 index 00000000..45a54854 --- /dev/null +++ b/cpp/wedpr-storage/ppc-io/src/BaseFileLineReader.h @@ -0,0 +1,130 @@ +/* + * Copyright (C) 2022 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 BaseFileLineReader.h + * @author: yujiechen + * @date 2022-10-19 + */ +#pragma once +#include "parser/MmapParser.h" +#include "ppc-framework/io/LineReader.h" +#include + +namespace ppc::io +{ +class BaseFileLineReader : public LineReader +{ +public: + BaseFileLineReader(char _lineSpliter) : m_lineSplitter(_lineSpliter) {} + ~BaseFileLineReader() override {} + + /** + * @brief get the next _offset line data + * + * @param _size: the data-size to be read + * read all rows at once when the _size is -1 + * @return DataBatch::Ptr: the container that contains the readed-data + */ + DataBatch::Ptr next(int64_t _size = -1, DataSchema schema = DataSchema::String) override; + + // the capacity of the file or memory-bytes + uint64_t capacity() const override { return m_length; } + + uint64_t columnSize() const override { return 1; } + bcos::bytes readBytes() override; + +protected: + virtual bool allocateCurrentBlock() = 0; + + + template + int64_t readLineFromBlock(DataBatch::Ptr _dataBatch, int64_t _size) + { + int64_t readedLineNum = 0; + int64_t readedBytes = 0; + for (; readedLineNum < _size; readedLineNum++) + { + T dataItem; + auto readLineResult = + m_currentBlockParser->readLine(readedBytes, dataItem, m_lineSplitter); + // update the offset + m_offset += readedBytes; + if (m_appendToLine) + { + m_appendToLine = false; + _dataBatch->appendToLine(std::move(dataItem)); + } + else + { + _dataBatch->append(std::move(dataItem)); + } + if (ReadLineResult::ReadFinishWithoutSpliter == readLineResult) + { + m_appendToLine = true; + } + // reset the current mmap-file since it has been read-finished + if (ReadLineResult::ReadFinish == readLineResult || + ReadLineResult::ReadFinishWithoutSpliter == readLineResult) + { + m_currentBlockParser.reset(); + break; + } + } + IO_LOG(INFO) << LOG_DESC("readLineFromBlock") << LOG_KV("readedLineNum", readedLineNum) + << LOG_KV("expectedSize", _size) << LOG_KV("offset", m_offset); + return readedLineNum; + } + + template + DataBatch::Ptr readLineData(int64_t _size, DataSchema _schema) + { + auto dataBatch = std::make_shared(); + dataBatch->setDataSchema(_schema); + int64_t expectedSize = _size; + while (expectedSize > 0 && (allocateCurrentBlock())) + { + auto readLineNum = readLineFromBlock(dataBatch, expectedSize); + expectedSize = expectedSize - readLineNum; + } + IO_LOG(INFO) << LOG_DESC("readLineData") << LOG_KV("size", _size) + << LOG_KV("readedSize", dataBatch->size()); + return dataBatch; + } + + template + DataBatch::Ptr readAllData(DataSchema _dataSchema) + { + auto dataBatch = std::make_shared(); + dataBatch->setDataSchema(_dataSchema); + while (allocateCurrentBlock()) + { + readLineFromBlock(dataBatch, m_readGranularity); + } + IO_LOG(INFO) << LOG_DESC("readAllData") << LOG_KV("size", dataBatch->size()); + return dataBatch; + } + +protected: + char m_lineSplitter; + uint64_t m_length; + BaseBufferParser::Ptr m_currentBlockParser; // the current block-parser + + mutable uint64_t m_offset = 0; // the current read pointer + bool m_appendToLine = false; + + // Note: the m_readGranularity should be set by the override class + uint64_t m_readGranularity; +}; +} // namespace ppc::io \ No newline at end of file diff --git a/cpp/wedpr-storage/ppc-io/src/CMakeLists.txt b/cpp/wedpr-storage/ppc-io/src/CMakeLists.txt new file mode 100644 index 00000000..7f4be366 --- /dev/null +++ b/cpp/wedpr-storage/ppc-io/src/CMakeLists.txt @@ -0,0 +1,4 @@ +file(GLOB_RECURSE SRCS *.cpp) +add_library(${IO_TARGET} ${SRCS}) +# Note: the DataBatch depends on tbb +target_link_libraries(${IO_TARGET} PUBLIC ${BCOS_UTILITIES_TARGET} ${HDFS_LIB} ${CPU_FEATURES_LIB}) \ No newline at end of file diff --git a/cpp/wedpr-storage/ppc-io/src/Common.h b/cpp/wedpr-storage/ppc-io/src/Common.h new file mode 100644 index 00000000..f771627a --- /dev/null +++ b/cpp/wedpr-storage/ppc-io/src/Common.h @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2022 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 Common.h + * @author: yujiechen + * @date 2022-10-20 + */ +#pragma once + +#include "ppc-framework/Common.h" +#include "ppc-framework/storage/FileStorage.h" +#include +#include + +#define IO_LOG(LEVEL) BCOS_LOG(LEVEL) << LOG_BADGE("IO") + +namespace ppc::io +{ +DERIVE_PPC_EXCEPTION(ConnectionOptionNotFound); +DERIVE_PPC_EXCEPTION(InvalidMmapGranularity); +DERIVE_PPC_EXCEPTION(MmapFileException); +DERIVE_PPC_EXCEPTION(InvalidParam); +DERIVE_PPC_EXCEPTION(OpenFileLineWriterException); +DERIVE_PPC_EXCEPTION(CloseFileLineWriterException); +DERIVE_PPC_EXCEPTION(UnSupportedDataResource); +DERIVE_PPC_EXCEPTION(LoadDataResourceException); + +DERIVE_PPC_EXCEPTION(HDFSOpenMetaInfoFailed); +DERIVE_PPC_EXCEPTION(HDFSReadDataFailed); +DERIVE_PPC_EXCEPTION(HDFSWriteDataFailed); +DERIVE_PPC_EXCEPTION(HDFSFlushFailed); + +struct HdfsFileWrapper +{ + HdfsFileWrapper(ppc::storage::FileHandler::Ptr _handler, HdfsFileInternalWrapper* _fs) + : handler(std::move(_handler)), fs(_fs) + {} + ppc::storage::FileHandler::Ptr handler; + HdfsFileInternalWrapper* fs; +}; + +struct HDFSFileDeleter +{ + void operator()(HdfsFileWrapper* _wrapper) const + { + if (!_wrapper->fs) + { + return; + } + hdfsCloseFile((hdfsFS)_wrapper->handler->storageHandler(), _wrapper->fs); + } + ppc::storage::FileHandler::Ptr handler; +}; +} // namespace ppc::io \ No newline at end of file diff --git a/cpp/wedpr-storage/ppc-io/src/DataResourceLoaderImpl.cpp b/cpp/wedpr-storage/ppc-io/src/DataResourceLoaderImpl.cpp new file mode 100644 index 00000000..6d951bf4 --- /dev/null +++ b/cpp/wedpr-storage/ppc-io/src/DataResourceLoaderImpl.cpp @@ -0,0 +1,377 @@ +/* + * Copyright (C) 2022 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 DataResourceLoaderImpl.cpp + * @author: yujiechen + * @date 2022-11-4 + */ +#include "DataResourceLoaderImpl.h" +#include "Common.h" +#include "FileLineReader.h" +#include "FileLineWriter.h" +#include "HDFSReader.h" +#include "HDFSWriter.h" +#include "SQLResultReader.h" +#include +#include + +using namespace ppc::io; +using namespace ppc::storage; +using namespace ppc::protocol; +using namespace bcos; + + +DataResourceLoaderImpl::DataResourceLoaderImpl( + ppc::protocol::SQLConnectionOption::Ptr const& _sqlConnectionOpt, + ppc::protocol::FileStorageConnectionOption::Ptr const& _fileStorageConnectionOpt, + ppc::protocol::RemoteStorageConnectionOption::Ptr const& _remoteStorageConnectionOpt, + ppc::storage::SQLStorageFactory::Ptr const& _sqlStorageFactory, + ppc::storage::FileStorageFactory::Ptr const& _fileStorageFactory, + ppc::storage::RemoteStorageFactory::Ptr const& _remoteStorageFactory) + : m_sqlConnectionOpt(_sqlConnectionOpt), + m_fileStorageConnectionOpt(_fileStorageConnectionOpt), + m_remoteStorageConnectionOpt(_remoteStorageConnectionOpt), + m_sqlStorageFactory(_sqlStorageFactory), + m_fileStorageFactory(_fileStorageFactory), + m_remoteStorageFactory(_remoteStorageFactory) +{} + +void DataResourceLoaderImpl::lazyLoadHdfsStorage() +{ + if (!m_fileStorageConnectionOpt) + { + return; + } + bcos::Guard l(x_hdfsStorage); + if (m_hdfsStorage) + { + return; + } + m_hdfsStorage = + m_fileStorageFactory->createFileStorage(DataResourceType::HDFS, m_fileStorageConnectionOpt); + IO_LOG(INFO) << LOG_DESC("lazyLoadHdfsStorage") << m_fileStorageConnectionOpt->desc(); + return; +} + +void DataResourceLoaderImpl::lazyLoadSqlStorage() +{ + if (!m_sqlConnectionOpt) + { + return; + } + bcos::Guard l(x_sqlStorage); + if (m_sqlStorage) + { + return; + } + m_sqlStorage = + m_sqlStorageFactory->createSQLStorage(DataResourceType::MySQL, m_sqlConnectionOpt); + IO_LOG(INFO) << LOG_DESC("lazyLoadSqlStorage") << m_sqlConnectionOpt->desc(); +} + +LineReader::Ptr DataResourceLoaderImpl::loadReader(DataResourceDesc::ConstPtr _desc, + DataSchema _schema, bool _parseByColumn, FileStorage::Ptr const& _fileStorage) +{ + if (!_desc) + { + BOOST_THROW_EXCEPTION(LoadDataResourceException() + << bcos::errinfo_comment("must define the desc for data-resource")); + } + switch (_desc->type()) + { + // load lineReader from file + case (int)(DataResourceType::FILE): + { + return std::make_shared(_desc->path()); + } + // load reader from the sql + case (int)(DataResourceType::MySQL): + { + return loadSQLResource(_desc, _schema, _parseByColumn); + } + case (int)(DataResourceType::HDFS): + { + return loadHDFSResource(_desc, _fileStorage); + } + default: + { + BOOST_THROW_EXCEPTION( + UnSupportedDataResource() << errinfo_comment("Only support File/MySQL/HDFS now")); + } + } +} + +LineReader::Ptr DataResourceLoaderImpl::loadSQLResource( + DataResourceDesc::ConstPtr _desc, DataSchema, bool _parseByColumn) +{ + IO_LOG(INFO) << LOG_DESC("loadSQLResource") << LOG_KV("command", _desc->accessCommand()); + SQLStorage::Ptr storage; + if (_desc->sqlConnectionOption()) + { + storage = m_sqlStorageFactory->createSQLStorage( + (ppc::protocol::DataResourceType)_desc->type(), _desc->sqlConnectionOption()); + } + else if (m_sqlConnectionOpt) + { + lazyLoadSqlStorage(); + storage = m_sqlStorage; + } + else + { + BOOST_THROW_EXCEPTION( + ConnectionOptionNotFound() << errinfo_comment("mysql connection option not found")); + } + + // exec command + auto result = storage->execQuery( + _parseByColumn, _desc->accessCommand().c_str(), FieldDataType::TERMINATE); + return std::make_shared(std::move(result), _parseByColumn); +} + +LineReader::Ptr DataResourceLoaderImpl::loadHDFSResource( + ppc::protocol::DataResourceDesc::ConstPtr _desc, FileStorage::Ptr const& _storage) +{ + IO_LOG(INFO) << LOG_DESC("loadHDFSResource") << LOG_KV("path", _desc->path()); + auto storage = _storage; + if (!storage) + { + if (_desc->fileStorageConnectionOption()) + { + storage = m_fileStorageFactory->createFileStorage( + (ppc::protocol::DataResourceType)_desc->type(), + _desc->fileStorageConnectionOption()); + } + else if (m_fileStorageConnectionOpt) + { + lazyLoadHdfsStorage(); + storage = m_hdfsStorage; + } + else + { + BOOST_THROW_EXCEPTION( + ConnectionOptionNotFound() << errinfo_comment("hdfs connection option not found")); + } + } + // load the HDFSReader, open the file + auto handler = storage->openFile(_desc->path()); + return std::make_shared(handler); +} + +void DataResourceLoaderImpl::deleteResource( + ppc::protocol::DataResourceDesc::ConstPtr _desc, ppc::storage::FileStorage::Ptr const& _storage) +{ + if (!_desc) + { + BOOST_THROW_EXCEPTION(LoadDataResourceException() + << bcos::errinfo_comment("must define the desc for data-resource")); + } + switch (_desc->type()) + { + case (int)(DataResourceType::FILE): + case (int)(DataResourceType::HDFS): + { + auto storage = _storage; + if (!storage) + { + if (_desc->fileStorageConnectionOption()) + { + storage = m_fileStorageFactory->createFileStorage( + (ppc::protocol::DataResourceType)_desc->type(), + _desc->fileStorageConnectionOption()); + } + else if (m_fileStorageConnectionOpt) + { + lazyLoadHdfsStorage(); + storage = m_hdfsStorage; + } + else + { + BOOST_THROW_EXCEPTION(ConnectionOptionNotFound() + << errinfo_comment("hdfs connection option not found")); + } + } + + if (storage->fileExists(_desc->path())) + { + storage->deleteFile(_desc->path()); + } + break; + } + default: + { + BOOST_THROW_EXCEPTION( + UnSupportedDataResource() << errinfo_comment( + "deleteResource: Only support File/HDFS now, passed in resource type: " + + std::to_string(_desc->type()))); + } + } +} + +void DataResourceLoaderImpl::renameResource(ppc::protocol::DataResourceDesc::ConstPtr _desc, + std::string const& _new_path, ppc::storage::FileStorage::Ptr const& _storage) +{ + if (!_desc) + { + BOOST_THROW_EXCEPTION(LoadDataResourceException() + << bcos::errinfo_comment("must define the desc for data-resource")); + } + switch (_desc->type()) + { + case (int)(DataResourceType::FILE): + case (int)(DataResourceType::HDFS): + { + auto storage = _storage; + if (!storage) + { + if (_desc->fileStorageConnectionOption()) + { + storage = m_fileStorageFactory->createFileStorage( + (ppc::protocol::DataResourceType)_desc->type(), + _desc->fileStorageConnectionOption()); + } + else if (m_fileStorageConnectionOpt) + { + lazyLoadHdfsStorage(); + storage = m_hdfsStorage; + } + else + { + BOOST_THROW_EXCEPTION(ConnectionOptionNotFound() + << errinfo_comment("hdfs connection option not found")); + } + } + + if (storage->fileExists(_new_path)) + { + storage->deleteFile(_new_path); + } + storage->renameFile(_desc->path(), _new_path); + break; + } + default: + { + BOOST_THROW_EXCEPTION( + UnSupportedDataResource() << errinfo_comment( + "renameResource: Only support File/HDFS now, passed in resource type: " + + std::to_string(_desc->type()))); + } + } +} + +void DataResourceLoaderImpl::checkResourceExists( + ppc::protocol::DataResourceDesc::ConstPtr _desc, ppc::storage::FileStorage::Ptr const& _storage) +{ + if (!_desc) + { + BOOST_THROW_EXCEPTION(LoadDataResourceException() + << bcos::errinfo_comment("must define the desc for data-resource")); + } + switch (_desc->type()) + { + case (int)(DataResourceType::FILE): + { + if (boost::filesystem::exists(boost::filesystem::path(_desc->path()))) + { + BOOST_THROW_EXCEPTION(LoadDataResourceException() << bcos::errinfo_comment( + "The file: " + _desc->path() + " already exists!")); + } + break; + } + case (int)(DataResourceType::HDFS): + { + auto storage = _storage; + if (!storage) + { + if (_desc->fileStorageConnectionOption()) + { + storage = m_fileStorageFactory->createFileStorage( + (ppc::protocol::DataResourceType)_desc->type(), + _desc->fileStorageConnectionOption()); + } + else if (m_fileStorageConnectionOpt) + { + lazyLoadHdfsStorage(); + storage = m_hdfsStorage; + } + else + { + BOOST_THROW_EXCEPTION(ConnectionOptionNotFound() + << errinfo_comment("hdfs connection option not found")); + } + } + if (storage->fileExists(_desc->path())) + { + BOOST_THROW_EXCEPTION(LoadDataResourceException() << bcos::errinfo_comment( + "The hdfs file: " + _desc->path() + " already exists!")); + } + break; + } + default: + { + BOOST_THROW_EXCEPTION( + UnSupportedDataResource() << errinfo_comment( + "checkResourceExists: Only support File/HDFS now, passed in resource type: " + + std::to_string(_desc->type()))); + } + } +} + + +LineWriter::Ptr DataResourceLoaderImpl::loadWriter( + DataResourceDesc::ConstPtr _desc, bool _truncate, FileStorage::Ptr const& _storage) +{ + if (!_desc) + { + BOOST_THROW_EXCEPTION(LoadDataResourceException() + << bcos::errinfo_comment("must define the desc for data-resource")); + } + switch (_desc->type()) + { + case (int)(DataResourceType::FILE): + { + return std::make_shared(_desc->path(), _truncate); + } + case (int)(DataResourceType::HDFS): + { + auto storage = _storage; + if (!storage) + { + if (_desc->fileStorageConnectionOption()) + { + storage = m_fileStorageFactory->createFileStorage( + (ppc::protocol::DataResourceType)_desc->type(), + _desc->fileStorageConnectionOption()); + } + else if (m_fileStorageConnectionOpt) + { + lazyLoadHdfsStorage(); + storage = m_hdfsStorage; + } + else + { + BOOST_THROW_EXCEPTION(ConnectionOptionNotFound() + << errinfo_comment("hdfs connection option not found")); + } + } + auto handler = storage->openFile(_desc->path(), true); + return std::make_shared(handler, _truncate); + } + default: + { + BOOST_THROW_EXCEPTION( + UnSupportedDataResource() << errinfo_comment("Only support File/HDFS now")); + } + } +} \ No newline at end of file diff --git a/cpp/wedpr-storage/ppc-io/src/DataResourceLoaderImpl.h b/cpp/wedpr-storage/ppc-io/src/DataResourceLoaderImpl.h new file mode 100644 index 00000000..4287f758 --- /dev/null +++ b/cpp/wedpr-storage/ppc-io/src/DataResourceLoaderImpl.h @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2022 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 DataResourceLoaderImpl.h + * @author: yujiechen + * @date 2022-11-4 + */ +#pragma once +#include "ppc-framework/io/DataResourceLoader.h" +#include "ppc-framework/storage/FileStorage.h" +#include "ppc-framework/storage/RemoteStorage.h" +#include "ppc-framework/storage/SQLStorage.h" +#include + +namespace ppc::io +{ +class DataResourceLoaderImpl : public DataResourceLoader +{ +public: + using Ptr = std::shared_ptr; + DataResourceLoaderImpl(ppc::protocol::SQLConnectionOption::Ptr const& _sqlConnectionOpt, + ppc::protocol::FileStorageConnectionOption::Ptr const& _fileStorageConnectionOpt, + ppc::protocol::RemoteStorageConnectionOption::Ptr const& _remoteStorageConnectionOpt, + ppc::storage::SQLStorageFactory::Ptr const& _sqlStorageFactory, + ppc::storage::FileStorageFactory::Ptr const& _fileStorageFactory, + ppc::storage::RemoteStorageFactory::Ptr const& _remoteStorageFactory); + + DataResourceLoaderImpl() = default; + ~DataResourceLoaderImpl() override = default; + + LineReader::Ptr loadReader(ppc::protocol::DataResourceDesc::ConstPtr _desc, + ppc::io::DataSchema _schema = ppc::io::DataSchema::String, bool _parseByColumn = true, + ppc::storage::FileStorage::Ptr const& _storage = nullptr) override; + + LineWriter::Ptr loadWriter(ppc::protocol::DataResourceDesc::ConstPtr _desc, + bool _truncate = false, ppc::storage::FileStorage::Ptr const& _storage = nullptr) override; + + void checkResourceExists(ppc::protocol::DataResourceDesc::ConstPtr _desc, + ppc::storage::FileStorage::Ptr const& _storage = nullptr) override; + + void deleteResource(ppc::protocol::DataResourceDesc::ConstPtr _desc, + ppc::storage::FileStorage::Ptr const& _storage = nullptr) override; + + void renameResource(ppc::protocol::DataResourceDesc::ConstPtr _desc, + std::string const& _new_path, + ppc::storage::FileStorage::Ptr const& _storage = nullptr) override; + +protected: + virtual LineReader::Ptr loadSQLResource(ppc::protocol::DataResourceDesc::ConstPtr _desc, + ppc::io::DataSchema _schema, bool _parseByColumn); + + virtual LineReader::Ptr loadHDFSResource(ppc::protocol::DataResourceDesc::ConstPtr _desc, + ppc::storage::FileStorage::Ptr const& _fileStorage); + + void lazyLoadHdfsStorage(); + void lazyLoadSqlStorage(); + +private: + // the sql storage + ppc::protocol::SQLConnectionOption::Ptr m_sqlConnectionOpt; + ppc::storage::SQLStorage::Ptr m_sqlStorage; + bcos::Mutex x_sqlStorage; + + // the hdfs storage + ppc::protocol::FileStorageConnectionOption::Ptr m_fileStorageConnectionOpt; + ppc::storage::FileStorage::Ptr m_hdfsStorage; + bcos::Mutex x_hdfsStorage; + + ppc::protocol::RemoteStorageConnectionOption::Ptr m_remoteStorageConnectionOpt; + + ppc::storage::SQLStorageFactory::Ptr m_sqlStorageFactory; + ppc::storage::FileStorageFactory::Ptr m_fileStorageFactory; + ppc::storage::RemoteStorageFactory::Ptr m_remoteStorageFactory; +}; +} // namespace ppc::io \ No newline at end of file diff --git a/cpp/wedpr-storage/ppc-io/src/FileLineReader.cpp b/cpp/wedpr-storage/ppc-io/src/FileLineReader.cpp new file mode 100644 index 00000000..7a71585d --- /dev/null +++ b/cpp/wedpr-storage/ppc-io/src/FileLineReader.cpp @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2022 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 FileLineReader.cpp + * @author: yujiechen + * @date 2022-10-19 + */ + +#include "FileLineReader.h" +#include "Common.h" +#include +#include +#include +#include +#include +#include +using namespace ppc::io; +using namespace bcos; + +FileLineReader::FileLineReader( + std::string const& _filePath, int64_t _mmapGranularity, char _lineSpliter) + : BaseFileLineReader(_lineSpliter), + m_filePath(_filePath), + c_pageSize(getpagesize()), + m_mmapGranularity(_mmapGranularity) +{ + if (-1 == _mmapGranularity) + { + m_mmapGranularity = 500 * 1024 * c_pageSize; + } + // check the mmap-granularity + if (m_mmapGranularity % c_pageSize != 0) + { + BOOST_THROW_EXCEPTION( + InvalidMmapGranularity() << errinfo_comment( + "the mmapGranularity must a multiple of page-size: " + std::to_string(c_pageSize))); + } + // check whether the file exists + if (!boost::filesystem::exists(boost::filesystem::path(m_filePath))) + { + BOOST_THROW_EXCEPTION(OpenFileFailed() << errinfo_comment(_filePath + " not exist!")); + } + // the filePath should not be directory + if (boost::filesystem::is_directory(boost::filesystem::path(m_filePath))) + { + BOOST_THROW_EXCEPTION( + OpenFileFailed() << errinfo_comment( + "The " + _filePath + " is a directory. Only support load content from file!")); + } + m_readGranularity = m_mmapGranularity / 8; + // open the file + m_fd = open(m_filePath.c_str(), O_RDONLY, 0644); + if (-1 == m_fd) + { + BOOST_THROW_EXCEPTION( + OpenFileFailed() << errinfo_comment("open file " + _filePath + " exception")); + } + m_length = lseek(m_fd, 0, SEEK_END); + IO_LOG(INFO) << LOG_DESC("FileLineReader: open file success") << LOG_KV("file", _filePath) + << LOG_KV("length", m_length) << LOG_KV("pageSize", c_pageSize); +} + +FileLineReader::~FileLineReader() +{ + if (-1 == m_fd) + { + return; + } + close(m_fd); +} + +bool FileLineReader::allocateCurrentBlock() +{ + if (readFinished()) + { + return false; + } + // holds mmap that has not been read-finished + if (m_currentBlockParser && m_currentBlockParser->pointer() < m_currentBlockParser->length()) + { + return true; + } + // without mmap or the mmap has already been read-finished, re-allocate a new mmapFile + auto mmapSize = std::min(m_mmapGranularity, (m_length - m_offset)); + m_currentBlockParser = std::make_unique(m_fd, m_offset, mmapSize); + IO_LOG(TRACE) << LOG_DESC("allocate new mmap") << LOG_KV("size", mmapSize) + << LOG_KV("offset", m_offset); + return true; +} \ No newline at end of file diff --git a/cpp/wedpr-storage/ppc-io/src/FileLineReader.h b/cpp/wedpr-storage/ppc-io/src/FileLineReader.h new file mode 100644 index 00000000..fca4b47a --- /dev/null +++ b/cpp/wedpr-storage/ppc-io/src/FileLineReader.h @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2022 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 FileLineReader.h + * @author: yujiechen + * @date 2022-10-19 + */ +#pragma once +#include "BaseFileLineReader.h" +#include "parser/MmapParser.h" +#include "ppc-framework/io/LineReader.h" +#include + +namespace ppc::io +{ +class FileLineReader : public BaseFileLineReader +{ +public: + using Ptr = std::shared_ptr; + // Note: the same file can't be read/write in the same time + FileLineReader( + std::string const& _filePath, int64_t _mmapGranularity = -1, char _lineSpliter = '\n'); + ~FileLineReader() override; + + ppc::protocol::DataResourceType type() const override + { + return ppc::protocol::DataResourceType::FILE; + } + bool readFinished() const override { return (m_offset == m_length); } + +protected: + bool allocateCurrentBlock() override; + +protected: + std::string m_filePath; + int c_pageSize; + // Note: the mmapGranularity must a multiple of page-size + uint64_t m_mmapGranularity; // the mmap-granularity, default is (500 * 1024 * pageSize) + + int m_fd = -1; +}; + +class FileLineReaderFactory : public LineReaderFactory +{ +public: + using Ptr = std::shared_ptr; + FileLineReaderFactory() = default; + ~FileLineReaderFactory() override = default; + + LineReader::Ptr createLineReader(std::string const& _filePath, + uint64_t _mmapGranularity = 500 * 1024 * 1024, char _lineSpliter = '\n') override + { + return std::make_shared(_filePath, _mmapGranularity, _lineSpliter); + } +}; +} // namespace ppc::io \ No newline at end of file diff --git a/cpp/wedpr-storage/ppc-io/src/FileLineWriter.cpp b/cpp/wedpr-storage/ppc-io/src/FileLineWriter.cpp new file mode 100644 index 00000000..c8f74832 --- /dev/null +++ b/cpp/wedpr-storage/ppc-io/src/FileLineWriter.cpp @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2022 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 FileLineWriter.cpp + * @author: yujiechen + * @date 2022-10-21 + */ +#include "FileLineWriter.h" +#include +#include + +using namespace ppc::io; +using namespace bcos; +FileLineWriter::FileLineWriter(std::string const& _filePath, bool _trunc) : m_filePath(_filePath) +{ + boost::filesystem::path filePath(m_filePath); + auto parentPath = filePath.parent_path(); + // the parentPath is a file + if (!parentPath.empty() && boost::filesystem::exists(filePath.parent_path()) && + !boost::filesystem::is_directory(parentPath)) + { + BOOST_THROW_EXCEPTION( + OpenFileLineWriterException() << bcos::errinfo_comment( + "open " + m_filePath + " error for the non-dir-parent-path exists!")); + } + try + { + // the parentPath not exists, create the parentPath + if (!parentPath.empty() && !boost::filesystem::is_directory(parentPath)) + { + boost::filesystem::create_directories(parentPath); + } + m_outStream.open(m_filePath, std::ios::binary | (_trunc ? std::ios::trunc : std::ios::app)); + } + catch (std::exception const& e) + { + BOOST_THROW_EXCEPTION( + OpenFileLineWriterException() << bcos::errinfo_comment( + "open " + m_filePath + " error: " + boost::diagnostic_information(e))); + } +} + +// write the data into the writer(Note: only support row-data) +bool FileLineWriter::writeLine( + DataBatch::ConstPtr _data, DataSchema _schema, std::string _lineSplitter) +{ + switch (_schema) + { + case DataSchema::String: + { + writeData(_data, _lineSplitter); + return true; + } + case DataSchema::Bytes: + { + writeData(_data, _lineSplitter); + return true; + } + default: + { + BOOST_THROW_EXCEPTION(UnsupportedDataSchema() << bcos::errinfo_comment( + "Only support String and Bytes schema now!")); + } + } +} + +void FileLineWriter::writeBytes(bytesConstRef _data) +{ + m_outStream.write(reinterpret_cast(_data.data()), _data.size()); +} + + +// flush the data into the storage-backend +void FileLineWriter::flush() +{ + m_outStream.flush(); +} +// close the storage-backend resource(Note: flush before close) +void FileLineWriter::close() +{ + m_outStream.close(); +} \ No newline at end of file diff --git a/cpp/wedpr-storage/ppc-io/src/FileLineWriter.h b/cpp/wedpr-storage/ppc-io/src/FileLineWriter.h new file mode 100644 index 00000000..19b762fa --- /dev/null +++ b/cpp/wedpr-storage/ppc-io/src/FileLineWriter.h @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2022 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 FileLineWriter.h + * @author: yujiechen + * @date 2022-10-21 + */ +#pragma once +#include "Common.h" +#include "ppc-framework/io/LineWriter.h" +#include + +namespace ppc::io +{ +class FileLineWriter : public LineWriter +{ +public: + using Ptr = std::shared_ptr; + FileLineWriter(std::string const& _filePath, bool _trunc = false); + ~FileLineWriter() override + { + try + { + flush(); + close(); + } + catch (std::exception const& e) + { + BOOST_THROW_EXCEPTION( + CloseFileLineWriterException() << bcos::errinfo_comment( + "close " + m_filePath + " error: " + boost::diagnostic_information(e))); + } + } + + ppc::protocol::DataResourceType type() const override + { + return ppc::protocol::DataResourceType::FILE; + } + + // write the data into the writer(Note: only support row-data) + bool writeLine( + DataBatch::ConstPtr _data, DataSchema _schema, std::string _lineSplitter) override; + + void writeBytes(bcos::bytesConstRef _data) override; + + // flush the data into the storage-backend + void flush() override; + // close the storage-backend resource(Note: flush before close) + void close() override; + +private: + template + void writeData(DataBatch::ConstPtr _dataBatch, std::string _lineSplitter) + { + IO_LOG(TRACE) << LOG_DESC("writeData, size:") << _dataBatch->size(); + for (uint64_t i = 0; i < _dataBatch->size(); i++) + { + auto const& element = _dataBatch->get(i); + m_outStream.write(reinterpret_cast(element.data()), element.size()); + if (_lineSplitter.empty()) + { + continue; + } + m_outStream.write(_lineSplitter.c_str(), _lineSplitter.size()); + } + } + +protected: + std::ofstream m_outStream; + std::string m_filePath; +}; +} // namespace ppc::io \ No newline at end of file diff --git a/cpp/wedpr-storage/ppc-io/src/FileSystemDeleter.h b/cpp/wedpr-storage/ppc-io/src/FileSystemDeleter.h new file mode 100644 index 00000000..dff414d1 --- /dev/null +++ b/cpp/wedpr-storage/ppc-io/src/FileSystemDeleter.h @@ -0,0 +1,37 @@ +#pragma once +#include +#include +#include +#include + +class FileSystemDeleter +{ +public: + FileSystemDeleter(std::vector filePaths): m_filePaths(filePaths) {} + ~FileSystemDeleter() + { + removeAllFiles(m_filePaths); + } + +public: + void removeAllFiles(const std::vector &files) + { + for (const auto &file : files) + { + try + { + if (!file.empty() && boost::filesystem::exists(file)) + { + boost::filesystem::remove_all(file); + BCOS_LOG(INFO) << LOG_DESC("remove file") << LOG_KV("file", file); + } + } catch (...) + { + // do nothing + } + } + } + +private: + std::vector m_filePaths; +}; \ No newline at end of file diff --git a/cpp/wedpr-storage/ppc-io/src/HDFSReader.cpp b/cpp/wedpr-storage/ppc-io/src/HDFSReader.cpp new file mode 100644 index 00000000..a6432b4f --- /dev/null +++ b/cpp/wedpr-storage/ppc-io/src/HDFSReader.cpp @@ -0,0 +1,120 @@ +/* + * Copyright (C) 2022 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 HDFSReader.cpp + * @author: yujiechen + * @date 2022-11-30 + */ +#include "HDFSReader.h" + +using namespace bcos; +using namespace ppc::io; +using namespace ppc::storage; + +HDFSReader::HDFSReader(FileHandler::Ptr _handler, uint64_t _bufferSize, char _lineSpliter) + : BaseFileLineReader(_lineSpliter), m_handler(_handler), m_bufferSize(_bufferSize) +{ + m_length = ((hdfsFileInfo*)_handler->fileInfoHandler())->mSize; + m_hostsInfo = + hdfsGetHosts((hdfsFS)_handler->storageHandler(), _handler->path().c_str(), 0, m_length); + if (!m_hostsInfo) + { + BOOST_THROW_EXCEPTION( + HDFSOpenMetaInfoFailed() + << errinfo_comment("hdfsGetHosts failed, error: " + std::string(hdfsGetLastError()))); + } + // set the m_readGranularity + m_readGranularity = m_bufferSize / 8; + IO_LOG(DEBUG) << LOG_DESC("create HDFSReader success") << LOG_KV("path", _handler->path()) + << LOG_KV("fileSize", m_length) << LOG_KV("bufferSize", m_bufferSize) + << LOG_KV("readGranularity", m_readGranularity); +} + +bool HDFSReader::allocateCurrentBlock() +{ + if (readFinished()) + { + return false; + } + // the loaded block-parser has not been read-finished + if (m_currentBlockParser && m_currentBlockParser->pointer() < m_currentBlockParser->length()) + { + return true; + } + + // read data from the current fd + if (m_currentFd && loadDataAndCreateBufferParser()) + { + return true; + } + // the current fd is null or read-empty-data from the current fd + if (!tryToOpenNewFile()) + { + return false; + } + // open new file success, try to load-data and create buffer parser + return loadDataAndCreateBufferParser(); +} + +bool HDFSReader::tryToOpenNewFile() +{ + m_currentBlockOffset++; + if (!m_hostsInfo) + { + return false; + } + if (!m_hostsInfo[m_currentBlock]) + { + return false; + } + char* hostName = m_hostsInfo[m_currentBlock][m_currentBlockOffset]; + // the block has been read-finished + if (!hostName) + { + m_currentBlock++; + // reset the offset to 0 + m_currentBlockOffset = 0; + } + // all blocks has been read-finished + if (!m_hostsInfo[m_currentBlock]) + { + IO_LOG(INFO) << LOG_DESC("tryToOpenNewFile finish for null block") + << LOG_KV("block", m_currentBlock); + + return false; + } + // open the file + hostName = m_hostsInfo[m_currentBlock][m_currentBlockOffset]; + if (!hostName) + { + IO_LOG(INFO) << LOG_DESC("tryToOpenNewFile finish for null block items") + << LOG_KV("block", m_currentBlock) + << LOG_KV("blockOffset", m_currentBlockOffset); + return false; + } + // release the old fd + hdfsFS fs = (hdfsFS)m_handler->storageHandler(); + // try to open the new file + m_currentFd.reset(new HdfsFileWrapper( + m_handler, hdfsOpenFile2(fs, hostName, m_handler->path().c_str(), O_RDONLY, + ((hdfsFileInfo*)(m_handler->fileInfoHandler()))->mBlockSize, 0, 0))); + if (!m_currentFd) + { + BOOST_THROW_EXCEPTION(OpenFileFailed() << errinfo_comment( + "HDFSOpenFileFailed failed, host:" + std::string(hostName) + + ", error: " + std::string(hdfsGetLastError()))); + } + return true; +} \ No newline at end of file diff --git a/cpp/wedpr-storage/ppc-io/src/HDFSReader.h b/cpp/wedpr-storage/ppc-io/src/HDFSReader.h new file mode 100644 index 00000000..31aeab30 --- /dev/null +++ b/cpp/wedpr-storage/ppc-io/src/HDFSReader.h @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2022 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 HDFSReader.h + * @author: yujiechen + * @date 2022-11-30 + */ +#pragma once +#include "BaseFileLineReader.h" +#include "parser/BufferParser.h" +#include "ppc-framework/io/LineReader.h" +#include "ppc-framework/storage/FileStorage.h" +#include + +namespace ppc::io +{ +class HDFSReader : public BaseFileLineReader +{ +public: + using Ptr = std::shared_ptr; + HDFSReader(ppc::storage::FileHandler::Ptr _handler, uint64_t _bufferSize = 500 * 1024 * 1024, + char _lineSpliter = '\n'); + ~HDFSReader() override = default; + + // the capacity of the file or memory-bytes + uint64_t capacity() const override { return m_length; } + ppc::protocol::DataResourceType type() const override + { + return ppc::protocol::DataResourceType::HDFS; + } + + bool readFinished() const override { return (m_offset == m_length); } + +protected: + bool allocateCurrentBlock() override; + virtual bool tryToOpenNewFile(); + + inline bool loadDataAndCreateBufferParser() + { + auto buffer = std::make_shared(); + auto dataLen = std::min(m_bufferSize, (m_length - m_offset)); + buffer->resize(dataLen); + + hdfsFS fs = (hdfsFS)m_handler->storageHandler(); + // read data from the hdfs + uint64_t readedCount = 0; + int64_t readedBytes = 0; + // Note: when read-finished, hdfsRead return 0 + // the hdfsRead api only return 65536Bytes data at one time + do + { + readedBytes = hdfsRead(fs, m_currentFd->fs, buffer->data() + readedCount, dataLen); + readedCount += readedBytes; + } while (readedBytes != 0 && readedBytes != -1 && readedCount < dataLen); + // read error + if (readedBytes == -1) + { + BOOST_THROW_EXCEPTION( + HDFSReadDataFailed() << bcos::errinfo_comment( + "loadDataAndCreateBufferParser: read-hdfs-data failed, error: " + + std::string(hdfsGetLastError()))); + } + // the file has been read finished + if (readedCount > 0) + { + IO_LOG(TRACE) << LOG_DESC("loadDataAndCreateBufferParser") + << LOG_KV("readedCount", readedCount); + m_readedBytes += readedCount; + buffer->resize(readedCount); + // seek to the pointer + hdfsSeek(fs, m_currentFd->fs, m_readedBytes); + // allocate the currentBlockParser + m_currentBlockParser = std::make_shared(std::move(*buffer)); + return true; + } + return false; + } + +private: + // the file handler + ppc::storage::FileHandler::Ptr m_handler; + // buffer size loaded per time + uint64_t m_bufferSize; + std::unique_ptr m_currentFd; + char*** m_hostsInfo; + uint64_t m_readedBytes = 0; + int m_currentBlock = 0; + int m_currentBlockOffset = -1; +}; +} // namespace ppc::io \ No newline at end of file diff --git a/cpp/wedpr-storage/ppc-io/src/HDFSWriter.cpp b/cpp/wedpr-storage/ppc-io/src/HDFSWriter.cpp new file mode 100644 index 00000000..47dd6090 --- /dev/null +++ b/cpp/wedpr-storage/ppc-io/src/HDFSWriter.cpp @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2022 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 HDFSWriter.h + * @author: yujiechen + * @date 2022-12-1 + */ +#include "HDFSWriter.h" + +using namespace ppc::io; +using namespace ppc::storage; +using namespace bcos; + +HDFSWriter::HDFSWriter(FileHandler::Ptr _handler, bool _trunc, int64_t _cacheSize) + : m_handler(std::move(_handler)), m_cacheSize(_cacheSize) +{ + IO_LOG(INFO) << LOG_DESC("HDFSWriter") << LOG_KV("path", m_handler->path()); + int flag = O_WRONLY; + if (!_trunc) + { + flag |= O_APPEND; + } + auto rawFd = + hdfsOpenFile((hdfsFS)m_handler->storageHandler(), m_handler->path().c_str(), flag, 0, 0, 0); + if (!rawFd) + { + BOOST_THROW_EXCEPTION(OpenFileFailed() << errinfo_comment( + "HDFSWriter: open file " + m_handler->path() + " failed!")); + } + + m_fd.reset(new HdfsFileWrapper(m_handler, rawFd)); +} +// write the data into the writer(Note: only support row-data) +bool HDFSWriter::writeLine(DataBatch::ConstPtr _data, DataSchema _schema, std::string _lineSplitter) +{ + switch (_schema) + { + case DataSchema::String: + { + writeData(_data, _lineSplitter); + return true; + } + case DataSchema::Bytes: + { + writeData(_data, _lineSplitter); + return true; + } + default: + { + BOOST_THROW_EXCEPTION(UnsupportedDataSchema() << bcos::errinfo_comment( + "Only support String and Bytes schema now!")); + } + } + return false; +} + +void HDFSWriter::writeBytes(bcos::bytesConstRef _data) +{ + auto ret = hdfsWrite((hdfsFS)m_handler->storageHandler(), m_fd->fs, _data.data(), _data.size()); + if (ret == -1) + { + BOOST_THROW_EXCEPTION(HDFSWriteDataFailed() << bcos::errinfo_comment( + "writeBytes failed, error: " + std::string(hdfsGetLastError()))); + } +} + +// flush the data into the storage-backend +// Note: we should not calls flush multiple times +void HDFSWriter::flush() +{ + if (hdfsFlush((hdfsFS)m_handler->storageHandler(), m_fd->fs) == -1) + { + BOOST_THROW_EXCEPTION(HDFSFlushFailed() << bcos::errinfo_comment( + "flush failed, error: " + std::string(hdfsGetLastError()))); + } +} +// close the storage-backend resource(Note: flush before close) +void HDFSWriter::close() +{ + m_fd.reset(); +} \ No newline at end of file diff --git a/cpp/wedpr-storage/ppc-io/src/HDFSWriter.h b/cpp/wedpr-storage/ppc-io/src/HDFSWriter.h new file mode 100644 index 00000000..3c97b9da --- /dev/null +++ b/cpp/wedpr-storage/ppc-io/src/HDFSWriter.h @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2022 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 HDFSWriter.h + * @author: yujiechen + * @date 2022-12-1 + */ +#pragma once +#include "Common.h" +#include "ppc-framework/io/LineWriter.h" +#include "ppc-framework/storage/FileStorage.h" + +namespace ppc::io +{ +class HDFSWriter : public LineWriter +{ +public: + using Ptr = std::shared_ptr; + HDFSWriter(ppc::storage::FileHandler::Ptr _handler, bool _trunc, + int64_t _cacheSize = 100 * 1024 * 1024); + ~HDFSWriter() override { close(); } + + ppc::protocol::DataResourceType type() const override + { + return ppc::protocol::DataResourceType::HDFS; + } + + // write the data into the writer(Note: only support row-data) + bool writeLine( + DataBatch::ConstPtr _data, DataSchema _schema, std::string _lineSplitter = "\n") override; + + void writeBytes(bcos::bytesConstRef _data) override; + + // flush the data into the storage-backend + void flush() override; + // close the storage-backend resource(Note: flush before close) + void close() override; + +protected: + void flushCache(bool _enforce) + { + if (m_cache.size() == 0) + { + return; + } + if (!_enforce && m_cache.size() < m_cacheSize) + { + return; + } + // flush cache into the hdfs, clear the cache + auto ret = hdfsWrite( + (hdfsFS)m_handler->storageHandler(), m_fd->fs, m_cache.data(), m_cache.size()); + if (ret == -1) + { + BOOST_THROW_EXCEPTION( + HDFSWriteDataFailed() << bcos::errinfo_comment( + "write cache-data failed, error: " + std::string(hdfsGetLastError()))); + } + m_cache.clear(); + } + + template + void writeData(DataBatch::ConstPtr _data, std::string _lineSplitter) + { + for (uint64_t i = 0; i < _data->size(); i++) + { + if (m_cache.size() >= m_cacheSize) + { + flushCache(false); + } + auto& lineData = _data->get(i); + m_cache.insert(m_cache.end(), reinterpret_cast(lineData.data()), + reinterpret_cast(lineData.data() + lineData.size())); + if (_lineSplitter.empty()) + { + continue; + } + m_cache.insert(m_cache.end(), reinterpret_cast(_lineSplitter.data()), + reinterpret_cast(_lineSplitter.data() + _lineSplitter.size())); + } + flushCache(true); + } + +private: + ppc::storage::FileHandler::Ptr m_handler; + std::unique_ptr m_fd; + + int64_t m_cacheSize; + bcos::bytes m_cache; +}; +} // namespace ppc::io \ No newline at end of file diff --git a/cpp/wedpr-storage/ppc-io/src/SQLResultReader.h b/cpp/wedpr-storage/ppc-io/src/SQLResultReader.h new file mode 100644 index 00000000..99b92843 --- /dev/null +++ b/cpp/wedpr-storage/ppc-io/src/SQLResultReader.h @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2022 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 SQLResultReader.h + * @author: yujiechen + * @date 2022-11-4 + */ +#pragma once +#include "ppc-framework/io/LineReader.h" +#include "ppc-framework/storage/SQLStorage.h" +#include + +namespace ppc::io +{ +class SQLResultReader : public LineReader +{ +public: + using Ptr = std::shared_ptr; + SQLResultReader(ppc::storage::QueryResult::Ptr _result, bool _parseByColumn) + : m_result(std::move(_result)), m_parseByColumn(_parseByColumn) + {} + ~SQLResultReader() override {} + // get the next _offset line data + // Note: the _schema is not used by mysql-result-reader + DataBatch::Ptr next(int64_t _offset = 0, DataSchema _schema = DataSchema::Bytes) override + { + boost::ignore_unused(_schema); + if ((int64_t)m_result->data().size() <= _offset) + { + return nullptr; + } + return m_result->mutableData().at(_offset); + } + + // the capacity the query-result + uint64_t capacity() const override { return m_result->data().size(); } + uint64_t columnSize() const override + { + if (m_parseByColumn) + { + return m_result->data().size(); + } + return 1; + } + + ppc::protocol::DataResourceType type() const override + { + return ppc::protocol::DataResourceType::MySQL; + } + + bcos::bytes readBytes() override + { + throw std::runtime_error("SQLResultReader: unimplemented readBytes!"); + } + bool readFinished() const override { return true; } + +private: + ppc::storage::QueryResult::Ptr m_result; + bool m_parseByColumn; +}; +} // namespace ppc::io \ No newline at end of file diff --git a/cpp/wedpr-storage/ppc-io/src/parser/BaseBufferParser.h b/cpp/wedpr-storage/ppc-io/src/parser/BaseBufferParser.h new file mode 100644 index 00000000..de2093c0 --- /dev/null +++ b/cpp/wedpr-storage/ppc-io/src/parser/BaseBufferParser.h @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2022 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 BaseBufferParser.h + * @author: yujiechen + * @date 2022-11-30 + */ +#pragma once +#include +namespace ppc::io +{ +enum class ReadLineResult +{ + ReadFinish, + ReadFinishWithoutSpliter, + NotReadFinish, +}; +class BaseBufferParser +{ +public: + using Ptr = std::shared_ptr; + BaseBufferParser() = default; + BaseBufferParser(char* _address, uint64_t _length) : m_address(_address), m_length(_length) {} + virtual ~BaseBufferParser() = default; + + virtual void* address() const { return (void*)m_address; } + virtual uint64_t length() const { return m_length; } + + template + ReadLineResult readLine(int64_t& readBytes, T& _lineData, char _delim = '\n') + { + if (m_pointer >= m_length) + { + return ReadLineResult::ReadFinish; + } + auto orgPointer = m_pointer; + auto startAddr = m_address + m_pointer; + uint64_t copyLen = 0; + bool findDelim = false; + for (; m_pointer < m_length; m_pointer++) + { + while (m_pointer < m_length && (((char)*(m_address + m_pointer) == _delim) || + ((char)*(m_address + m_pointer) == c_ignoreDelim))) + { + // skip the delim when read-line next-round + m_pointer++; + findDelim = true; + } + if (findDelim) + { + break; + } + copyLen++; + } + readBytes = (uint64_t)(m_pointer - orgPointer); + _lineData.resize(copyLen); + memcpy(_lineData.data(), (char*)startAddr, copyLen); + // not read-finished + if (m_pointer < m_length) + { + return ReadLineResult::NotReadFinish; + } + if (findDelim) + { + return ReadLineResult::ReadFinish; + } + return ReadLineResult::ReadFinishWithoutSpliter; + } + + virtual void readAll(bcos::bytes& _data) + { + _data.insert(_data.end(), (char*)m_address, (char*)m_address + m_length); + m_pointer = m_length; + } + virtual uint64_t pointer() const { return m_pointer; } + +protected: + char* m_address = nullptr; + uint64_t m_length; + uint64_t m_pointer = 0; + + const char c_ignoreDelim = '\r'; +}; +} // namespace ppc::io \ No newline at end of file diff --git a/cpp/wedpr-storage/ppc-io/src/parser/BufferParser.h b/cpp/wedpr-storage/ppc-io/src/parser/BufferParser.h new file mode 100644 index 00000000..ed4791fc --- /dev/null +++ b/cpp/wedpr-storage/ppc-io/src/parser/BufferParser.h @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2022 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 BufferParser.h + * @author: yujiechen + * @date 2022-11-30 + */ +#pragma once +#include "BaseBufferParser.h" + +namespace ppc::io +{ +class BufferParser : public BaseBufferParser +{ +public: + using Ptr = std::shared_ptr; + BufferParser(std::vector&& _data) : BaseBufferParser(), m_data(std::move(_data)) + { + m_length = m_data.size(); + m_address = (char*)m_data.data(); + } + ~BufferParser() override = default; + +protected: + std::vector m_data; +}; +} // namespace ppc::io \ No newline at end of file diff --git a/cpp/wedpr-storage/ppc-io/src/parser/MmapParser.h b/cpp/wedpr-storage/ppc-io/src/parser/MmapParser.h new file mode 100644 index 00000000..90e8ed2b --- /dev/null +++ b/cpp/wedpr-storage/ppc-io/src/parser/MmapParser.h @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2022 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 MmapParser.h + * @author: yujiechen + * @date 2022-10-20 + */ +#pragma once +#include "../Common.h" +#include "BaseBufferParser.h" +#include +#include + +namespace ppc::io +{ +class MmapParser : public BaseBufferParser +{ +public: + using Ptr = std::unique_ptr; + MmapParser(int _fd, uint64_t _offset, uint64_t _length, bool _readOnly = true) + : BaseBufferParser() + { + m_length = _length; + int prot = PROT_READ; + if (!_readOnly) + { + prot = PROT_READ | PROT_WRITE; + } + // Note: the mmap offset param must be a multiple of page-size(4096), otherwise, Invalid + // Argument error will be raised + m_address = (char*)mmap(nullptr, _length, prot, MAP_SHARED, _fd, _offset); + if (MAP_FAILED == m_address) + { + BOOST_THROW_EXCEPTION(MmapFileException() << bcos::errinfo_comment( + "mmap file exception, code: " + std::to_string(errno) + + ", error: " + strerror(errno))); + } + IO_LOG(INFO) << LOG_DESC("MmapFile success") << LOG_KV("offset", _offset) + << LOG_KV("length", _length) << LOG_KV("readOnly", _readOnly) + << ", address:" << std::hex << (uint64_t)m_address; + } + + ~MmapParser() override + { + if (!m_address) + { + return; + } + munmap(m_address, m_length); + } +}; +} // namespace ppc::io \ No newline at end of file diff --git a/cpp/wedpr-storage/ppc-io/tests/CMakeLists.txt b/cpp/wedpr-storage/ppc-io/tests/CMakeLists.txt new file mode 100644 index 00000000..549e861c --- /dev/null +++ b/cpp/wedpr-storage/ppc-io/tests/CMakeLists.txt @@ -0,0 +1,10 @@ +file(GLOB_RECURSE SOURCES "*.cpp" "*.h") + +# cmake settings +set(TEST_BINARY_NAME test-ppc-io) + +add_executable(${TEST_BINARY_NAME} ${SOURCES}) +target_include_directories(${TEST_BINARY_NAME} PRIVATE .) + +target_link_libraries(${TEST_BINARY_NAME} ${IO_TARGET} ${BOOST_UNIT_TEST}) +add_test(NAME test-io WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} COMMAND ${TEST_BINARY_NAME}) diff --git a/cpp/wedpr-storage/ppc-io/tests/TestLineReader.cpp b/cpp/wedpr-storage/ppc-io/tests/TestLineReader.cpp new file mode 100644 index 00000000..2050a9c9 --- /dev/null +++ b/cpp/wedpr-storage/ppc-io/tests/TestLineReader.cpp @@ -0,0 +1,190 @@ +/* + * Copyright (C) 2022 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 applicabl 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 TestLineReader.cpp + * @author: yujiechen + * @date 2022-10-21 + */ +#include "ppc-io/src/Common.h" +#include "ppc-io/src/FileLineReader.h" +#include +#include + +using namespace ppc::io; +using namespace bcos; +using namespace bcos::test; + +namespace ppc::test +{ +BOOST_FIXTURE_TEST_SUITE(lineReaderTest, TestPromptFixture) + +void testFileLineReaderFunc(FileLineReaderFactory::Ptr _factory, std::string const& _filePath, + char _lineSpliter, uint64_t _mmapGranularity, uint64_t _fileTotalLine, + std::vector const& _expectedData, uint64_t _batchSize) +{ + if (_mmapGranularity % getpagesize() != 0) + { + BOOST_CHECK_THROW(_factory->createLineReader(_filePath, _mmapGranularity, _lineSpliter), + InvalidMmapGranularity); + return; + } + auto lineReader = _factory->createLineReader(_filePath, _mmapGranularity, _lineSpliter); + // case1: read all data from the file + auto dataBatch = lineReader->next(-1); + BOOST_CHECK(dataBatch->size() == _fileTotalLine); + std::cout << "#### dataBatch size: " << dataBatch->size() << std::endl; + + // check the data + uint64_t offset = 0; + for (auto const& item : _expectedData) + { + BOOST_CHECK(item == dataBatch->get(offset)); + offset++; + } + // try to read again while the file has been read-finished + BOOST_CHECK(nullptr == lineReader->next(1)); + + // case2: read _batchSize everyTime + lineReader = _factory->createLineReader(_filePath, _mmapGranularity, _lineSpliter); + uint64_t readedLine = 0; + std::vector dataBatches; + while (true) + { + dataBatch = lineReader->next(_batchSize); + if (!dataBatch) + { + break; + } + readedLine += dataBatch->size(); + dataBatches.emplace_back(dataBatch); + } + BOOST_CHECK(readedLine == _expectedData.size()); + // check the dataBatch + offset = 0; + for (auto const& batch : dataBatches) + { + for (uint64_t i = 0; i < batch->size(); i++) + { + BOOST_CHECK(batch->get(i) == _expectedData[offset]); + offset++; + } + } +} +BOOST_AUTO_TEST_CASE(testDataBatch) +{ + auto dataBatch = std::make_shared(); + uint64_t dataSize = 1002; + std::vector stringData; + std::vector intData; + uint64_t expectedStringCapacity = 0; + for (uint64_t i = 0; i < dataSize; i++) + { + auto str = std::to_string(i); + expectedStringCapacity += str.size(); + stringData.emplace_back(str); + intData.emplace_back(i); + } + // setData and check capacity + auto tmpData = stringData; + dataBatch->setData(std::move(tmpData)); + std::cout << "#### capacityBytes" << dataBatch->capacityBytes() << std::endl; + std::cout << "### expectedStringCapacity: " << expectedStringCapacity << std::endl; + BOOST_CHECK(dataBatch->capacityBytes() == expectedStringCapacity); + // append + for (uint64_t i = 0; i < stringData.size(); i++) + { + BOOST_CHECK(dataBatch->get(i) == stringData.at(i)); + BOOST_CHECK(dataBatch->elementSize(i) == stringData.at(i).size()); + auto tmp = stringData.at(i); + dataBatch->append(std::move(tmp)); + } + BOOST_CHECK(dataBatch->capacityBytes() == 2 * expectedStringCapacity); + + // appendToLine + auto orgSize = dataBatch->elementSize(dataBatch->size() - 1); + auto data = stringData.at(0); + dataBatch->appendToLine(std::move(data)); + BOOST_CHECK(dataBatch->elementSize(dataBatch->size() - 1) == + (stringData.at(0).size() + orgSize)); + // test set + std::string resetData = "reset"; + auto tmp = resetData; + dataBatch->set(0, std::move(tmp)); + BOOST_CHECK(resetData == dataBatch->get(0)); + + auto intDataBatch = std::make_shared(); + auto tmpIntData = intData; + intDataBatch->setData(std::move(tmpIntData)); + BOOST_CHECK(intDataBatch->capacityBytes() == dataSize * sizeof(uint64_t)); + for (uint64_t i = 0; i < intData.size(); i++) + { + BOOST_CHECK(intDataBatch->get(i) == intData.at(i)); + BOOST_CHECK(intDataBatch->elementSize(i) == sizeof(intData.at(i))); + auto tmp = intData.at(i); + intDataBatch->append(std::move(tmp)); + } + BOOST_CHECK(intDataBatch->capacityBytes() == 2 * dataSize * sizeof(uint64_t)); + + // the data-schema not set + BOOST_CHECK_THROW(intDataBatch->getBytes(0), DataSchemaNotSetted); + intDataBatch->setDataSchema(DataSchema::Uint); + + auto expectedData = boost::lexical_cast(intData.at(0)); + BOOST_CHECK(intDataBatch->getBytes(0) == bcos::bytes(expectedData.begin(), expectedData.end())); +} +BOOST_AUTO_TEST_CASE(testFileLineReader) +{ + std::string filePath = "../../../../wedpr-storage/ppc-io/tests/data/testData"; + uint64_t fileTotalLine = 10000; + std::vector fileData; + for (uint64_t i = 1; i <= fileTotalLine; i++) + { + fileData.emplace_back(std::to_string(i)); + } + auto factory = std::make_shared(); + // case1: invalid mmap-granularity + testFileLineReaderFunc(factory, filePath, '\n', 1024, fileTotalLine, fileData, 100); + + // case2: valid mmap-granularity + auto pageSize = getpagesize(); + auto startT = utcSteadyTime(); + testFileLineReaderFunc(factory, filePath, '\n', pageSize, fileTotalLine, fileData, 100); + std::cout << "### timecost with 1-page mmap-granularity:" << (utcSteadyTime() - startT) << " ms" + << ", pageSize:" << pageSize << std::endl; + + // case3: large mmap-granularity + startT = bcos::utcSteadyTime(); + testFileLineReaderFunc( + factory, filePath, '\n', 500 * 1024 * pageSize, fileTotalLine, fileData, 100); + std::cout << "### timecost with 500K-page mmap-granularity:" << (utcSteadyTime() - startT) + << " ms" + << ", pageSize:" << pageSize << std::endl; + + // case4: the windows file + auto windowsFilePath = "../../../../wedpr-storage/ppc-io/tests/data/windows_file.txt"; + auto lineReader = factory->createLineReader(windowsFilePath, pageSize, '\n'); + auto windowsDataBatch = lineReader->next(-1, DataSchema::Bytes); + + auto linuxFilePath = "../../../../wedpr-storage/ppc-io/tests/data/linux_file.txt"; + lineReader = factory->createLineReader(linuxFilePath, pageSize, '\n'); + auto linuxDataBatch = lineReader->next(-1, DataSchema::Bytes); + BOOST_CHECK(windowsDataBatch->size() == linuxDataBatch->size()); + for (uint64_t i = 0; i < windowsDataBatch->size(); i++) + { + BOOST_CHECK(windowsDataBatch->get(i) == linuxDataBatch->get(i)); + } +} +BOOST_AUTO_TEST_SUITE_END() +} // namespace ppc::test diff --git a/cpp/wedpr-storage/ppc-io/tests/TestLineWriter.cpp b/cpp/wedpr-storage/ppc-io/tests/TestLineWriter.cpp new file mode 100644 index 00000000..e33fda2e --- /dev/null +++ b/cpp/wedpr-storage/ppc-io/tests/TestLineWriter.cpp @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2022 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 applicabl 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 TestLineReader.cpp + * @author: yujiechen + * @date 2022-10-21 + */ + +#include "ppc-io/src/Common.h" +#include "ppc-io/src/FileLineReader.h" +#include "ppc-io/src/FileLineWriter.h" +#include +#include + +using namespace ppc::io; +using namespace bcos; +using namespace bcos::test; + +namespace ppc::test +{ +BOOST_FIXTURE_TEST_SUITE(lineWriterTest, TestPromptFixture) +BOOST_AUTO_TEST_CASE(testFileLineWriter) +{ + auto dataBatch = std::make_shared(); + for (uint64_t i = 0; i < 10000; i++) + { + dataBatch->append(std::to_string(i)); + } + std::string fileName = "testWriter"; + auto writer = std::make_shared(fileName, true); + writer->writeLine(dataBatch, DataSchema::String, "\n"); + writer->close(); + // check the content use FileLineReader + auto reader = std::make_shared(fileName); + auto readedData = reader->next(-1); + BOOST_CHECK(readedData->size() == dataBatch->size()); + for (uint64_t i = 0; i < readedData->size(); i++) + { + BOOST_CHECK(readedData->get(i) == dataBatch->get(i)); + } +} +BOOST_AUTO_TEST_SUITE_END() +} // namespace ppc::test diff --git a/cpp/wedpr-storage/ppc-io/tests/data/linux_file.txt b/cpp/wedpr-storage/ppc-io/tests/data/linux_file.txt new file mode 100644 index 00000000..f00c965d --- /dev/null +++ b/cpp/wedpr-storage/ppc-io/tests/data/linux_file.txt @@ -0,0 +1,10 @@ +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 diff --git a/cpp/wedpr-storage/ppc-io/tests/data/testData b/cpp/wedpr-storage/ppc-io/tests/data/testData new file mode 100644 index 00000000..5bcdcf0d --- /dev/null +++ b/cpp/wedpr-storage/ppc-io/tests/data/testData @@ -0,0 +1,10002 @@ +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 + + +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +163 +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 +175 +176 +177 +178 +179 +180 +181 +182 +183 +184 +185 +186 +187 +188 +189 +190 +191 +192 +193 +194 +195 +196 +197 +198 +199 +200 +201 +202 +203 +204 +205 +206 +207 +208 +209 +210 +211 +212 +213 +214 +215 +216 +217 +218 +219 +220 +221 +222 +223 +224 +225 +226 +227 +228 +229 +230 +231 +232 +233 +234 +235 +236 +237 +238 +239 +240 +241 +242 +243 +244 +245 +246 +247 +248 +249 +250 +251 +252 +253 +254 +255 +256 +257 +258 +259 +260 +261 +262 +263 +264 +265 +266 +267 +268 +269 +270 +271 +272 +273 +274 +275 +276 +277 +278 +279 +280 +281 +282 +283 +284 +285 +286 +287 +288 +289 +290 +291 +292 +293 +294 +295 +296 +297 +298 +299 +300 +301 +302 +303 +304 +305 +306 +307 +308 +309 +310 +311 +312 +313 +314 +315 +316 +317 +318 +319 +320 +321 +322 +323 +324 +325 +326 +327 +328 +329 +330 +331 +332 +333 +334 +335 +336 +337 +338 +339 +340 +341 +342 +343 +344 +345 +346 +347 +348 +349 +350 +351 +352 +353 +354 +355 +356 +357 +358 +359 +360 +361 +362 +363 +364 +365 +366 +367 +368 +369 +370 +371 +372 +373 +374 +375 +376 +377 +378 +379 +380 +381 +382 +383 +384 +385 +386 +387 +388 +389 +390 +391 +392 +393 +394 +395 +396 +397 +398 +399 +400 +401 +402 +403 +404 +405 +406 +407 +408 +409 +410 +411 +412 +413 +414 +415 +416 +417 +418 +419 +420 +421 +422 +423 +424 +425 +426 +427 +428 +429 +430 +431 +432 +433 +434 +435 +436 +437 +438 +439 +440 +441 +442 +443 +444 +445 +446 +447 +448 +449 +450 +451 +452 +453 +454 +455 +456 +457 +458 +459 +460 +461 +462 +463 +464 +465 +466 +467 +468 +469 +470 +471 +472 +473 +474 +475 +476 +477 +478 +479 +480 +481 +482 +483 +484 +485 +486 +487 +488 +489 +490 +491 +492 +493 +494 +495 +496 +497 +498 +499 +500 +501 +502 +503 +504 +505 +506 +507 +508 +509 +510 +511 +512 +513 +514 +515 +516 +517 +518 +519 +520 +521 +522 +523 +524 +525 +526 +527 +528 +529 +530 +531 +532 +533 +534 +535 +536 +537 +538 +539 +540 +541 +542 +543 +544 +545 +546 +547 +548 +549 +550 +551 +552 +553 +554 +555 +556 +557 +558 +559 +560 +561 +562 +563 +564 +565 +566 +567 +568 +569 +570 +571 +572 +573 +574 +575 +576 +577 +578 +579 +580 +581 +582 +583 +584 +585 +586 +587 +588 +589 +590 +591 +592 +593 +594 +595 +596 +597 +598 +599 +600 +601 +602 +603 +604 +605 +606 +607 +608 +609 +610 +611 +612 +613 +614 +615 +616 +617 +618 +619 +620 +621 +622 +623 +624 +625 +626 +627 +628 +629 +630 +631 +632 +633 +634 +635 +636 +637 +638 +639 +640 +641 +642 +643 +644 +645 +646 +647 +648 +649 +650 +651 +652 +653 +654 +655 +656 +657 +658 +659 +660 +661 +662 +663 +664 +665 +666 +667 +668 +669 +670 +671 +672 +673 +674 +675 +676 +677 +678 +679 +680 +681 +682 +683 +684 +685 +686 +687 +688 +689 +690 +691 +692 +693 +694 +695 +696 +697 +698 +699 +700 +701 +702 +703 +704 +705 +706 +707 +708 +709 +710 +711 +712 +713 +714 +715 +716 +717 +718 +719 +720 +721 +722 +723 +724 +725 +726 +727 +728 +729 +730 +731 +732 +733 +734 +735 +736 +737 +738 +739 +740 +741 +742 +743 +744 +745 +746 +747 +748 +749 +750 +751 +752 +753 +754 +755 +756 +757 +758 +759 +760 +761 +762 +763 +764 +765 +766 +767 +768 +769 +770 +771 +772 +773 +774 +775 +776 +777 +778 +779 +780 +781 +782 +783 +784 +785 +786 +787 +788 +789 +790 +791 +792 +793 +794 +795 +796 +797 +798 +799 +800 +801 +802 +803 +804 +805 +806 +807 +808 +809 +810 +811 +812 +813 +814 +815 +816 +817 +818 +819 +820 +821 +822 +823 +824 +825 +826 +827 +828 +829 +830 +831 +832 +833 +834 +835 +836 +837 +838 +839 +840 +841 +842 +843 +844 +845 +846 +847 +848 +849 +850 +851 +852 +853 +854 +855 +856 +857 +858 +859 +860 +861 +862 +863 +864 +865 +866 +867 +868 +869 +870 +871 +872 +873 +874 +875 +876 +877 +878 +879 +880 +881 +882 +883 +884 +885 +886 +887 +888 +889 +890 +891 +892 +893 +894 +895 +896 +897 +898 +899 +900 +901 +902 +903 +904 +905 +906 +907 +908 +909 +910 +911 +912 +913 +914 +915 +916 +917 +918 +919 +920 +921 +922 +923 +924 +925 +926 +927 +928 +929 +930 +931 +932 +933 +934 +935 +936 +937 +938 +939 +940 +941 +942 +943 +944 +945 +946 +947 +948 +949 +950 +951 +952 +953 +954 +955 +956 +957 +958 +959 +960 +961 +962 +963 +964 +965 +966 +967 +968 +969 +970 +971 +972 +973 +974 +975 +976 +977 +978 +979 +980 +981 +982 +983 +984 +985 +986 +987 +988 +989 +990 +991 +992 +993 +994 +995 +996 +997 +998 +999 +1000 +1001 +1002 +1003 +1004 +1005 +1006 +1007 +1008 +1009 +1010 +1011 +1012 +1013 +1014 +1015 +1016 +1017 +1018 +1019 +1020 +1021 +1022 +1023 +1024 +1025 +1026 +1027 +1028 +1029 +1030 +1031 +1032 +1033 +1034 +1035 +1036 +1037 +1038 +1039 +1040 +1041 +1042 +1043 +1044 +1045 +1046 +1047 +1048 +1049 +1050 +1051 +1052 +1053 +1054 +1055 +1056 +1057 +1058 +1059 +1060 +1061 +1062 +1063 +1064 +1065 +1066 +1067 +1068 +1069 +1070 +1071 +1072 +1073 +1074 +1075 +1076 +1077 +1078 +1079 +1080 +1081 +1082 +1083 +1084 +1085 +1086 +1087 +1088 +1089 +1090 +1091 +1092 +1093 +1094 +1095 +1096 +1097 +1098 +1099 +1100 +1101 +1102 +1103 +1104 +1105 +1106 +1107 +1108 +1109 +1110 +1111 +1112 +1113 +1114 +1115 +1116 +1117 +1118 +1119 +1120 +1121 +1122 +1123 +1124 +1125 +1126 +1127 +1128 +1129 +1130 +1131 +1132 +1133 +1134 +1135 +1136 +1137 +1138 +1139 +1140 +1141 +1142 +1143 +1144 +1145 +1146 +1147 +1148 +1149 +1150 +1151 +1152 +1153 +1154 +1155 +1156 +1157 +1158 +1159 +1160 +1161 +1162 +1163 +1164 +1165 +1166 +1167 +1168 +1169 +1170 +1171 +1172 +1173 +1174 +1175 +1176 +1177 +1178 +1179 +1180 +1181 +1182 +1183 +1184 +1185 +1186 +1187 +1188 +1189 +1190 +1191 +1192 +1193 +1194 +1195 +1196 +1197 +1198 +1199 +1200 +1201 +1202 +1203 +1204 +1205 +1206 +1207 +1208 +1209 +1210 +1211 +1212 +1213 +1214 +1215 +1216 +1217 +1218 +1219 +1220 +1221 +1222 +1223 +1224 +1225 +1226 +1227 +1228 +1229 +1230 +1231 +1232 +1233 +1234 +1235 +1236 +1237 +1238 +1239 +1240 +1241 +1242 +1243 +1244 +1245 +1246 +1247 +1248 +1249 +1250 +1251 +1252 +1253 +1254 +1255 +1256 +1257 +1258 +1259 +1260 +1261 +1262 +1263 +1264 +1265 +1266 +1267 +1268 +1269 +1270 +1271 +1272 +1273 +1274 +1275 +1276 +1277 +1278 +1279 +1280 +1281 +1282 +1283 +1284 +1285 +1286 +1287 +1288 +1289 +1290 +1291 +1292 +1293 +1294 +1295 +1296 +1297 +1298 +1299 +1300 +1301 +1302 +1303 +1304 +1305 +1306 +1307 +1308 +1309 +1310 +1311 +1312 +1313 +1314 +1315 +1316 +1317 +1318 +1319 +1320 +1321 +1322 +1323 +1324 +1325 +1326 +1327 +1328 +1329 +1330 +1331 +1332 +1333 +1334 +1335 +1336 +1337 +1338 +1339 +1340 +1341 +1342 +1343 +1344 +1345 +1346 +1347 +1348 +1349 +1350 +1351 +1352 +1353 +1354 +1355 +1356 +1357 +1358 +1359 +1360 +1361 +1362 +1363 +1364 +1365 +1366 +1367 +1368 +1369 +1370 +1371 +1372 +1373 +1374 +1375 +1376 +1377 +1378 +1379 +1380 +1381 +1382 +1383 +1384 +1385 +1386 +1387 +1388 +1389 +1390 +1391 +1392 +1393 +1394 +1395 +1396 +1397 +1398 +1399 +1400 +1401 +1402 +1403 +1404 +1405 +1406 +1407 +1408 +1409 +1410 +1411 +1412 +1413 +1414 +1415 +1416 +1417 +1418 +1419 +1420 +1421 +1422 +1423 +1424 +1425 +1426 +1427 +1428 +1429 +1430 +1431 +1432 +1433 +1434 +1435 +1436 +1437 +1438 +1439 +1440 +1441 +1442 +1443 +1444 +1445 +1446 +1447 +1448 +1449 +1450 +1451 +1452 +1453 +1454 +1455 +1456 +1457 +1458 +1459 +1460 +1461 +1462 +1463 +1464 +1465 +1466 +1467 +1468 +1469 +1470 +1471 +1472 +1473 +1474 +1475 +1476 +1477 +1478 +1479 +1480 +1481 +1482 +1483 +1484 +1485 +1486 +1487 +1488 +1489 +1490 +1491 +1492 +1493 +1494 +1495 +1496 +1497 +1498 +1499 +1500 +1501 +1502 +1503 +1504 +1505 +1506 +1507 +1508 +1509 +1510 +1511 +1512 +1513 +1514 +1515 +1516 +1517 +1518 +1519 +1520 +1521 +1522 +1523 +1524 +1525 +1526 +1527 +1528 +1529 +1530 +1531 +1532 +1533 +1534 +1535 +1536 +1537 +1538 +1539 +1540 +1541 +1542 +1543 +1544 +1545 +1546 +1547 +1548 +1549 +1550 +1551 +1552 +1553 +1554 +1555 +1556 +1557 +1558 +1559 +1560 +1561 +1562 +1563 +1564 +1565 +1566 +1567 +1568 +1569 +1570 +1571 +1572 +1573 +1574 +1575 +1576 +1577 +1578 +1579 +1580 +1581 +1582 +1583 +1584 +1585 +1586 +1587 +1588 +1589 +1590 +1591 +1592 +1593 +1594 +1595 +1596 +1597 +1598 +1599 +1600 +1601 +1602 +1603 +1604 +1605 +1606 +1607 +1608 +1609 +1610 +1611 +1612 +1613 +1614 +1615 +1616 +1617 +1618 +1619 +1620 +1621 +1622 +1623 +1624 +1625 +1626 +1627 +1628 +1629 +1630 +1631 +1632 +1633 +1634 +1635 +1636 +1637 +1638 +1639 +1640 +1641 +1642 +1643 +1644 +1645 +1646 +1647 +1648 +1649 +1650 +1651 +1652 +1653 +1654 +1655 +1656 +1657 +1658 +1659 +1660 +1661 +1662 +1663 +1664 +1665 +1666 +1667 +1668 +1669 +1670 +1671 +1672 +1673 +1674 +1675 +1676 +1677 +1678 +1679 +1680 +1681 +1682 +1683 +1684 +1685 +1686 +1687 +1688 +1689 +1690 +1691 +1692 +1693 +1694 +1695 +1696 +1697 +1698 +1699 +1700 +1701 +1702 +1703 +1704 +1705 +1706 +1707 +1708 +1709 +1710 +1711 +1712 +1713 +1714 +1715 +1716 +1717 +1718 +1719 +1720 +1721 +1722 +1723 +1724 +1725 +1726 +1727 +1728 +1729 +1730 +1731 +1732 +1733 +1734 +1735 +1736 +1737 +1738 +1739 +1740 +1741 +1742 +1743 +1744 +1745 +1746 +1747 +1748 +1749 +1750 +1751 +1752 +1753 +1754 +1755 +1756 +1757 +1758 +1759 +1760 +1761 +1762 +1763 +1764 +1765 +1766 +1767 +1768 +1769 +1770 +1771 +1772 +1773 +1774 +1775 +1776 +1777 +1778 +1779 +1780 +1781 +1782 +1783 +1784 +1785 +1786 +1787 +1788 +1789 +1790 +1791 +1792 +1793 +1794 +1795 +1796 +1797 +1798 +1799 +1800 +1801 +1802 +1803 +1804 +1805 +1806 +1807 +1808 +1809 +1810 +1811 +1812 +1813 +1814 +1815 +1816 +1817 +1818 +1819 +1820 +1821 +1822 +1823 +1824 +1825 +1826 +1827 +1828 +1829 +1830 +1831 +1832 +1833 +1834 +1835 +1836 +1837 +1838 +1839 +1840 +1841 +1842 +1843 +1844 +1845 +1846 +1847 +1848 +1849 +1850 +1851 +1852 +1853 +1854 +1855 +1856 +1857 +1858 +1859 +1860 +1861 +1862 +1863 +1864 +1865 +1866 +1867 +1868 +1869 +1870 +1871 +1872 +1873 +1874 +1875 +1876 +1877 +1878 +1879 +1880 +1881 +1882 +1883 +1884 +1885 +1886 +1887 +1888 +1889 +1890 +1891 +1892 +1893 +1894 +1895 +1896 +1897 +1898 +1899 +1900 +1901 +1902 +1903 +1904 +1905 +1906 +1907 +1908 +1909 +1910 +1911 +1912 +1913 +1914 +1915 +1916 +1917 +1918 +1919 +1920 +1921 +1922 +1923 +1924 +1925 +1926 +1927 +1928 +1929 +1930 +1931 +1932 +1933 +1934 +1935 +1936 +1937 +1938 +1939 +1940 +1941 +1942 +1943 +1944 +1945 +1946 +1947 +1948 +1949 +1950 +1951 +1952 +1953 +1954 +1955 +1956 +1957 +1958 +1959 +1960 +1961 +1962 +1963 +1964 +1965 +1966 +1967 +1968 +1969 +1970 +1971 +1972 +1973 +1974 +1975 +1976 +1977 +1978 +1979 +1980 +1981 +1982 +1983 +1984 +1985 +1986 +1987 +1988 +1989 +1990 +1991 +1992 +1993 +1994 +1995 +1996 +1997 +1998 +1999 +2000 +2001 +2002 +2003 +2004 +2005 +2006 +2007 +2008 +2009 +2010 +2011 +2012 +2013 +2014 +2015 +2016 +2017 +2018 +2019 +2020 +2021 +2022 +2023 +2024 +2025 +2026 +2027 +2028 +2029 +2030 +2031 +2032 +2033 +2034 +2035 +2036 +2037 +2038 +2039 +2040 +2041 +2042 +2043 +2044 +2045 +2046 +2047 +2048 +2049 +2050 +2051 +2052 +2053 +2054 +2055 +2056 +2057 +2058 +2059 +2060 +2061 +2062 +2063 +2064 +2065 +2066 +2067 +2068 +2069 +2070 +2071 +2072 +2073 +2074 +2075 +2076 +2077 +2078 +2079 +2080 +2081 +2082 +2083 +2084 +2085 +2086 +2087 +2088 +2089 +2090 +2091 +2092 +2093 +2094 +2095 +2096 +2097 +2098 +2099 +2100 +2101 +2102 +2103 +2104 +2105 +2106 +2107 +2108 +2109 +2110 +2111 +2112 +2113 +2114 +2115 +2116 +2117 +2118 +2119 +2120 +2121 +2122 +2123 +2124 +2125 +2126 +2127 +2128 +2129 +2130 +2131 +2132 +2133 +2134 +2135 +2136 +2137 +2138 +2139 +2140 +2141 +2142 +2143 +2144 +2145 +2146 +2147 +2148 +2149 +2150 +2151 +2152 +2153 +2154 +2155 +2156 +2157 +2158 +2159 +2160 +2161 +2162 +2163 +2164 +2165 +2166 +2167 +2168 +2169 +2170 +2171 +2172 +2173 +2174 +2175 +2176 +2177 +2178 +2179 +2180 +2181 +2182 +2183 +2184 +2185 +2186 +2187 +2188 +2189 +2190 +2191 +2192 +2193 +2194 +2195 +2196 +2197 +2198 +2199 +2200 +2201 +2202 +2203 +2204 +2205 +2206 +2207 +2208 +2209 +2210 +2211 +2212 +2213 +2214 +2215 +2216 +2217 +2218 +2219 +2220 +2221 +2222 +2223 +2224 +2225 +2226 +2227 +2228 +2229 +2230 +2231 +2232 +2233 +2234 +2235 +2236 +2237 +2238 +2239 +2240 +2241 +2242 +2243 +2244 +2245 +2246 +2247 +2248 +2249 +2250 +2251 +2252 +2253 +2254 +2255 +2256 +2257 +2258 +2259 +2260 +2261 +2262 +2263 +2264 +2265 +2266 +2267 +2268 +2269 +2270 +2271 +2272 +2273 +2274 +2275 +2276 +2277 +2278 +2279 +2280 +2281 +2282 +2283 +2284 +2285 +2286 +2287 +2288 +2289 +2290 +2291 +2292 +2293 +2294 +2295 +2296 +2297 +2298 +2299 +2300 +2301 +2302 +2303 +2304 +2305 +2306 +2307 +2308 +2309 +2310 +2311 +2312 +2313 +2314 +2315 +2316 +2317 +2318 +2319 +2320 +2321 +2322 +2323 +2324 +2325 +2326 +2327 +2328 +2329 +2330 +2331 +2332 +2333 +2334 +2335 +2336 +2337 +2338 +2339 +2340 +2341 +2342 +2343 +2344 +2345 +2346 +2347 +2348 +2349 +2350 +2351 +2352 +2353 +2354 +2355 +2356 +2357 +2358 +2359 +2360 +2361 +2362 +2363 +2364 +2365 +2366 +2367 +2368 +2369 +2370 +2371 +2372 +2373 +2374 +2375 +2376 +2377 +2378 +2379 +2380 +2381 +2382 +2383 +2384 +2385 +2386 +2387 +2388 +2389 +2390 +2391 +2392 +2393 +2394 +2395 +2396 +2397 +2398 +2399 +2400 +2401 +2402 +2403 +2404 +2405 +2406 +2407 +2408 +2409 +2410 +2411 +2412 +2413 +2414 +2415 +2416 +2417 +2418 +2419 +2420 +2421 +2422 +2423 +2424 +2425 +2426 +2427 +2428 +2429 +2430 +2431 +2432 +2433 +2434 +2435 +2436 +2437 +2438 +2439 +2440 +2441 +2442 +2443 +2444 +2445 +2446 +2447 +2448 +2449 +2450 +2451 +2452 +2453 +2454 +2455 +2456 +2457 +2458 +2459 +2460 +2461 +2462 +2463 +2464 +2465 +2466 +2467 +2468 +2469 +2470 +2471 +2472 +2473 +2474 +2475 +2476 +2477 +2478 +2479 +2480 +2481 +2482 +2483 +2484 +2485 +2486 +2487 +2488 +2489 +2490 +2491 +2492 +2493 +2494 +2495 +2496 +2497 +2498 +2499 +2500 +2501 +2502 +2503 +2504 +2505 +2506 +2507 +2508 +2509 +2510 +2511 +2512 +2513 +2514 +2515 +2516 +2517 +2518 +2519 +2520 +2521 +2522 +2523 +2524 +2525 +2526 +2527 +2528 +2529 +2530 +2531 +2532 +2533 +2534 +2535 +2536 +2537 +2538 +2539 +2540 +2541 +2542 +2543 +2544 +2545 +2546 +2547 +2548 +2549 +2550 +2551 +2552 +2553 +2554 +2555 +2556 +2557 +2558 +2559 +2560 +2561 +2562 +2563 +2564 +2565 +2566 +2567 +2568 +2569 +2570 +2571 +2572 +2573 +2574 +2575 +2576 +2577 +2578 +2579 +2580 +2581 +2582 +2583 +2584 +2585 +2586 +2587 +2588 +2589 +2590 +2591 +2592 +2593 +2594 +2595 +2596 +2597 +2598 +2599 +2600 +2601 +2602 +2603 +2604 +2605 +2606 +2607 +2608 +2609 +2610 +2611 +2612 +2613 +2614 +2615 +2616 +2617 +2618 +2619 +2620 +2621 +2622 +2623 +2624 +2625 +2626 +2627 +2628 +2629 +2630 +2631 +2632 +2633 +2634 +2635 +2636 +2637 +2638 +2639 +2640 +2641 +2642 +2643 +2644 +2645 +2646 +2647 +2648 +2649 +2650 +2651 +2652 +2653 +2654 +2655 +2656 +2657 +2658 +2659 +2660 +2661 +2662 +2663 +2664 +2665 +2666 +2667 +2668 +2669 +2670 +2671 +2672 +2673 +2674 +2675 +2676 +2677 +2678 +2679 +2680 +2681 +2682 +2683 +2684 +2685 +2686 +2687 +2688 +2689 +2690 +2691 +2692 +2693 +2694 +2695 +2696 +2697 +2698 +2699 +2700 +2701 +2702 +2703 +2704 +2705 +2706 +2707 +2708 +2709 +2710 +2711 +2712 +2713 +2714 +2715 +2716 +2717 +2718 +2719 +2720 +2721 +2722 +2723 +2724 +2725 +2726 +2727 +2728 +2729 +2730 +2731 +2732 +2733 +2734 +2735 +2736 +2737 +2738 +2739 +2740 +2741 +2742 +2743 +2744 +2745 +2746 +2747 +2748 +2749 +2750 +2751 +2752 +2753 +2754 +2755 +2756 +2757 +2758 +2759 +2760 +2761 +2762 +2763 +2764 +2765 +2766 +2767 +2768 +2769 +2770 +2771 +2772 +2773 +2774 +2775 +2776 +2777 +2778 +2779 +2780 +2781 +2782 +2783 +2784 +2785 +2786 +2787 +2788 +2789 +2790 +2791 +2792 +2793 +2794 +2795 +2796 +2797 +2798 +2799 +2800 +2801 +2802 +2803 +2804 +2805 +2806 +2807 +2808 +2809 +2810 +2811 +2812 +2813 +2814 +2815 +2816 +2817 +2818 +2819 +2820 +2821 +2822 +2823 +2824 +2825 +2826 +2827 +2828 +2829 +2830 +2831 +2832 +2833 +2834 +2835 +2836 +2837 +2838 +2839 +2840 +2841 +2842 +2843 +2844 +2845 +2846 +2847 +2848 +2849 +2850 +2851 +2852 +2853 +2854 +2855 +2856 +2857 +2858 +2859 +2860 +2861 +2862 +2863 +2864 +2865 +2866 +2867 +2868 +2869 +2870 +2871 +2872 +2873 +2874 +2875 +2876 +2877 +2878 +2879 +2880 +2881 +2882 +2883 +2884 +2885 +2886 +2887 +2888 +2889 +2890 +2891 +2892 +2893 +2894 +2895 +2896 +2897 +2898 +2899 +2900 +2901 +2902 +2903 +2904 +2905 +2906 +2907 +2908 +2909 +2910 +2911 +2912 +2913 +2914 +2915 +2916 +2917 +2918 +2919 +2920 +2921 +2922 +2923 +2924 +2925 +2926 +2927 +2928 +2929 +2930 +2931 +2932 +2933 +2934 +2935 +2936 +2937 +2938 +2939 +2940 +2941 +2942 +2943 +2944 +2945 +2946 +2947 +2948 +2949 +2950 +2951 +2952 +2953 +2954 +2955 +2956 +2957 +2958 +2959 +2960 +2961 +2962 +2963 +2964 +2965 +2966 +2967 +2968 +2969 +2970 +2971 +2972 +2973 +2974 +2975 +2976 +2977 +2978 +2979 +2980 +2981 +2982 +2983 +2984 +2985 +2986 +2987 +2988 +2989 +2990 +2991 +2992 +2993 +2994 +2995 +2996 +2997 +2998 +2999 +3000 +3001 +3002 +3003 +3004 +3005 +3006 +3007 +3008 +3009 +3010 +3011 +3012 +3013 +3014 +3015 +3016 +3017 +3018 +3019 +3020 +3021 +3022 +3023 +3024 +3025 +3026 +3027 +3028 +3029 +3030 +3031 +3032 +3033 +3034 +3035 +3036 +3037 +3038 +3039 +3040 +3041 +3042 +3043 +3044 +3045 +3046 +3047 +3048 +3049 +3050 +3051 +3052 +3053 +3054 +3055 +3056 +3057 +3058 +3059 +3060 +3061 +3062 +3063 +3064 +3065 +3066 +3067 +3068 +3069 +3070 +3071 +3072 +3073 +3074 +3075 +3076 +3077 +3078 +3079 +3080 +3081 +3082 +3083 +3084 +3085 +3086 +3087 +3088 +3089 +3090 +3091 +3092 +3093 +3094 +3095 +3096 +3097 +3098 +3099 +3100 +3101 +3102 +3103 +3104 +3105 +3106 +3107 +3108 +3109 +3110 +3111 +3112 +3113 +3114 +3115 +3116 +3117 +3118 +3119 +3120 +3121 +3122 +3123 +3124 +3125 +3126 +3127 +3128 +3129 +3130 +3131 +3132 +3133 +3134 +3135 +3136 +3137 +3138 +3139 +3140 +3141 +3142 +3143 +3144 +3145 +3146 +3147 +3148 +3149 +3150 +3151 +3152 +3153 +3154 +3155 +3156 +3157 +3158 +3159 +3160 +3161 +3162 +3163 +3164 +3165 +3166 +3167 +3168 +3169 +3170 +3171 +3172 +3173 +3174 +3175 +3176 +3177 +3178 +3179 +3180 +3181 +3182 +3183 +3184 +3185 +3186 +3187 +3188 +3189 +3190 +3191 +3192 +3193 +3194 +3195 +3196 +3197 +3198 +3199 +3200 +3201 +3202 +3203 +3204 +3205 +3206 +3207 +3208 +3209 +3210 +3211 +3212 +3213 +3214 +3215 +3216 +3217 +3218 +3219 +3220 +3221 +3222 +3223 +3224 +3225 +3226 +3227 +3228 +3229 +3230 +3231 +3232 +3233 +3234 +3235 +3236 +3237 +3238 +3239 +3240 +3241 +3242 +3243 +3244 +3245 +3246 +3247 +3248 +3249 +3250 +3251 +3252 +3253 +3254 +3255 +3256 +3257 +3258 +3259 +3260 +3261 +3262 +3263 +3264 +3265 +3266 +3267 +3268 +3269 +3270 +3271 +3272 +3273 +3274 +3275 +3276 +3277 +3278 +3279 +3280 +3281 +3282 +3283 +3284 +3285 +3286 +3287 +3288 +3289 +3290 +3291 +3292 +3293 +3294 +3295 +3296 +3297 +3298 +3299 +3300 +3301 +3302 +3303 +3304 +3305 +3306 +3307 +3308 +3309 +3310 +3311 +3312 +3313 +3314 +3315 +3316 +3317 +3318 +3319 +3320 +3321 +3322 +3323 +3324 +3325 +3326 +3327 +3328 +3329 +3330 +3331 +3332 +3333 +3334 +3335 +3336 +3337 +3338 +3339 +3340 +3341 +3342 +3343 +3344 +3345 +3346 +3347 +3348 +3349 +3350 +3351 +3352 +3353 +3354 +3355 +3356 +3357 +3358 +3359 +3360 +3361 +3362 +3363 +3364 +3365 +3366 +3367 +3368 +3369 +3370 +3371 +3372 +3373 +3374 +3375 +3376 +3377 +3378 +3379 +3380 +3381 +3382 +3383 +3384 +3385 +3386 +3387 +3388 +3389 +3390 +3391 +3392 +3393 +3394 +3395 +3396 +3397 +3398 +3399 +3400 +3401 +3402 +3403 +3404 +3405 +3406 +3407 +3408 +3409 +3410 +3411 +3412 +3413 +3414 +3415 +3416 +3417 +3418 +3419 +3420 +3421 +3422 +3423 +3424 +3425 +3426 +3427 +3428 +3429 +3430 +3431 +3432 +3433 +3434 +3435 +3436 +3437 +3438 +3439 +3440 +3441 +3442 +3443 +3444 +3445 +3446 +3447 +3448 +3449 +3450 +3451 +3452 +3453 +3454 +3455 +3456 +3457 +3458 +3459 +3460 +3461 +3462 +3463 +3464 +3465 +3466 +3467 +3468 +3469 +3470 +3471 +3472 +3473 +3474 +3475 +3476 +3477 +3478 +3479 +3480 +3481 +3482 +3483 +3484 +3485 +3486 +3487 +3488 +3489 +3490 +3491 +3492 +3493 +3494 +3495 +3496 +3497 +3498 +3499 +3500 +3501 +3502 +3503 +3504 +3505 +3506 +3507 +3508 +3509 +3510 +3511 +3512 +3513 +3514 +3515 +3516 +3517 +3518 +3519 +3520 +3521 +3522 +3523 +3524 +3525 +3526 +3527 +3528 +3529 +3530 +3531 +3532 +3533 +3534 +3535 +3536 +3537 +3538 +3539 +3540 +3541 +3542 +3543 +3544 +3545 +3546 +3547 +3548 +3549 +3550 +3551 +3552 +3553 +3554 +3555 +3556 +3557 +3558 +3559 +3560 +3561 +3562 +3563 +3564 +3565 +3566 +3567 +3568 +3569 +3570 +3571 +3572 +3573 +3574 +3575 +3576 +3577 +3578 +3579 +3580 +3581 +3582 +3583 +3584 +3585 +3586 +3587 +3588 +3589 +3590 +3591 +3592 +3593 +3594 +3595 +3596 +3597 +3598 +3599 +3600 +3601 +3602 +3603 +3604 +3605 +3606 +3607 +3608 +3609 +3610 +3611 +3612 +3613 +3614 +3615 +3616 +3617 +3618 +3619 +3620 +3621 +3622 +3623 +3624 +3625 +3626 +3627 +3628 +3629 +3630 +3631 +3632 +3633 +3634 +3635 +3636 +3637 +3638 +3639 +3640 +3641 +3642 +3643 +3644 +3645 +3646 +3647 +3648 +3649 +3650 +3651 +3652 +3653 +3654 +3655 +3656 +3657 +3658 +3659 +3660 +3661 +3662 +3663 +3664 +3665 +3666 +3667 +3668 +3669 +3670 +3671 +3672 +3673 +3674 +3675 +3676 +3677 +3678 +3679 +3680 +3681 +3682 +3683 +3684 +3685 +3686 +3687 +3688 +3689 +3690 +3691 +3692 +3693 +3694 +3695 +3696 +3697 +3698 +3699 +3700 +3701 +3702 +3703 +3704 +3705 +3706 +3707 +3708 +3709 +3710 +3711 +3712 +3713 +3714 +3715 +3716 +3717 +3718 +3719 +3720 +3721 +3722 +3723 +3724 +3725 +3726 +3727 +3728 +3729 +3730 +3731 +3732 +3733 +3734 +3735 +3736 +3737 +3738 +3739 +3740 +3741 +3742 +3743 +3744 +3745 +3746 +3747 +3748 +3749 +3750 +3751 +3752 +3753 +3754 +3755 +3756 +3757 +3758 +3759 +3760 +3761 +3762 +3763 +3764 +3765 +3766 +3767 +3768 +3769 +3770 +3771 +3772 +3773 +3774 +3775 +3776 +3777 +3778 +3779 +3780 +3781 +3782 +3783 +3784 +3785 +3786 +3787 +3788 +3789 +3790 +3791 +3792 +3793 +3794 +3795 +3796 +3797 +3798 +3799 +3800 +3801 +3802 +3803 +3804 +3805 +3806 +3807 +3808 +3809 +3810 +3811 +3812 +3813 +3814 +3815 +3816 +3817 +3818 +3819 +3820 +3821 +3822 +3823 +3824 +3825 +3826 +3827 +3828 +3829 +3830 +3831 +3832 +3833 +3834 +3835 +3836 +3837 +3838 +3839 +3840 +3841 +3842 +3843 +3844 +3845 +3846 +3847 +3848 +3849 +3850 +3851 +3852 +3853 +3854 +3855 +3856 +3857 +3858 +3859 +3860 +3861 +3862 +3863 +3864 +3865 +3866 +3867 +3868 +3869 +3870 +3871 +3872 +3873 +3874 +3875 +3876 +3877 +3878 +3879 +3880 +3881 +3882 +3883 +3884 +3885 +3886 +3887 +3888 +3889 +3890 +3891 +3892 +3893 +3894 +3895 +3896 +3897 +3898 +3899 +3900 +3901 +3902 +3903 +3904 +3905 +3906 +3907 +3908 +3909 +3910 +3911 +3912 +3913 +3914 +3915 +3916 +3917 +3918 +3919 +3920 +3921 +3922 +3923 +3924 +3925 +3926 +3927 +3928 +3929 +3930 +3931 +3932 +3933 +3934 +3935 +3936 +3937 +3938 +3939 +3940 +3941 +3942 +3943 +3944 +3945 +3946 +3947 +3948 +3949 +3950 +3951 +3952 +3953 +3954 +3955 +3956 +3957 +3958 +3959 +3960 +3961 +3962 +3963 +3964 +3965 +3966 +3967 +3968 +3969 +3970 +3971 +3972 +3973 +3974 +3975 +3976 +3977 +3978 +3979 +3980 +3981 +3982 +3983 +3984 +3985 +3986 +3987 +3988 +3989 +3990 +3991 +3992 +3993 +3994 +3995 +3996 +3997 +3998 +3999 +4000 +4001 +4002 +4003 +4004 +4005 +4006 +4007 +4008 +4009 +4010 +4011 +4012 +4013 +4014 +4015 +4016 +4017 +4018 +4019 +4020 +4021 +4022 +4023 +4024 +4025 +4026 +4027 +4028 +4029 +4030 +4031 +4032 +4033 +4034 +4035 +4036 +4037 +4038 +4039 +4040 +4041 +4042 +4043 +4044 +4045 +4046 +4047 +4048 +4049 +4050 +4051 +4052 +4053 +4054 +4055 +4056 +4057 +4058 +4059 +4060 +4061 +4062 +4063 +4064 +4065 +4066 +4067 +4068 +4069 +4070 +4071 +4072 +4073 +4074 +4075 +4076 +4077 +4078 +4079 +4080 +4081 +4082 +4083 +4084 +4085 +4086 +4087 +4088 +4089 +4090 +4091 +4092 +4093 +4094 +4095 +4096 +4097 +4098 +4099 +4100 +4101 +4102 +4103 +4104 +4105 +4106 +4107 +4108 +4109 +4110 +4111 +4112 +4113 +4114 +4115 +4116 +4117 +4118 +4119 +4120 +4121 +4122 +4123 +4124 +4125 +4126 +4127 +4128 +4129 +4130 +4131 +4132 +4133 +4134 +4135 +4136 +4137 +4138 +4139 +4140 +4141 +4142 +4143 +4144 +4145 +4146 +4147 +4148 +4149 +4150 +4151 +4152 +4153 +4154 +4155 +4156 +4157 +4158 +4159 +4160 +4161 +4162 +4163 +4164 +4165 +4166 +4167 +4168 +4169 +4170 +4171 +4172 +4173 +4174 +4175 +4176 +4177 +4178 +4179 +4180 +4181 +4182 +4183 +4184 +4185 +4186 +4187 +4188 +4189 +4190 +4191 +4192 +4193 +4194 +4195 +4196 +4197 +4198 +4199 +4200 +4201 +4202 +4203 +4204 +4205 +4206 +4207 +4208 +4209 +4210 +4211 +4212 +4213 +4214 +4215 +4216 +4217 +4218 +4219 +4220 +4221 +4222 +4223 +4224 +4225 +4226 +4227 +4228 +4229 +4230 +4231 +4232 +4233 +4234 +4235 +4236 +4237 +4238 +4239 +4240 +4241 +4242 +4243 +4244 +4245 +4246 +4247 +4248 +4249 +4250 +4251 +4252 +4253 +4254 +4255 +4256 +4257 +4258 +4259 +4260 +4261 +4262 +4263 +4264 +4265 +4266 +4267 +4268 +4269 +4270 +4271 +4272 +4273 +4274 +4275 +4276 +4277 +4278 +4279 +4280 +4281 +4282 +4283 +4284 +4285 +4286 +4287 +4288 +4289 +4290 +4291 +4292 +4293 +4294 +4295 +4296 +4297 +4298 +4299 +4300 +4301 +4302 +4303 +4304 +4305 +4306 +4307 +4308 +4309 +4310 +4311 +4312 +4313 +4314 +4315 +4316 +4317 +4318 +4319 +4320 +4321 +4322 +4323 +4324 +4325 +4326 +4327 +4328 +4329 +4330 +4331 +4332 +4333 +4334 +4335 +4336 +4337 +4338 +4339 +4340 +4341 +4342 +4343 +4344 +4345 +4346 +4347 +4348 +4349 +4350 +4351 +4352 +4353 +4354 +4355 +4356 +4357 +4358 +4359 +4360 +4361 +4362 +4363 +4364 +4365 +4366 +4367 +4368 +4369 +4370 +4371 +4372 +4373 +4374 +4375 +4376 +4377 +4378 +4379 +4380 +4381 +4382 +4383 +4384 +4385 +4386 +4387 +4388 +4389 +4390 +4391 +4392 +4393 +4394 +4395 +4396 +4397 +4398 +4399 +4400 +4401 +4402 +4403 +4404 +4405 +4406 +4407 +4408 +4409 +4410 +4411 +4412 +4413 +4414 +4415 +4416 +4417 +4418 +4419 +4420 +4421 +4422 +4423 +4424 +4425 +4426 +4427 +4428 +4429 +4430 +4431 +4432 +4433 +4434 +4435 +4436 +4437 +4438 +4439 +4440 +4441 +4442 +4443 +4444 +4445 +4446 +4447 +4448 +4449 +4450 +4451 +4452 +4453 +4454 +4455 +4456 +4457 +4458 +4459 +4460 +4461 +4462 +4463 +4464 +4465 +4466 +4467 +4468 +4469 +4470 +4471 +4472 +4473 +4474 +4475 +4476 +4477 +4478 +4479 +4480 +4481 +4482 +4483 +4484 +4485 +4486 +4487 +4488 +4489 +4490 +4491 +4492 +4493 +4494 +4495 +4496 +4497 +4498 +4499 +4500 +4501 +4502 +4503 +4504 +4505 +4506 +4507 +4508 +4509 +4510 +4511 +4512 +4513 +4514 +4515 +4516 +4517 +4518 +4519 +4520 +4521 +4522 +4523 +4524 +4525 +4526 +4527 +4528 +4529 +4530 +4531 +4532 +4533 +4534 +4535 +4536 +4537 +4538 +4539 +4540 +4541 +4542 +4543 +4544 +4545 +4546 +4547 +4548 +4549 +4550 +4551 +4552 +4553 +4554 +4555 +4556 +4557 +4558 +4559 +4560 +4561 +4562 +4563 +4564 +4565 +4566 +4567 +4568 +4569 +4570 +4571 +4572 +4573 +4574 +4575 +4576 +4577 +4578 +4579 +4580 +4581 +4582 +4583 +4584 +4585 +4586 +4587 +4588 +4589 +4590 +4591 +4592 +4593 +4594 +4595 +4596 +4597 +4598 +4599 +4600 +4601 +4602 +4603 +4604 +4605 +4606 +4607 +4608 +4609 +4610 +4611 +4612 +4613 +4614 +4615 +4616 +4617 +4618 +4619 +4620 +4621 +4622 +4623 +4624 +4625 +4626 +4627 +4628 +4629 +4630 +4631 +4632 +4633 +4634 +4635 +4636 +4637 +4638 +4639 +4640 +4641 +4642 +4643 +4644 +4645 +4646 +4647 +4648 +4649 +4650 +4651 +4652 +4653 +4654 +4655 +4656 +4657 +4658 +4659 +4660 +4661 +4662 +4663 +4664 +4665 +4666 +4667 +4668 +4669 +4670 +4671 +4672 +4673 +4674 +4675 +4676 +4677 +4678 +4679 +4680 +4681 +4682 +4683 +4684 +4685 +4686 +4687 +4688 +4689 +4690 +4691 +4692 +4693 +4694 +4695 +4696 +4697 +4698 +4699 +4700 +4701 +4702 +4703 +4704 +4705 +4706 +4707 +4708 +4709 +4710 +4711 +4712 +4713 +4714 +4715 +4716 +4717 +4718 +4719 +4720 +4721 +4722 +4723 +4724 +4725 +4726 +4727 +4728 +4729 +4730 +4731 +4732 +4733 +4734 +4735 +4736 +4737 +4738 +4739 +4740 +4741 +4742 +4743 +4744 +4745 +4746 +4747 +4748 +4749 +4750 +4751 +4752 +4753 +4754 +4755 +4756 +4757 +4758 +4759 +4760 +4761 +4762 +4763 +4764 +4765 +4766 +4767 +4768 +4769 +4770 +4771 +4772 +4773 +4774 +4775 +4776 +4777 +4778 +4779 +4780 +4781 +4782 +4783 +4784 +4785 +4786 +4787 +4788 +4789 +4790 +4791 +4792 +4793 +4794 +4795 +4796 +4797 +4798 +4799 +4800 +4801 +4802 +4803 +4804 +4805 +4806 +4807 +4808 +4809 +4810 +4811 +4812 +4813 +4814 +4815 +4816 +4817 +4818 +4819 +4820 +4821 +4822 +4823 +4824 +4825 +4826 +4827 +4828 +4829 +4830 +4831 +4832 +4833 +4834 +4835 +4836 +4837 +4838 +4839 +4840 +4841 +4842 +4843 +4844 +4845 +4846 +4847 +4848 +4849 +4850 +4851 +4852 +4853 +4854 +4855 +4856 +4857 +4858 +4859 +4860 +4861 +4862 +4863 +4864 +4865 +4866 +4867 +4868 +4869 +4870 +4871 +4872 +4873 +4874 +4875 +4876 +4877 +4878 +4879 +4880 +4881 +4882 +4883 +4884 +4885 +4886 +4887 +4888 +4889 +4890 +4891 +4892 +4893 +4894 +4895 +4896 +4897 +4898 +4899 +4900 +4901 +4902 +4903 +4904 +4905 +4906 +4907 +4908 +4909 +4910 +4911 +4912 +4913 +4914 +4915 +4916 +4917 +4918 +4919 +4920 +4921 +4922 +4923 +4924 +4925 +4926 +4927 +4928 +4929 +4930 +4931 +4932 +4933 +4934 +4935 +4936 +4937 +4938 +4939 +4940 +4941 +4942 +4943 +4944 +4945 +4946 +4947 +4948 +4949 +4950 +4951 +4952 +4953 +4954 +4955 +4956 +4957 +4958 +4959 +4960 +4961 +4962 +4963 +4964 +4965 +4966 +4967 +4968 +4969 +4970 +4971 +4972 +4973 +4974 +4975 +4976 +4977 +4978 +4979 +4980 +4981 +4982 +4983 +4984 +4985 +4986 +4987 +4988 +4989 +4990 +4991 +4992 +4993 +4994 +4995 +4996 +4997 +4998 +4999 +5000 +5001 +5002 +5003 +5004 +5005 +5006 +5007 +5008 +5009 +5010 +5011 +5012 +5013 +5014 +5015 +5016 +5017 +5018 +5019 +5020 +5021 +5022 +5023 +5024 +5025 +5026 +5027 +5028 +5029 +5030 +5031 +5032 +5033 +5034 +5035 +5036 +5037 +5038 +5039 +5040 +5041 +5042 +5043 +5044 +5045 +5046 +5047 +5048 +5049 +5050 +5051 +5052 +5053 +5054 +5055 +5056 +5057 +5058 +5059 +5060 +5061 +5062 +5063 +5064 +5065 +5066 +5067 +5068 +5069 +5070 +5071 +5072 +5073 +5074 +5075 +5076 +5077 +5078 +5079 +5080 +5081 +5082 +5083 +5084 +5085 +5086 +5087 +5088 +5089 +5090 +5091 +5092 +5093 +5094 +5095 +5096 +5097 +5098 +5099 +5100 +5101 +5102 +5103 +5104 +5105 +5106 +5107 +5108 +5109 +5110 +5111 +5112 +5113 +5114 +5115 +5116 +5117 +5118 +5119 +5120 +5121 +5122 +5123 +5124 +5125 +5126 +5127 +5128 +5129 +5130 +5131 +5132 +5133 +5134 +5135 +5136 +5137 +5138 +5139 +5140 +5141 +5142 +5143 +5144 +5145 +5146 +5147 +5148 +5149 +5150 +5151 +5152 +5153 +5154 +5155 +5156 +5157 +5158 +5159 +5160 +5161 +5162 +5163 +5164 +5165 +5166 +5167 +5168 +5169 +5170 +5171 +5172 +5173 +5174 +5175 +5176 +5177 +5178 +5179 +5180 +5181 +5182 +5183 +5184 +5185 +5186 +5187 +5188 +5189 +5190 +5191 +5192 +5193 +5194 +5195 +5196 +5197 +5198 +5199 +5200 +5201 +5202 +5203 +5204 +5205 +5206 +5207 +5208 +5209 +5210 +5211 +5212 +5213 +5214 +5215 +5216 +5217 +5218 +5219 +5220 +5221 +5222 +5223 +5224 +5225 +5226 +5227 +5228 +5229 +5230 +5231 +5232 +5233 +5234 +5235 +5236 +5237 +5238 +5239 +5240 +5241 +5242 +5243 +5244 +5245 +5246 +5247 +5248 +5249 +5250 +5251 +5252 +5253 +5254 +5255 +5256 +5257 +5258 +5259 +5260 +5261 +5262 +5263 +5264 +5265 +5266 +5267 +5268 +5269 +5270 +5271 +5272 +5273 +5274 +5275 +5276 +5277 +5278 +5279 +5280 +5281 +5282 +5283 +5284 +5285 +5286 +5287 +5288 +5289 +5290 +5291 +5292 +5293 +5294 +5295 +5296 +5297 +5298 +5299 +5300 +5301 +5302 +5303 +5304 +5305 +5306 +5307 +5308 +5309 +5310 +5311 +5312 +5313 +5314 +5315 +5316 +5317 +5318 +5319 +5320 +5321 +5322 +5323 +5324 +5325 +5326 +5327 +5328 +5329 +5330 +5331 +5332 +5333 +5334 +5335 +5336 +5337 +5338 +5339 +5340 +5341 +5342 +5343 +5344 +5345 +5346 +5347 +5348 +5349 +5350 +5351 +5352 +5353 +5354 +5355 +5356 +5357 +5358 +5359 +5360 +5361 +5362 +5363 +5364 +5365 +5366 +5367 +5368 +5369 +5370 +5371 +5372 +5373 +5374 +5375 +5376 +5377 +5378 +5379 +5380 +5381 +5382 +5383 +5384 +5385 +5386 +5387 +5388 +5389 +5390 +5391 +5392 +5393 +5394 +5395 +5396 +5397 +5398 +5399 +5400 +5401 +5402 +5403 +5404 +5405 +5406 +5407 +5408 +5409 +5410 +5411 +5412 +5413 +5414 +5415 +5416 +5417 +5418 +5419 +5420 +5421 +5422 +5423 +5424 +5425 +5426 +5427 +5428 +5429 +5430 +5431 +5432 +5433 +5434 +5435 +5436 +5437 +5438 +5439 +5440 +5441 +5442 +5443 +5444 +5445 +5446 +5447 +5448 +5449 +5450 +5451 +5452 +5453 +5454 +5455 +5456 +5457 +5458 +5459 +5460 +5461 +5462 +5463 +5464 +5465 +5466 +5467 +5468 +5469 +5470 +5471 +5472 +5473 +5474 +5475 +5476 +5477 +5478 +5479 +5480 +5481 +5482 +5483 +5484 +5485 +5486 +5487 +5488 +5489 +5490 +5491 +5492 +5493 +5494 +5495 +5496 +5497 +5498 +5499 +5500 +5501 +5502 +5503 +5504 +5505 +5506 +5507 +5508 +5509 +5510 +5511 +5512 +5513 +5514 +5515 +5516 +5517 +5518 +5519 +5520 +5521 +5522 +5523 +5524 +5525 +5526 +5527 +5528 +5529 +5530 +5531 +5532 +5533 +5534 +5535 +5536 +5537 +5538 +5539 +5540 +5541 +5542 +5543 +5544 +5545 +5546 +5547 +5548 +5549 +5550 +5551 +5552 +5553 +5554 +5555 +5556 +5557 +5558 +5559 +5560 +5561 +5562 +5563 +5564 +5565 +5566 +5567 +5568 +5569 +5570 +5571 +5572 +5573 +5574 +5575 +5576 +5577 +5578 +5579 +5580 +5581 +5582 +5583 +5584 +5585 +5586 +5587 +5588 +5589 +5590 +5591 +5592 +5593 +5594 +5595 +5596 +5597 +5598 +5599 +5600 +5601 +5602 +5603 +5604 +5605 +5606 +5607 +5608 +5609 +5610 +5611 +5612 +5613 +5614 +5615 +5616 +5617 +5618 +5619 +5620 +5621 +5622 +5623 +5624 +5625 +5626 +5627 +5628 +5629 +5630 +5631 +5632 +5633 +5634 +5635 +5636 +5637 +5638 +5639 +5640 +5641 +5642 +5643 +5644 +5645 +5646 +5647 +5648 +5649 +5650 +5651 +5652 +5653 +5654 +5655 +5656 +5657 +5658 +5659 +5660 +5661 +5662 +5663 +5664 +5665 +5666 +5667 +5668 +5669 +5670 +5671 +5672 +5673 +5674 +5675 +5676 +5677 +5678 +5679 +5680 +5681 +5682 +5683 +5684 +5685 +5686 +5687 +5688 +5689 +5690 +5691 +5692 +5693 +5694 +5695 +5696 +5697 +5698 +5699 +5700 +5701 +5702 +5703 +5704 +5705 +5706 +5707 +5708 +5709 +5710 +5711 +5712 +5713 +5714 +5715 +5716 +5717 +5718 +5719 +5720 +5721 +5722 +5723 +5724 +5725 +5726 +5727 +5728 +5729 +5730 +5731 +5732 +5733 +5734 +5735 +5736 +5737 +5738 +5739 +5740 +5741 +5742 +5743 +5744 +5745 +5746 +5747 +5748 +5749 +5750 +5751 +5752 +5753 +5754 +5755 +5756 +5757 +5758 +5759 +5760 +5761 +5762 +5763 +5764 +5765 +5766 +5767 +5768 +5769 +5770 +5771 +5772 +5773 +5774 +5775 +5776 +5777 +5778 +5779 +5780 +5781 +5782 +5783 +5784 +5785 +5786 +5787 +5788 +5789 +5790 +5791 +5792 +5793 +5794 +5795 +5796 +5797 +5798 +5799 +5800 +5801 +5802 +5803 +5804 +5805 +5806 +5807 +5808 +5809 +5810 +5811 +5812 +5813 +5814 +5815 +5816 +5817 +5818 +5819 +5820 +5821 +5822 +5823 +5824 +5825 +5826 +5827 +5828 +5829 +5830 +5831 +5832 +5833 +5834 +5835 +5836 +5837 +5838 +5839 +5840 +5841 +5842 +5843 +5844 +5845 +5846 +5847 +5848 +5849 +5850 +5851 +5852 +5853 +5854 +5855 +5856 +5857 +5858 +5859 +5860 +5861 +5862 +5863 +5864 +5865 +5866 +5867 +5868 +5869 +5870 +5871 +5872 +5873 +5874 +5875 +5876 +5877 +5878 +5879 +5880 +5881 +5882 +5883 +5884 +5885 +5886 +5887 +5888 +5889 +5890 +5891 +5892 +5893 +5894 +5895 +5896 +5897 +5898 +5899 +5900 +5901 +5902 +5903 +5904 +5905 +5906 +5907 +5908 +5909 +5910 +5911 +5912 +5913 +5914 +5915 +5916 +5917 +5918 +5919 +5920 +5921 +5922 +5923 +5924 +5925 +5926 +5927 +5928 +5929 +5930 +5931 +5932 +5933 +5934 +5935 +5936 +5937 +5938 +5939 +5940 +5941 +5942 +5943 +5944 +5945 +5946 +5947 +5948 +5949 +5950 +5951 +5952 +5953 +5954 +5955 +5956 +5957 +5958 +5959 +5960 +5961 +5962 +5963 +5964 +5965 +5966 +5967 +5968 +5969 +5970 +5971 +5972 +5973 +5974 +5975 +5976 +5977 +5978 +5979 +5980 +5981 +5982 +5983 +5984 +5985 +5986 +5987 +5988 +5989 +5990 +5991 +5992 +5993 +5994 +5995 +5996 +5997 +5998 +5999 +6000 +6001 +6002 +6003 +6004 +6005 +6006 +6007 +6008 +6009 +6010 +6011 +6012 +6013 +6014 +6015 +6016 +6017 +6018 +6019 +6020 +6021 +6022 +6023 +6024 +6025 +6026 +6027 +6028 +6029 +6030 +6031 +6032 +6033 +6034 +6035 +6036 +6037 +6038 +6039 +6040 +6041 +6042 +6043 +6044 +6045 +6046 +6047 +6048 +6049 +6050 +6051 +6052 +6053 +6054 +6055 +6056 +6057 +6058 +6059 +6060 +6061 +6062 +6063 +6064 +6065 +6066 +6067 +6068 +6069 +6070 +6071 +6072 +6073 +6074 +6075 +6076 +6077 +6078 +6079 +6080 +6081 +6082 +6083 +6084 +6085 +6086 +6087 +6088 +6089 +6090 +6091 +6092 +6093 +6094 +6095 +6096 +6097 +6098 +6099 +6100 +6101 +6102 +6103 +6104 +6105 +6106 +6107 +6108 +6109 +6110 +6111 +6112 +6113 +6114 +6115 +6116 +6117 +6118 +6119 +6120 +6121 +6122 +6123 +6124 +6125 +6126 +6127 +6128 +6129 +6130 +6131 +6132 +6133 +6134 +6135 +6136 +6137 +6138 +6139 +6140 +6141 +6142 +6143 +6144 +6145 +6146 +6147 +6148 +6149 +6150 +6151 +6152 +6153 +6154 +6155 +6156 +6157 +6158 +6159 +6160 +6161 +6162 +6163 +6164 +6165 +6166 +6167 +6168 +6169 +6170 +6171 +6172 +6173 +6174 +6175 +6176 +6177 +6178 +6179 +6180 +6181 +6182 +6183 +6184 +6185 +6186 +6187 +6188 +6189 +6190 +6191 +6192 +6193 +6194 +6195 +6196 +6197 +6198 +6199 +6200 +6201 +6202 +6203 +6204 +6205 +6206 +6207 +6208 +6209 +6210 +6211 +6212 +6213 +6214 +6215 +6216 +6217 +6218 +6219 +6220 +6221 +6222 +6223 +6224 +6225 +6226 +6227 +6228 +6229 +6230 +6231 +6232 +6233 +6234 +6235 +6236 +6237 +6238 +6239 +6240 +6241 +6242 +6243 +6244 +6245 +6246 +6247 +6248 +6249 +6250 +6251 +6252 +6253 +6254 +6255 +6256 +6257 +6258 +6259 +6260 +6261 +6262 +6263 +6264 +6265 +6266 +6267 +6268 +6269 +6270 +6271 +6272 +6273 +6274 +6275 +6276 +6277 +6278 +6279 +6280 +6281 +6282 +6283 +6284 +6285 +6286 +6287 +6288 +6289 +6290 +6291 +6292 +6293 +6294 +6295 +6296 +6297 +6298 +6299 +6300 +6301 +6302 +6303 +6304 +6305 +6306 +6307 +6308 +6309 +6310 +6311 +6312 +6313 +6314 +6315 +6316 +6317 +6318 +6319 +6320 +6321 +6322 +6323 +6324 +6325 +6326 +6327 +6328 +6329 +6330 +6331 +6332 +6333 +6334 +6335 +6336 +6337 +6338 +6339 +6340 +6341 +6342 +6343 +6344 +6345 +6346 +6347 +6348 +6349 +6350 +6351 +6352 +6353 +6354 +6355 +6356 +6357 +6358 +6359 +6360 +6361 +6362 +6363 +6364 +6365 +6366 +6367 +6368 +6369 +6370 +6371 +6372 +6373 +6374 +6375 +6376 +6377 +6378 +6379 +6380 +6381 +6382 +6383 +6384 +6385 +6386 +6387 +6388 +6389 +6390 +6391 +6392 +6393 +6394 +6395 +6396 +6397 +6398 +6399 +6400 +6401 +6402 +6403 +6404 +6405 +6406 +6407 +6408 +6409 +6410 +6411 +6412 +6413 +6414 +6415 +6416 +6417 +6418 +6419 +6420 +6421 +6422 +6423 +6424 +6425 +6426 +6427 +6428 +6429 +6430 +6431 +6432 +6433 +6434 +6435 +6436 +6437 +6438 +6439 +6440 +6441 +6442 +6443 +6444 +6445 +6446 +6447 +6448 +6449 +6450 +6451 +6452 +6453 +6454 +6455 +6456 +6457 +6458 +6459 +6460 +6461 +6462 +6463 +6464 +6465 +6466 +6467 +6468 +6469 +6470 +6471 +6472 +6473 +6474 +6475 +6476 +6477 +6478 +6479 +6480 +6481 +6482 +6483 +6484 +6485 +6486 +6487 +6488 +6489 +6490 +6491 +6492 +6493 +6494 +6495 +6496 +6497 +6498 +6499 +6500 +6501 +6502 +6503 +6504 +6505 +6506 +6507 +6508 +6509 +6510 +6511 +6512 +6513 +6514 +6515 +6516 +6517 +6518 +6519 +6520 +6521 +6522 +6523 +6524 +6525 +6526 +6527 +6528 +6529 +6530 +6531 +6532 +6533 +6534 +6535 +6536 +6537 +6538 +6539 +6540 +6541 +6542 +6543 +6544 +6545 +6546 +6547 +6548 +6549 +6550 +6551 +6552 +6553 +6554 +6555 +6556 +6557 +6558 +6559 +6560 +6561 +6562 +6563 +6564 +6565 +6566 +6567 +6568 +6569 +6570 +6571 +6572 +6573 +6574 +6575 +6576 +6577 +6578 +6579 +6580 +6581 +6582 +6583 +6584 +6585 +6586 +6587 +6588 +6589 +6590 +6591 +6592 +6593 +6594 +6595 +6596 +6597 +6598 +6599 +6600 +6601 +6602 +6603 +6604 +6605 +6606 +6607 +6608 +6609 +6610 +6611 +6612 +6613 +6614 +6615 +6616 +6617 +6618 +6619 +6620 +6621 +6622 +6623 +6624 +6625 +6626 +6627 +6628 +6629 +6630 +6631 +6632 +6633 +6634 +6635 +6636 +6637 +6638 +6639 +6640 +6641 +6642 +6643 +6644 +6645 +6646 +6647 +6648 +6649 +6650 +6651 +6652 +6653 +6654 +6655 +6656 +6657 +6658 +6659 +6660 +6661 +6662 +6663 +6664 +6665 +6666 +6667 +6668 +6669 +6670 +6671 +6672 +6673 +6674 +6675 +6676 +6677 +6678 +6679 +6680 +6681 +6682 +6683 +6684 +6685 +6686 +6687 +6688 +6689 +6690 +6691 +6692 +6693 +6694 +6695 +6696 +6697 +6698 +6699 +6700 +6701 +6702 +6703 +6704 +6705 +6706 +6707 +6708 +6709 +6710 +6711 +6712 +6713 +6714 +6715 +6716 +6717 +6718 +6719 +6720 +6721 +6722 +6723 +6724 +6725 +6726 +6727 +6728 +6729 +6730 +6731 +6732 +6733 +6734 +6735 +6736 +6737 +6738 +6739 +6740 +6741 +6742 +6743 +6744 +6745 +6746 +6747 +6748 +6749 +6750 +6751 +6752 +6753 +6754 +6755 +6756 +6757 +6758 +6759 +6760 +6761 +6762 +6763 +6764 +6765 +6766 +6767 +6768 +6769 +6770 +6771 +6772 +6773 +6774 +6775 +6776 +6777 +6778 +6779 +6780 +6781 +6782 +6783 +6784 +6785 +6786 +6787 +6788 +6789 +6790 +6791 +6792 +6793 +6794 +6795 +6796 +6797 +6798 +6799 +6800 +6801 +6802 +6803 +6804 +6805 +6806 +6807 +6808 +6809 +6810 +6811 +6812 +6813 +6814 +6815 +6816 +6817 +6818 +6819 +6820 +6821 +6822 +6823 +6824 +6825 +6826 +6827 +6828 +6829 +6830 +6831 +6832 +6833 +6834 +6835 +6836 +6837 +6838 +6839 +6840 +6841 +6842 +6843 +6844 +6845 +6846 +6847 +6848 +6849 +6850 +6851 +6852 +6853 +6854 +6855 +6856 +6857 +6858 +6859 +6860 +6861 +6862 +6863 +6864 +6865 +6866 +6867 +6868 +6869 +6870 +6871 +6872 +6873 +6874 +6875 +6876 +6877 +6878 +6879 +6880 +6881 +6882 +6883 +6884 +6885 +6886 +6887 +6888 +6889 +6890 +6891 +6892 +6893 +6894 +6895 +6896 +6897 +6898 +6899 +6900 +6901 +6902 +6903 +6904 +6905 +6906 +6907 +6908 +6909 +6910 +6911 +6912 +6913 +6914 +6915 +6916 +6917 +6918 +6919 +6920 +6921 +6922 +6923 +6924 +6925 +6926 +6927 +6928 +6929 +6930 +6931 +6932 +6933 +6934 +6935 +6936 +6937 +6938 +6939 +6940 +6941 +6942 +6943 +6944 +6945 +6946 +6947 +6948 +6949 +6950 +6951 +6952 +6953 +6954 +6955 +6956 +6957 +6958 +6959 +6960 +6961 +6962 +6963 +6964 +6965 +6966 +6967 +6968 +6969 +6970 +6971 +6972 +6973 +6974 +6975 +6976 +6977 +6978 +6979 +6980 +6981 +6982 +6983 +6984 +6985 +6986 +6987 +6988 +6989 +6990 +6991 +6992 +6993 +6994 +6995 +6996 +6997 +6998 +6999 +7000 +7001 +7002 +7003 +7004 +7005 +7006 +7007 +7008 +7009 +7010 +7011 +7012 +7013 +7014 +7015 +7016 +7017 +7018 +7019 +7020 +7021 +7022 +7023 +7024 +7025 +7026 +7027 +7028 +7029 +7030 +7031 +7032 +7033 +7034 +7035 +7036 +7037 +7038 +7039 +7040 +7041 +7042 +7043 +7044 +7045 +7046 +7047 +7048 +7049 +7050 +7051 +7052 +7053 +7054 +7055 +7056 +7057 +7058 +7059 +7060 +7061 +7062 +7063 +7064 +7065 +7066 +7067 +7068 +7069 +7070 +7071 +7072 +7073 +7074 +7075 +7076 +7077 +7078 +7079 +7080 +7081 +7082 +7083 +7084 +7085 +7086 +7087 +7088 +7089 +7090 +7091 +7092 +7093 +7094 +7095 +7096 +7097 +7098 +7099 +7100 +7101 +7102 +7103 +7104 +7105 +7106 +7107 +7108 +7109 +7110 +7111 +7112 +7113 +7114 +7115 +7116 +7117 +7118 +7119 +7120 +7121 +7122 +7123 +7124 +7125 +7126 +7127 +7128 +7129 +7130 +7131 +7132 +7133 +7134 +7135 +7136 +7137 +7138 +7139 +7140 +7141 +7142 +7143 +7144 +7145 +7146 +7147 +7148 +7149 +7150 +7151 +7152 +7153 +7154 +7155 +7156 +7157 +7158 +7159 +7160 +7161 +7162 +7163 +7164 +7165 +7166 +7167 +7168 +7169 +7170 +7171 +7172 +7173 +7174 +7175 +7176 +7177 +7178 +7179 +7180 +7181 +7182 +7183 +7184 +7185 +7186 +7187 +7188 +7189 +7190 +7191 +7192 +7193 +7194 +7195 +7196 +7197 +7198 +7199 +7200 +7201 +7202 +7203 +7204 +7205 +7206 +7207 +7208 +7209 +7210 +7211 +7212 +7213 +7214 +7215 +7216 +7217 +7218 +7219 +7220 +7221 +7222 +7223 +7224 +7225 +7226 +7227 +7228 +7229 +7230 +7231 +7232 +7233 +7234 +7235 +7236 +7237 +7238 +7239 +7240 +7241 +7242 +7243 +7244 +7245 +7246 +7247 +7248 +7249 +7250 +7251 +7252 +7253 +7254 +7255 +7256 +7257 +7258 +7259 +7260 +7261 +7262 +7263 +7264 +7265 +7266 +7267 +7268 +7269 +7270 +7271 +7272 +7273 +7274 +7275 +7276 +7277 +7278 +7279 +7280 +7281 +7282 +7283 +7284 +7285 +7286 +7287 +7288 +7289 +7290 +7291 +7292 +7293 +7294 +7295 +7296 +7297 +7298 +7299 +7300 +7301 +7302 +7303 +7304 +7305 +7306 +7307 +7308 +7309 +7310 +7311 +7312 +7313 +7314 +7315 +7316 +7317 +7318 +7319 +7320 +7321 +7322 +7323 +7324 +7325 +7326 +7327 +7328 +7329 +7330 +7331 +7332 +7333 +7334 +7335 +7336 +7337 +7338 +7339 +7340 +7341 +7342 +7343 +7344 +7345 +7346 +7347 +7348 +7349 +7350 +7351 +7352 +7353 +7354 +7355 +7356 +7357 +7358 +7359 +7360 +7361 +7362 +7363 +7364 +7365 +7366 +7367 +7368 +7369 +7370 +7371 +7372 +7373 +7374 +7375 +7376 +7377 +7378 +7379 +7380 +7381 +7382 +7383 +7384 +7385 +7386 +7387 +7388 +7389 +7390 +7391 +7392 +7393 +7394 +7395 +7396 +7397 +7398 +7399 +7400 +7401 +7402 +7403 +7404 +7405 +7406 +7407 +7408 +7409 +7410 +7411 +7412 +7413 +7414 +7415 +7416 +7417 +7418 +7419 +7420 +7421 +7422 +7423 +7424 +7425 +7426 +7427 +7428 +7429 +7430 +7431 +7432 +7433 +7434 +7435 +7436 +7437 +7438 +7439 +7440 +7441 +7442 +7443 +7444 +7445 +7446 +7447 +7448 +7449 +7450 +7451 +7452 +7453 +7454 +7455 +7456 +7457 +7458 +7459 +7460 +7461 +7462 +7463 +7464 +7465 +7466 +7467 +7468 +7469 +7470 +7471 +7472 +7473 +7474 +7475 +7476 +7477 +7478 +7479 +7480 +7481 +7482 +7483 +7484 +7485 +7486 +7487 +7488 +7489 +7490 +7491 +7492 +7493 +7494 +7495 +7496 +7497 +7498 +7499 +7500 +7501 +7502 +7503 +7504 +7505 +7506 +7507 +7508 +7509 +7510 +7511 +7512 +7513 +7514 +7515 +7516 +7517 +7518 +7519 +7520 +7521 +7522 +7523 +7524 +7525 +7526 +7527 +7528 +7529 +7530 +7531 +7532 +7533 +7534 +7535 +7536 +7537 +7538 +7539 +7540 +7541 +7542 +7543 +7544 +7545 +7546 +7547 +7548 +7549 +7550 +7551 +7552 +7553 +7554 +7555 +7556 +7557 +7558 +7559 +7560 +7561 +7562 +7563 +7564 +7565 +7566 +7567 +7568 +7569 +7570 +7571 +7572 +7573 +7574 +7575 +7576 +7577 +7578 +7579 +7580 +7581 +7582 +7583 +7584 +7585 +7586 +7587 +7588 +7589 +7590 +7591 +7592 +7593 +7594 +7595 +7596 +7597 +7598 +7599 +7600 +7601 +7602 +7603 +7604 +7605 +7606 +7607 +7608 +7609 +7610 +7611 +7612 +7613 +7614 +7615 +7616 +7617 +7618 +7619 +7620 +7621 +7622 +7623 +7624 +7625 +7626 +7627 +7628 +7629 +7630 +7631 +7632 +7633 +7634 +7635 +7636 +7637 +7638 +7639 +7640 +7641 +7642 +7643 +7644 +7645 +7646 +7647 +7648 +7649 +7650 +7651 +7652 +7653 +7654 +7655 +7656 +7657 +7658 +7659 +7660 +7661 +7662 +7663 +7664 +7665 +7666 +7667 +7668 +7669 +7670 +7671 +7672 +7673 +7674 +7675 +7676 +7677 +7678 +7679 +7680 +7681 +7682 +7683 +7684 +7685 +7686 +7687 +7688 +7689 +7690 +7691 +7692 +7693 +7694 +7695 +7696 +7697 +7698 +7699 +7700 +7701 +7702 +7703 +7704 +7705 +7706 +7707 +7708 +7709 +7710 +7711 +7712 +7713 +7714 +7715 +7716 +7717 +7718 +7719 +7720 +7721 +7722 +7723 +7724 +7725 +7726 +7727 +7728 +7729 +7730 +7731 +7732 +7733 +7734 +7735 +7736 +7737 +7738 +7739 +7740 +7741 +7742 +7743 +7744 +7745 +7746 +7747 +7748 +7749 +7750 +7751 +7752 +7753 +7754 +7755 +7756 +7757 +7758 +7759 +7760 +7761 +7762 +7763 +7764 +7765 +7766 +7767 +7768 +7769 +7770 +7771 +7772 +7773 +7774 +7775 +7776 +7777 +7778 +7779 +7780 +7781 +7782 +7783 +7784 +7785 +7786 +7787 +7788 +7789 +7790 +7791 +7792 +7793 +7794 +7795 +7796 +7797 +7798 +7799 +7800 +7801 +7802 +7803 +7804 +7805 +7806 +7807 +7808 +7809 +7810 +7811 +7812 +7813 +7814 +7815 +7816 +7817 +7818 +7819 +7820 +7821 +7822 +7823 +7824 +7825 +7826 +7827 +7828 +7829 +7830 +7831 +7832 +7833 +7834 +7835 +7836 +7837 +7838 +7839 +7840 +7841 +7842 +7843 +7844 +7845 +7846 +7847 +7848 +7849 +7850 +7851 +7852 +7853 +7854 +7855 +7856 +7857 +7858 +7859 +7860 +7861 +7862 +7863 +7864 +7865 +7866 +7867 +7868 +7869 +7870 +7871 +7872 +7873 +7874 +7875 +7876 +7877 +7878 +7879 +7880 +7881 +7882 +7883 +7884 +7885 +7886 +7887 +7888 +7889 +7890 +7891 +7892 +7893 +7894 +7895 +7896 +7897 +7898 +7899 +7900 +7901 +7902 +7903 +7904 +7905 +7906 +7907 +7908 +7909 +7910 +7911 +7912 +7913 +7914 +7915 +7916 +7917 +7918 +7919 +7920 +7921 +7922 +7923 +7924 +7925 +7926 +7927 +7928 +7929 +7930 +7931 +7932 +7933 +7934 +7935 +7936 +7937 +7938 +7939 +7940 +7941 +7942 +7943 +7944 +7945 +7946 +7947 +7948 +7949 +7950 +7951 +7952 +7953 +7954 +7955 +7956 +7957 +7958 +7959 +7960 +7961 +7962 +7963 +7964 +7965 +7966 +7967 +7968 +7969 +7970 +7971 +7972 +7973 +7974 +7975 +7976 +7977 +7978 +7979 +7980 +7981 +7982 +7983 +7984 +7985 +7986 +7987 +7988 +7989 +7990 +7991 +7992 +7993 +7994 +7995 +7996 +7997 +7998 +7999 +8000 +8001 +8002 +8003 +8004 +8005 +8006 +8007 +8008 +8009 +8010 +8011 +8012 +8013 +8014 +8015 +8016 +8017 +8018 +8019 +8020 +8021 +8022 +8023 +8024 +8025 +8026 +8027 +8028 +8029 +8030 +8031 +8032 +8033 +8034 +8035 +8036 +8037 +8038 +8039 +8040 +8041 +8042 +8043 +8044 +8045 +8046 +8047 +8048 +8049 +8050 +8051 +8052 +8053 +8054 +8055 +8056 +8057 +8058 +8059 +8060 +8061 +8062 +8063 +8064 +8065 +8066 +8067 +8068 +8069 +8070 +8071 +8072 +8073 +8074 +8075 +8076 +8077 +8078 +8079 +8080 +8081 +8082 +8083 +8084 +8085 +8086 +8087 +8088 +8089 +8090 +8091 +8092 +8093 +8094 +8095 +8096 +8097 +8098 +8099 +8100 +8101 +8102 +8103 +8104 +8105 +8106 +8107 +8108 +8109 +8110 +8111 +8112 +8113 +8114 +8115 +8116 +8117 +8118 +8119 +8120 +8121 +8122 +8123 +8124 +8125 +8126 +8127 +8128 +8129 +8130 +8131 +8132 +8133 +8134 +8135 +8136 +8137 +8138 +8139 +8140 +8141 +8142 +8143 +8144 +8145 +8146 +8147 +8148 +8149 +8150 +8151 +8152 +8153 +8154 +8155 +8156 +8157 +8158 +8159 +8160 +8161 +8162 +8163 +8164 +8165 +8166 +8167 +8168 +8169 +8170 +8171 +8172 +8173 +8174 +8175 +8176 +8177 +8178 +8179 +8180 +8181 +8182 +8183 +8184 +8185 +8186 +8187 +8188 +8189 +8190 +8191 +8192 +8193 +8194 +8195 +8196 +8197 +8198 +8199 +8200 +8201 +8202 +8203 +8204 +8205 +8206 +8207 +8208 +8209 +8210 +8211 +8212 +8213 +8214 +8215 +8216 +8217 +8218 +8219 +8220 +8221 +8222 +8223 +8224 +8225 +8226 +8227 +8228 +8229 +8230 +8231 +8232 +8233 +8234 +8235 +8236 +8237 +8238 +8239 +8240 +8241 +8242 +8243 +8244 +8245 +8246 +8247 +8248 +8249 +8250 +8251 +8252 +8253 +8254 +8255 +8256 +8257 +8258 +8259 +8260 +8261 +8262 +8263 +8264 +8265 +8266 +8267 +8268 +8269 +8270 +8271 +8272 +8273 +8274 +8275 +8276 +8277 +8278 +8279 +8280 +8281 +8282 +8283 +8284 +8285 +8286 +8287 +8288 +8289 +8290 +8291 +8292 +8293 +8294 +8295 +8296 +8297 +8298 +8299 +8300 +8301 +8302 +8303 +8304 +8305 +8306 +8307 +8308 +8309 +8310 +8311 +8312 +8313 +8314 +8315 +8316 +8317 +8318 +8319 +8320 +8321 +8322 +8323 +8324 +8325 +8326 +8327 +8328 +8329 +8330 +8331 +8332 +8333 +8334 +8335 +8336 +8337 +8338 +8339 +8340 +8341 +8342 +8343 +8344 +8345 +8346 +8347 +8348 +8349 +8350 +8351 +8352 +8353 +8354 +8355 +8356 +8357 +8358 +8359 +8360 +8361 +8362 +8363 +8364 +8365 +8366 +8367 +8368 +8369 +8370 +8371 +8372 +8373 +8374 +8375 +8376 +8377 +8378 +8379 +8380 +8381 +8382 +8383 +8384 +8385 +8386 +8387 +8388 +8389 +8390 +8391 +8392 +8393 +8394 +8395 +8396 +8397 +8398 +8399 +8400 +8401 +8402 +8403 +8404 +8405 +8406 +8407 +8408 +8409 +8410 +8411 +8412 +8413 +8414 +8415 +8416 +8417 +8418 +8419 +8420 +8421 +8422 +8423 +8424 +8425 +8426 +8427 +8428 +8429 +8430 +8431 +8432 +8433 +8434 +8435 +8436 +8437 +8438 +8439 +8440 +8441 +8442 +8443 +8444 +8445 +8446 +8447 +8448 +8449 +8450 +8451 +8452 +8453 +8454 +8455 +8456 +8457 +8458 +8459 +8460 +8461 +8462 +8463 +8464 +8465 +8466 +8467 +8468 +8469 +8470 +8471 +8472 +8473 +8474 +8475 +8476 +8477 +8478 +8479 +8480 +8481 +8482 +8483 +8484 +8485 +8486 +8487 +8488 +8489 +8490 +8491 +8492 +8493 +8494 +8495 +8496 +8497 +8498 +8499 +8500 +8501 +8502 +8503 +8504 +8505 +8506 +8507 +8508 +8509 +8510 +8511 +8512 +8513 +8514 +8515 +8516 +8517 +8518 +8519 +8520 +8521 +8522 +8523 +8524 +8525 +8526 +8527 +8528 +8529 +8530 +8531 +8532 +8533 +8534 +8535 +8536 +8537 +8538 +8539 +8540 +8541 +8542 +8543 +8544 +8545 +8546 +8547 +8548 +8549 +8550 +8551 +8552 +8553 +8554 +8555 +8556 +8557 +8558 +8559 +8560 +8561 +8562 +8563 +8564 +8565 +8566 +8567 +8568 +8569 +8570 +8571 +8572 +8573 +8574 +8575 +8576 +8577 +8578 +8579 +8580 +8581 +8582 +8583 +8584 +8585 +8586 +8587 +8588 +8589 +8590 +8591 +8592 +8593 +8594 +8595 +8596 +8597 +8598 +8599 +8600 +8601 +8602 +8603 +8604 +8605 +8606 +8607 +8608 +8609 +8610 +8611 +8612 +8613 +8614 +8615 +8616 +8617 +8618 +8619 +8620 +8621 +8622 +8623 +8624 +8625 +8626 +8627 +8628 +8629 +8630 +8631 +8632 +8633 +8634 +8635 +8636 +8637 +8638 +8639 +8640 +8641 +8642 +8643 +8644 +8645 +8646 +8647 +8648 +8649 +8650 +8651 +8652 +8653 +8654 +8655 +8656 +8657 +8658 +8659 +8660 +8661 +8662 +8663 +8664 +8665 +8666 +8667 +8668 +8669 +8670 +8671 +8672 +8673 +8674 +8675 +8676 +8677 +8678 +8679 +8680 +8681 +8682 +8683 +8684 +8685 +8686 +8687 +8688 +8689 +8690 +8691 +8692 +8693 +8694 +8695 +8696 +8697 +8698 +8699 +8700 +8701 +8702 +8703 +8704 +8705 +8706 +8707 +8708 +8709 +8710 +8711 +8712 +8713 +8714 +8715 +8716 +8717 +8718 +8719 +8720 +8721 +8722 +8723 +8724 +8725 +8726 +8727 +8728 +8729 +8730 +8731 +8732 +8733 +8734 +8735 +8736 +8737 +8738 +8739 +8740 +8741 +8742 +8743 +8744 +8745 +8746 +8747 +8748 +8749 +8750 +8751 +8752 +8753 +8754 +8755 +8756 +8757 +8758 +8759 +8760 +8761 +8762 +8763 +8764 +8765 +8766 +8767 +8768 +8769 +8770 +8771 +8772 +8773 +8774 +8775 +8776 +8777 +8778 +8779 +8780 +8781 +8782 +8783 +8784 +8785 +8786 +8787 +8788 +8789 +8790 +8791 +8792 +8793 +8794 +8795 +8796 +8797 +8798 +8799 +8800 +8801 +8802 +8803 +8804 +8805 +8806 +8807 +8808 +8809 +8810 +8811 +8812 +8813 +8814 +8815 +8816 +8817 +8818 +8819 +8820 +8821 +8822 +8823 +8824 +8825 +8826 +8827 +8828 +8829 +8830 +8831 +8832 +8833 +8834 +8835 +8836 +8837 +8838 +8839 +8840 +8841 +8842 +8843 +8844 +8845 +8846 +8847 +8848 +8849 +8850 +8851 +8852 +8853 +8854 +8855 +8856 +8857 +8858 +8859 +8860 +8861 +8862 +8863 +8864 +8865 +8866 +8867 +8868 +8869 +8870 +8871 +8872 +8873 +8874 +8875 +8876 +8877 +8878 +8879 +8880 +8881 +8882 +8883 +8884 +8885 +8886 +8887 +8888 +8889 +8890 +8891 +8892 +8893 +8894 +8895 +8896 +8897 +8898 +8899 +8900 +8901 +8902 +8903 +8904 +8905 +8906 +8907 +8908 +8909 +8910 +8911 +8912 +8913 +8914 +8915 +8916 +8917 +8918 +8919 +8920 +8921 +8922 +8923 +8924 +8925 +8926 +8927 +8928 +8929 +8930 +8931 +8932 +8933 +8934 +8935 +8936 +8937 +8938 +8939 +8940 +8941 +8942 +8943 +8944 +8945 +8946 +8947 +8948 +8949 +8950 +8951 +8952 +8953 +8954 +8955 +8956 +8957 +8958 +8959 +8960 +8961 +8962 +8963 +8964 +8965 +8966 +8967 +8968 +8969 +8970 +8971 +8972 +8973 +8974 +8975 +8976 +8977 +8978 +8979 +8980 +8981 +8982 +8983 +8984 +8985 +8986 +8987 +8988 +8989 +8990 +8991 +8992 +8993 +8994 +8995 +8996 +8997 +8998 +8999 +9000 +9001 +9002 +9003 +9004 +9005 +9006 +9007 +9008 +9009 +9010 +9011 +9012 +9013 +9014 +9015 +9016 +9017 +9018 +9019 +9020 +9021 +9022 +9023 +9024 +9025 +9026 +9027 +9028 +9029 +9030 +9031 +9032 +9033 +9034 +9035 +9036 +9037 +9038 +9039 +9040 +9041 +9042 +9043 +9044 +9045 +9046 +9047 +9048 +9049 +9050 +9051 +9052 +9053 +9054 +9055 +9056 +9057 +9058 +9059 +9060 +9061 +9062 +9063 +9064 +9065 +9066 +9067 +9068 +9069 +9070 +9071 +9072 +9073 +9074 +9075 +9076 +9077 +9078 +9079 +9080 +9081 +9082 +9083 +9084 +9085 +9086 +9087 +9088 +9089 +9090 +9091 +9092 +9093 +9094 +9095 +9096 +9097 +9098 +9099 +9100 +9101 +9102 +9103 +9104 +9105 +9106 +9107 +9108 +9109 +9110 +9111 +9112 +9113 +9114 +9115 +9116 +9117 +9118 +9119 +9120 +9121 +9122 +9123 +9124 +9125 +9126 +9127 +9128 +9129 +9130 +9131 +9132 +9133 +9134 +9135 +9136 +9137 +9138 +9139 +9140 +9141 +9142 +9143 +9144 +9145 +9146 +9147 +9148 +9149 +9150 +9151 +9152 +9153 +9154 +9155 +9156 +9157 +9158 +9159 +9160 +9161 +9162 +9163 +9164 +9165 +9166 +9167 +9168 +9169 +9170 +9171 +9172 +9173 +9174 +9175 +9176 +9177 +9178 +9179 +9180 +9181 +9182 +9183 +9184 +9185 +9186 +9187 +9188 +9189 +9190 +9191 +9192 +9193 +9194 +9195 +9196 +9197 +9198 +9199 +9200 +9201 +9202 +9203 +9204 +9205 +9206 +9207 +9208 +9209 +9210 +9211 +9212 +9213 +9214 +9215 +9216 +9217 +9218 +9219 +9220 +9221 +9222 +9223 +9224 +9225 +9226 +9227 +9228 +9229 +9230 +9231 +9232 +9233 +9234 +9235 +9236 +9237 +9238 +9239 +9240 +9241 +9242 +9243 +9244 +9245 +9246 +9247 +9248 +9249 +9250 +9251 +9252 +9253 +9254 +9255 +9256 +9257 +9258 +9259 +9260 +9261 +9262 +9263 +9264 +9265 +9266 +9267 +9268 +9269 +9270 +9271 +9272 +9273 +9274 +9275 +9276 +9277 +9278 +9279 +9280 +9281 +9282 +9283 +9284 +9285 +9286 +9287 +9288 +9289 +9290 +9291 +9292 +9293 +9294 +9295 +9296 +9297 +9298 +9299 +9300 +9301 +9302 +9303 +9304 +9305 +9306 +9307 +9308 +9309 +9310 +9311 +9312 +9313 +9314 +9315 +9316 +9317 +9318 +9319 +9320 +9321 +9322 +9323 +9324 +9325 +9326 +9327 +9328 +9329 +9330 +9331 +9332 +9333 +9334 +9335 +9336 +9337 +9338 +9339 +9340 +9341 +9342 +9343 +9344 +9345 +9346 +9347 +9348 +9349 +9350 +9351 +9352 +9353 +9354 +9355 +9356 +9357 +9358 +9359 +9360 +9361 +9362 +9363 +9364 +9365 +9366 +9367 +9368 +9369 +9370 +9371 +9372 +9373 +9374 +9375 +9376 +9377 +9378 +9379 +9380 +9381 +9382 +9383 +9384 +9385 +9386 +9387 +9388 +9389 +9390 +9391 +9392 +9393 +9394 +9395 +9396 +9397 +9398 +9399 +9400 +9401 +9402 +9403 +9404 +9405 +9406 +9407 +9408 +9409 +9410 +9411 +9412 +9413 +9414 +9415 +9416 +9417 +9418 +9419 +9420 +9421 +9422 +9423 +9424 +9425 +9426 +9427 +9428 +9429 +9430 +9431 +9432 +9433 +9434 +9435 +9436 +9437 +9438 +9439 +9440 +9441 +9442 +9443 +9444 +9445 +9446 +9447 +9448 +9449 +9450 +9451 +9452 +9453 +9454 +9455 +9456 +9457 +9458 +9459 +9460 +9461 +9462 +9463 +9464 +9465 +9466 +9467 +9468 +9469 +9470 +9471 +9472 +9473 +9474 +9475 +9476 +9477 +9478 +9479 +9480 +9481 +9482 +9483 +9484 +9485 +9486 +9487 +9488 +9489 +9490 +9491 +9492 +9493 +9494 +9495 +9496 +9497 +9498 +9499 +9500 +9501 +9502 +9503 +9504 +9505 +9506 +9507 +9508 +9509 +9510 +9511 +9512 +9513 +9514 +9515 +9516 +9517 +9518 +9519 +9520 +9521 +9522 +9523 +9524 +9525 +9526 +9527 +9528 +9529 +9530 +9531 +9532 +9533 +9534 +9535 +9536 +9537 +9538 +9539 +9540 +9541 +9542 +9543 +9544 +9545 +9546 +9547 +9548 +9549 +9550 +9551 +9552 +9553 +9554 +9555 +9556 +9557 +9558 +9559 +9560 +9561 +9562 +9563 +9564 +9565 +9566 +9567 +9568 +9569 +9570 +9571 +9572 +9573 +9574 +9575 +9576 +9577 +9578 +9579 +9580 +9581 +9582 +9583 +9584 +9585 +9586 +9587 +9588 +9589 +9590 +9591 +9592 +9593 +9594 +9595 +9596 +9597 +9598 +9599 +9600 +9601 +9602 +9603 +9604 +9605 +9606 +9607 +9608 +9609 +9610 +9611 +9612 +9613 +9614 +9615 +9616 +9617 +9618 +9619 +9620 +9621 +9622 +9623 +9624 +9625 +9626 +9627 +9628 +9629 +9630 +9631 +9632 +9633 +9634 +9635 +9636 +9637 +9638 +9639 +9640 +9641 +9642 +9643 +9644 +9645 +9646 +9647 +9648 +9649 +9650 +9651 +9652 +9653 +9654 +9655 +9656 +9657 +9658 +9659 +9660 +9661 +9662 +9663 +9664 +9665 +9666 +9667 +9668 +9669 +9670 +9671 +9672 +9673 +9674 +9675 +9676 +9677 +9678 +9679 +9680 +9681 +9682 +9683 +9684 +9685 +9686 +9687 +9688 +9689 +9690 +9691 +9692 +9693 +9694 +9695 +9696 +9697 +9698 +9699 +9700 +9701 +9702 +9703 +9704 +9705 +9706 +9707 +9708 +9709 +9710 +9711 +9712 +9713 +9714 +9715 +9716 +9717 +9718 +9719 +9720 +9721 +9722 +9723 +9724 +9725 +9726 +9727 +9728 +9729 +9730 +9731 +9732 +9733 +9734 +9735 +9736 +9737 +9738 +9739 +9740 +9741 +9742 +9743 +9744 +9745 +9746 +9747 +9748 +9749 +9750 +9751 +9752 +9753 +9754 +9755 +9756 +9757 +9758 +9759 +9760 +9761 +9762 +9763 +9764 +9765 +9766 +9767 +9768 +9769 +9770 +9771 +9772 +9773 +9774 +9775 +9776 +9777 +9778 +9779 +9780 +9781 +9782 +9783 +9784 +9785 +9786 +9787 +9788 +9789 +9790 +9791 +9792 +9793 +9794 +9795 +9796 +9797 +9798 +9799 +9800 +9801 +9802 +9803 +9804 +9805 +9806 +9807 +9808 +9809 +9810 +9811 +9812 +9813 +9814 +9815 +9816 +9817 +9818 +9819 +9820 +9821 +9822 +9823 +9824 +9825 +9826 +9827 +9828 +9829 +9830 +9831 +9832 +9833 +9834 +9835 +9836 +9837 +9838 +9839 +9840 +9841 +9842 +9843 +9844 +9845 +9846 +9847 +9848 +9849 +9850 +9851 +9852 +9853 +9854 +9855 +9856 +9857 +9858 +9859 +9860 +9861 +9862 +9863 +9864 +9865 +9866 +9867 +9868 +9869 +9870 +9871 +9872 +9873 +9874 +9875 +9876 +9877 +9878 +9879 +9880 +9881 +9882 +9883 +9884 +9885 +9886 +9887 +9888 +9889 +9890 +9891 +9892 +9893 +9894 +9895 +9896 +9897 +9898 +9899 +9900 +9901 +9902 +9903 +9904 +9905 +9906 +9907 +9908 +9909 +9910 +9911 +9912 +9913 +9914 +9915 +9916 +9917 +9918 +9919 +9920 +9921 +9922 +9923 +9924 +9925 +9926 +9927 +9928 +9929 +9930 +9931 +9932 +9933 +9934 +9935 +9936 +9937 +9938 +9939 +9940 +9941 +9942 +9943 +9944 +9945 +9946 +9947 +9948 +9949 +9950 +9951 +9952 +9953 +9954 +9955 +9956 +9957 +9958 +9959 +9960 +9961 +9962 +9963 +9964 +9965 +9966 +9967 +9968 +9969 +9970 +9971 +9972 +9973 +9974 +9975 +9976 +9977 +9978 +9979 +9980 +9981 +9982 +9983 +9984 +9985 +9986 +9987 +9988 +9989 +9990 +9991 +9992 +9993 +9994 +9995 +9996 +9997 +9998 +9999 +10000 diff --git a/cpp/wedpr-storage/ppc-io/tests/data/windows_file.txt b/cpp/wedpr-storage/ppc-io/tests/data/windows_file.txt new file mode 100644 index 00000000..bed6107d --- /dev/null +++ b/cpp/wedpr-storage/ppc-io/tests/data/windows_file.txt @@ -0,0 +1,10 @@ +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 \ No newline at end of file diff --git a/cpp/wedpr-storage/ppc-io/tests/main.cpp b/cpp/wedpr-storage/ppc-io/tests/main.cpp new file mode 100644 index 00000000..2c06f9b5 --- /dev/null +++ b/cpp/wedpr-storage/ppc-io/tests/main.cpp @@ -0,0 +1,2 @@ +#define BOOST_TEST_MAIN +#include \ No newline at end of file diff --git a/cpp/wedpr-storage/ppc-storage/CMakeLists.txt b/cpp/wedpr-storage/ppc-storage/CMakeLists.txt new file mode 100644 index 00000000..5e482dc1 --- /dev/null +++ b/cpp/wedpr-storage/ppc-storage/CMakeLists.txt @@ -0,0 +1,5 @@ +add_subdirectory(src) + +if (DEMO) + add_subdirectory(demo) +endif() \ No newline at end of file diff --git a/cpp/wedpr-storage/ppc-storage/demo/CMakeLists.txt b/cpp/wedpr-storage/ppc-storage/demo/CMakeLists.txt new file mode 100644 index 00000000..b3d19832 --- /dev/null +++ b/cpp/wedpr-storage/ppc-storage/demo/CMakeLists.txt @@ -0,0 +1,10 @@ +file(GLOB_RECURSE SOURCES "*.cpp" "*.h") + +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) +# cmake settings +set(STORAGE_DEMO_BINARY_NAME storage_demo) + +add_executable(${STORAGE_DEMO_BINARY_NAME} storage_demo.cpp) + +target_link_libraries(${STORAGE_DEMO_BINARY_NAME} ${STORAGE_TARGET} ${CPU_FEATURES_LIB} ${BOOST_UNIT_TEST}) +unset(CMAKE_RUNTIME_OUTPUT_DIRECTORY) \ No newline at end of file diff --git a/cpp/wedpr-storage/ppc-storage/demo/storage_demo.cpp b/cpp/wedpr-storage/ppc-storage/demo/storage_demo.cpp new file mode 100644 index 00000000..3d8f92c8 --- /dev/null +++ b/cpp/wedpr-storage/ppc-storage/demo/storage_demo.cpp @@ -0,0 +1,122 @@ +/* + * Copyright (C) 2022 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 storage_demo.cpp + * @desc: demo for storage + * @author: yujiechen + * @date 2022-10-24 + */ +#include "ppc-storage/src/CacheStorageFactoryImpl.h" +#include +#include +#include +#include +#include + +using namespace ppc::storage; +using namespace ppc::protocol; +using namespace bcos; +int main(int argc, char* argv[]) +{ + if (argc < 4) + { + std::cout << "Usage: " << argv[0] + << "\nredis: 0 ip port 123456\n proxy obServer cluster user password"; + return -1; + } + try + { + CacheStorageConfig cacheStorageConfig; + + if (atoi(argv[1]) == 0) + { + // redis + cacheStorageConfig.type = CacheType::Redis; + cacheStorageConfig.host = argv[2]; + cacheStorageConfig.port = atoi(argv[3]); + cacheStorageConfig.password = argv[4]; + cacheStorageConfig.database = 1; + } + else + { + std::cout << "Usage: " << argv[0] + << "\nredis: 0 ip port 123456\n proxy obServer cluster user password"; + return -1; + } + + CacheStorageFactoryImpl::Ptr factory = std::make_shared(); + auto cacheClient = factory->createCacheStorage(cacheStorageConfig); + + // set and get data + std::cout << "#### start cache test ####" << std::endl; + auto startT = utcSteadyTime(); + std::cout << "check setValue/getValue/exists..." << std::endl; + for (int i = 0; i < 1000; i++) + { + auto key = std::to_string(i); + auto value = "value" + key; + cacheClient->setValue(key, value); + auto result = cacheClient->getValue(key); + BOOST_CHECK(result.has_value() && result == value); + // check exists + BOOST_CHECK(cacheClient->exists(key)); + } + std::cout << "setValue/getValue/exists success, time: " << (utcSteadyTime() - startT) + << "ms" << std::endl; + std::cout << "check non-exists key..." << std::endl; + // check non-exists data + startT = utcSteadyTime(); + for (int i = 10000; i < 500; i++) + { + auto key = std::to_string(i); + auto result = cacheClient->getValue(key); + BOOST_CHECK(!result.has_value()); + BOOST_CHECK(!cacheClient->exists(key)); + } + std::cout << "check non-exists key success, time: " << (utcSteadyTime() - startT) << "ms" + << std::endl; + // expire all the keys with 1s expiration-time + startT = utcSteadyTime(); + std::cout << "check expireKey key..." << std::endl; + for (int i = 0; i < 1000; i++) + { + auto key = std::to_string(i); + cacheClient->expireKey(key, 1); + } + std::cout << "check expireKey key success, time: " << (utcSteadyTime() - startT) << "ms" + << std::endl; + // sleep 2s + std::cout << "sleep 2 seconds to wait for key-expiration" << std::endl; + boost::this_thread::sleep_for(boost::chrono::milliseconds(2000)); + std::cout << "wait-finished" << std::endl; + // check the key + startT = utcSteadyTime(); + std::cout << "check the key-expiration..." << std::endl; + for (int i = 0; i < 1000; i++) + { + auto key = std::to_string(i); + auto result = cacheClient->getValue(key); + BOOST_CHECK(!result.has_value()); + BOOST_CHECK(!cacheClient->exists(key)); + } + std::cout << "check the key-expiration success, time:" << (utcSteadyTime() - startT) + << std::endl; + std::cout << "#### end cache test ####" << std::endl; + } + catch (std::exception const& e) + { + std::cout << "access cache error: \n" << boost::diagnostic_information(e) << std::endl; + } +} \ No newline at end of file diff --git a/cpp/wedpr-storage/ppc-storage/src/CMakeLists.txt b/cpp/wedpr-storage/ppc-storage/src/CMakeLists.txt new file mode 100644 index 00000000..5e21c8da --- /dev/null +++ b/cpp/wedpr-storage/ppc-storage/src/CMakeLists.txt @@ -0,0 +1,7 @@ +file(GLOB_RECURSE SRCS *.cpp) +add_library(${STORAGE_TARGET} ${SRCS}) + +find_package(redis++ REQUIRED) +find_package(unofficial-mysql-connector-cpp REQUIRED) + +target_link_libraries(${STORAGE_TARGET} PUBLIC redis++::redis++_static unofficial::mysql-connector-cpp::connector resolv ${HDFS_LIB}) diff --git a/cpp/wedpr-storage/ppc-storage/src/CacheStorageFactoryImpl.h b/cpp/wedpr-storage/ppc-storage/src/CacheStorageFactoryImpl.h new file mode 100644 index 00000000..c7fe6b22 --- /dev/null +++ b/cpp/wedpr-storage/ppc-storage/src/CacheStorageFactoryImpl.h @@ -0,0 +1,75 @@ +/** + * Copyright (C) 2022 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 CacheStorageFactoryImpl.h + * @author: shawnhe + * @date 2023-03-13 + */ +#pragma once + +#include "Common.h" +#include "ppc-framework/storage/CacheStorage.h" +#include "redis/RedisStorage.h" + +namespace ppc::storage +{ +class CacheStorageFactoryImpl : public ppc::storage::CacheStorageFactory +{ +public: + using Ptr = std::shared_ptr; + +public: + CacheStorageFactoryImpl() = default; + ~CacheStorageFactoryImpl() = default; + +public: + CacheStorage::Ptr createCacheStorage(CacheStorageConfig const& _config) + { + switch (_config.type) + { + case ppc::protocol::CacheType::Redis: + { + STORAGE_LOG(INFO) << LOG_DESC("buildRedisCache"); + sw::redis::ConnectionOptions connection_options; + connection_options.host = _config.host; + connection_options.port = _config.port; + connection_options.password = _config.password; + connection_options.db = _config.database; + + // *0ms* by default. + connection_options.connect_timeout = + std::chrono::milliseconds(_config.connectionTimeout); + // Optional. Timeout before we successfully send request to or receive response from + // redis. By default, the timeout is 0ms, i.e. never timeout and block until we send or + // receive successfuly. NOTE: if any command is timed out, we throw a TimeoutError + // exception. 0ms by default + connection_options.socket_timeout = std::chrono::milliseconds(_config.socketTimeout); + connection_options.keep_alive = true; + + sw::redis::ConnectionPoolOptions pool_options; + pool_options.size = _config.pool; + + return std::make_shared(connection_options, pool_options); + } + default: + { + BOOST_THROW_EXCEPTION( + UnsupportedCacheStorage() << bcos::errinfo_comment( + "unsupported cache type: " + std::to_string((int)_config.type))); + } + } + } +}; +} // namespace ppc::storage \ No newline at end of file diff --git a/cpp/wedpr-storage/ppc-storage/src/Common.h b/cpp/wedpr-storage/ppc-storage/src/Common.h new file mode 100644 index 00000000..9041397b --- /dev/null +++ b/cpp/wedpr-storage/ppc-storage/src/Common.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2022 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 Common.h + * @author: yujiechen + * @date 2022-10-25 + */ +#pragma once +#include "ppc-framework/Common.h" +#include + +#define STORAGE_LOG(LEVEL) BCOS_LOG(LEVEL) << LOG_BADGE("STORAGE") + +namespace ppc::storage +{ +DERIVE_PPC_EXCEPTION(UnsupportedCacheStorage); +DERIVE_PPC_EXCEPTION(UnsupportedSQLStorage); +DERIVE_PPC_EXCEPTION(UnsupportedRemoteStorage); +} // namespace ppc::storage \ No newline at end of file diff --git a/cpp/wedpr-storage/ppc-storage/src/FileStorageFactoryImpl.h b/cpp/wedpr-storage/ppc-storage/src/FileStorageFactoryImpl.h new file mode 100644 index 00000000..57e16265 --- /dev/null +++ b/cpp/wedpr-storage/ppc-storage/src/FileStorageFactoryImpl.h @@ -0,0 +1,50 @@ +/** + * Copyright (C) 2022 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 FileStorageFactoryImpl.h + * @author: yujiechen + * @date 2022-11-30 + */ +#pragma once +#include "hdfs/HDFSStorage.h" + +namespace ppc::storage +{ +class FileStorageFactoryImpl : public FileStorageFactory +{ +public: + using Ptr = std::shared_ptr; + FileStorageFactoryImpl() = default; + ~FileStorageFactoryImpl() override = default; + + FileStorage::Ptr createFileStorage(ppc::protocol::DataResourceType _type, + ppc::protocol::FileStorageConnectionOption::Ptr const& _option) override + { + switch (_type) + { + case ppc::protocol::DataResourceType::HDFS: + { + _option->check(); + return std::make_shared(_option); + } + default: + { + BOOST_THROW_EXCEPTION( + UnsupportedFileStorage() << bcos::errinfo_comment("Only support HDFS now")); + } + } + } +}; +} // namespace ppc::storage \ No newline at end of file diff --git a/cpp/wedpr-storage/ppc-storage/src/SQLStorageFactoryImpl.h b/cpp/wedpr-storage/ppc-storage/src/SQLStorageFactoryImpl.h new file mode 100644 index 00000000..1c1695df --- /dev/null +++ b/cpp/wedpr-storage/ppc-storage/src/SQLStorageFactoryImpl.h @@ -0,0 +1,53 @@ +/** + * Copyright (C) 2022 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 SQLStorageFactoryImpl.h + * @author: yujiechen + * @date 2022-11-7 + */ +#pragma once +#include "mysql/MySQLStorage.h" +#include "ppc-framework/storage/FileStorage.h" +#include "ppc-framework/storage/SQLStorage.h" + +namespace ppc::storage +{ +class SQLStorageFactoryImpl : public SQLStorageFactory +{ +public: + using Ptr = std::shared_ptr; + + SQLStorageFactoryImpl() = default; + ~SQLStorageFactoryImpl() override = default; + + SQLStorage::Ptr createSQLStorage(ppc::protocol::DataResourceType _type, + ppc::protocol::SQLConnectionOption::Ptr const& _option) override + { + switch (_type) + { + case ppc::protocol::DataResourceType::MySQL: + { + _option->check(); + return std::make_shared(_option); + } + default: + { + BOOST_THROW_EXCEPTION( + UnsupportedSQLStorage() << bcos::errinfo_comment("Only support MySQL now")); + } + } + } +}; +} // namespace ppc::storage \ No newline at end of file diff --git a/cpp/wedpr-storage/ppc-storage/src/hdfs/Common.h b/cpp/wedpr-storage/ppc-storage/src/hdfs/Common.h new file mode 100644 index 00000000..17f8a2a4 --- /dev/null +++ b/cpp/wedpr-storage/ppc-storage/src/hdfs/Common.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2022 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 Common.h + * @author: yujiechen + * @date 2022-11-30 + */ +#pragma once +#include "../Common.h" +#define HDFS_STORAGE_LOG(LEVEL) BCOS_LOG(LEVEL) << LOG_BADGE("HDFS_STORAGE") +#define HDFS_AUTH_LOG(LEVEL) BCOS_LOG(LEVEL) << LOG_BADGE("HDFS_STORAGE_AUTH") +namespace ppc::storage +{ +DERIVE_PPC_EXCEPTION(ConnectToHDFSFailed); +DERIVE_PPC_EXCEPTION(CreateDirectoryFailed); +DERIVE_PPC_EXCEPTION(UnsupportedFileStorage); +DERIVE_PPC_EXCEPTION(DeleteHDFSFileFailed); +DERIVE_PPC_EXCEPTION(HDFSConnectionOptionNotSet); +DERIVE_PPC_EXCEPTION(RenameHDFSFileFailed); +} // namespace ppc::storage \ No newline at end of file diff --git a/cpp/wedpr-storage/ppc-storage/src/hdfs/HDFSStorage.cpp b/cpp/wedpr-storage/ppc-storage/src/hdfs/HDFSStorage.cpp new file mode 100644 index 00000000..8d467235 --- /dev/null +++ b/cpp/wedpr-storage/ppc-storage/src/hdfs/HDFSStorage.cpp @@ -0,0 +1,213 @@ +/* + * Copyright (C) 2022 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 HDFSStorage.cpp + * @author: yujiechen + * @date 2022-11-30 + */ +#include "HDFSStorage.h" +#include "auth/Krb5CredLoader.h" +#include +#include +#include +#include + +using namespace ppc::storage; +using namespace ppc::protocol; +using namespace bcos; + +HDFSStorage::HDFSStorage(FileStorageConnectionOption::Ptr const& _option) + : m_option(_option), m_builder(hdfsNewBuilder()) +{ + if (!m_option) + { + BOOST_THROW_EXCEPTION(HDFSConnectionOptionNotSet() + << errinfo_comment("Must set the hdfs-connection-option!")); + } + // Note: the libhdfs3 will try to connect to the hdfs with connect-timeout and retry + // 'rpc.client.connect.retry' times + // the default connect timeout is 600s + // the default 'rpc.client.connect.retry' is 10 + auto connectTimeout = + std::to_string(_option->connectionTimeout); // set 1s as the connectTimeout + HDFS_STORAGE_LOG(INFO) << LOG_DESC("create HDFSStorage") << _option->desc() + << LOG_KV("connectTimeout", connectTimeout); + hdfsBuilderConfSetStr(m_builder.get(), "rpc.client.connect.timeout", connectTimeout.c_str()); + + // default disable output.replace-datanode-on-failure, set to false to resolve append data error + if (_option->replaceDataNodeOnFailure) + { + hdfsBuilderConfSetStr(m_builder.get(), "output.replace-datanode-on-failure", "true"); + } + else + { + hdfsBuilderConfSetStr(m_builder.get(), "output.replace-datanode-on-failure", "false"); + } + + // set name node + hdfsBuilderSetNameNode(m_builder.get(), _option->nameNode.c_str()); + hdfsBuilderSetNameNodePort(m_builder.get(), _option->nameNodePort); + if (!_option->userName.empty()) + { + hdfsBuilderSetUserName(m_builder.get(), _option->userName.c_str()); + } + if (!_option->token.empty()) + { + hdfsBuilderSetToken(m_builder.get(), _option->token.c_str()); + } + // init the auth information + if (_option->authConfig) + { + // set auth type to Kerberos + hdfsBuilderConfSetStr(m_builder.get(), "hadoop.security.authentication", "kerberos"); + // init and store the auth information into the cache + auto ctx = std::make_shared(_option->authConfig); + ctx->init(); + HDFS_STORAGE_LOG(INFO) << LOG_DESC("SetKerbTicketCachePath") + << LOG_KV("ccachePath", _option->authConfig->ccachePath); + // set the ccache file path + hdfsBuilderSetKerbTicketCachePath(m_builder.get(), _option->authConfig->ccachePath.c_str()); + } + // connect to the hdfs, Note: the m_fs is a pointer + m_fs = std::shared_ptr( + hdfsBuilderConnect(m_builder.get()), HDFSFSDeleter()); + if (!m_fs) + { + BOOST_THROW_EXCEPTION( + ConnectToHDFSFailed() << errinfo_comment( + "Connect to hdfs failed! error: " + std::string(hdfsGetLastError()))); + } + HDFS_STORAGE_LOG(INFO) << LOG_DESC("create HDFSStorage success") << _option->desc() + << LOG_KV("connectTimeout", connectTimeout); +} + + +void HDFSStorage::tryToCreateHomeDirectory() const +{ + auto homeDir = getHomeDirectory(); + if (hdfsExists(m_fs.get(), homeDir.c_str()) != 0) + { + createDirectoryImpl(homeDir); + } +} + +void HDFSStorage::createDirectory(std::string const& _dirPath) const +{ + tryToCreateHomeDirectory(); + createDirectoryImpl(_dirPath); +} + +void HDFSStorage::createDirectoryImpl(std::string const& _dirPath) const +{ + HDFS_STORAGE_LOG(INFO) << LOG_DESC("createDirectory: ") << _dirPath; + if (hdfsCreateDirectory(m_fs.get(), _dirPath.c_str()) != 0) + { + BOOST_THROW_EXCEPTION(CreateDirectoryFailed() << bcos::errinfo_comment( + "createDirectory " + _dirPath + + " failed, error: " + std::string(hdfsGetLastError()))); + } + HDFS_STORAGE_LOG(INFO) << LOG_DESC("createDirectory success") << LOG_KV("path", _dirPath); +} + +FileHandler::Ptr HDFSStorage::openFile(std::string const& _path, bool _createIfNotExists) const +{ + // check the existence of the file + if (hdfsExists(m_fs.get(), _path.c_str()) != 0) + { + if (!_createIfNotExists) + { + BOOST_THROW_EXCEPTION(OpenFileFailed() << bcos::errinfo_comment( + "OpenFileFailed: The file " + _path + " not found!")); + } + else + { + HDFS_STORAGE_LOG(DEBUG) + << LOG_DESC("openFile: create the non-exists file") << LOG_KV("path", _path); + boost::filesystem::path filePath(_path); + auto parentPath = filePath.parent_path().string(); + if (parentPath.empty()) + { + parentPath = getHomeDirectory(); + } + // create the parent path + if (hdfsExists(m_fs.get(), parentPath.c_str()) != 0) + { + HDFS_STORAGE_LOG(DEBUG) << LOG_DESC("create parent path: ") << parentPath; + createDirectoryImpl(parentPath); + } + auto fd = hdfsOpenFile(m_fs.get(), _path.c_str(), O_CREAT, 0, 0, 0); + if (!fd) + { + HDFS_STORAGE_LOG(WARNING) + << LOG_DESC("openFileFailed: create the non-exists file failed") + << LOG_KV("path", _path) + << LOG_KV("exception", std::string(hdfsGetLastError())); + BOOST_THROW_EXCEPTION( + OpenFileFailed() << bcos::errinfo_comment( + "OpenFileFailed: create the non-exists file failed, path: " + _path + + ", error: " + std::string(hdfsGetLastError()))); + } + // release the fd + hdfsCloseFile(m_fs.get(), fd); + } + } + auto fileInfo = hdfsGetPathInfo(m_fs.get(), _path.c_str()); + HDFS_STORAGE_LOG(DEBUG) << LOG_DESC("HDFSStorage: openFile success") << LOG_KV("path", _path) + << LOG_KV("blockSize", fileInfo->mBlockSize) + << LOG_KV("blockNum", fileInfo->mSize); + + return std::make_shared(_path, m_fs, fileInfo); +} + +// delete the file +void HDFSStorage::deleteFile(std::string const& _path) const +{ + HDFS_STORAGE_LOG(INFO) << LOG_DESC("deleteFile") << LOG_KV("path", _path); + auto ret = hdfsDelete(m_fs.get(), _path.c_str(), 1); + // delete success + if (!ret) + { + return; + } + // delete failed + BOOST_THROW_EXCEPTION(DeleteHDFSFileFailed() + << bcos::errinfo_comment("DeleteHDFSFileFailed, path: " + _path + + ", error: " + std::string(hdfsGetLastError()))); +} + +void HDFSStorage::renameFile(std::string const& _old_path, std::string const& _new_path) const +{ + HDFS_STORAGE_LOG(INFO) << LOG_DESC("renameFile") << LOG_KV("old_path", _old_path) + << LOG_KV("new_path", _new_path); + auto ret = hdfsRename(m_fs.get(), _old_path.c_str(), _new_path.c_str()); + // delete success + if (!ret) + { + return; + } + // delete failed + BOOST_THROW_EXCEPTION(RenameHDFSFileFailed() + << bcos::errinfo_comment("RenameHDFSFileFailed, path: " + _old_path + + ", error: " + std::string(hdfsGetLastError()))); +} + +bool HDFSStorage::fileExists(std::string const& _path) const +{ + if (hdfsExists(m_fs.get(), _path.c_str()) != 0) + { + return false; + } + return true; +} \ No newline at end of file diff --git a/cpp/wedpr-storage/ppc-storage/src/hdfs/HDFSStorage.h b/cpp/wedpr-storage/ppc-storage/src/hdfs/HDFSStorage.h new file mode 100644 index 00000000..1bd62fa0 --- /dev/null +++ b/cpp/wedpr-storage/ppc-storage/src/hdfs/HDFSStorage.h @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2022 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 HDFSStorage.h + * @author: yujiechen + * @date 2022-11-30 + */ +#pragma once +#include "Common.h" +#include "ppc-framework/protocol/Protocol.h" +#include "ppc-framework/storage/FileStorage.h" +#include +#include +#include +#include + +namespace ppc::storage +{ +//// the hdfs handler +class HDFSHandler : public FileHandler +{ +public: + using Ptr = std::shared_ptr; + HDFSHandler(std::string const& _path, + std::shared_ptr _storageHandler, + hdfsFileInfo* _fileInfoHandler) + : m_path(_path), m_storageHandler(_storageHandler), m_fileInfoHandler(_fileInfoHandler) + {} + ~HDFSHandler() override { closeFile(); } + + void* fileInfoHandler() const override { return (void*)m_fileInfoHandler.get(); } + void* storageHandler() const override { return (void*)m_storageHandler.get(); } + std::string const& path() const override { return m_path; } + + void closeFile() { m_fileInfoHandler.reset(); } + +private: + std::string m_path; + std::shared_ptr m_storageHandler; + + struct HDFSFileInfoDeleter + { + void operator()(hdfsFileInfo* _fileInfo) const + { + if (!_fileInfo) + { + return; + } + hdfsFreeFileInfo(_fileInfo, 1); + } + }; + std::unique_ptr m_fileInfoHandler; +}; + +class HDFSStorage : public FileStorage +{ +public: + using Ptr = std::shared_ptr; + HDFSStorage(ppc::protocol::FileStorageConnectionOption::Ptr const& _connectOption); + ~HDFSStorage() {} + + void createDirectory(std::string const& _dirPath) const override; + FileHandler::Ptr openFile( + std::string const& _path, bool _createIfNotExists = false) const override; + // close the file + void closeFile(FileHandler::Ptr _handler) const override + { + auto hdfsHandler = std::dynamic_pointer_cast(_handler); + hdfsHandler->closeFile(); + } + + void renameFile(std::string const& _old_path, std::string const& _new_path) const override; + + void deleteFile(std::string const& _file) const override; + + bool fileExists(std::string const& _path) const override; + +private: + inline std::string getHomeDirectory() const + { + return std::string("/user/") + m_option->userName; + } + + void createDirectoryImpl(std::string const& _dirPath) const; + + void tryToCreateHomeDirectory() const; + +private: + ppc::protocol::FileStorageConnectionOption::Ptr m_option; + struct HDFSBuilderDeleter + { + void operator()(hdfsBuilder* _builder) const { hdfsFreeBuilder(_builder); } + }; + std::unique_ptr m_builder; + + struct HDFSFSDeleter + { + void operator()(HdfsFileSystemInternalWrapper* _fs) const { hdfsDisconnect(_fs); } + }; + std::shared_ptr m_fs; +}; +} // namespace ppc::storage \ No newline at end of file diff --git a/cpp/wedpr-storage/ppc-storage/src/hdfs/auth/Krb5CredLoader.cpp b/cpp/wedpr-storage/ppc-storage/src/hdfs/auth/Krb5CredLoader.cpp new file mode 100644 index 00000000..498aaa7e --- /dev/null +++ b/cpp/wedpr-storage/ppc-storage/src/hdfs/auth/Krb5CredLoader.cpp @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2022 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 Krb5CredLoader.cpp + * @author: yujiechen + * @date 2024-12-1 + */ +#include "Krb5CredLoader.h" +#include "../Common.h" + +using namespace ppc::storage; +using namespace ppc; +using namespace ppc::protocol; +using namespace bcos; + +void Krb5Context::init() +{ + HDFS_AUTH_LOG(INFO) << LOG_DESC("init Krb5Context") << m_config->desc(); + + // init the profile + auto ret = profile_init_path(m_config->authConfigFilePath.c_str(), &m_profile); + if (ret) + { + BOOST_THROW_EXCEPTION(WeDPRException() << errinfo_comment( + "load Krb5Context failed for profile_init_path failed!")); + } + m_profilePtr = &m_profile; + // load krb5 ctx + auto error = krb5_init_context_profile(m_profile, 1, &m_ctx); + checkResult(error, "krb5_init_context_profile"); + + // init the principal + error = krb5_parse_name(m_ctx, m_config->principal.c_str(), &m_principal); + checkResult(error, "krb5_parse_name"); + // init credential + error = krb5_get_init_creds_password( + m_ctx, &m_credsObj, m_principal, m_config->password.c_str(), NULL, NULL, 0, NULL, NULL); + checkResult(error, "krb5_get_init_creds_password"); + m_creds = &m_credsObj; + // init the ccache + error = krb5_cc_resolve(m_ctx, m_config->ccachePath.c_str(), &m_ccache); + checkResult(error, "krb5_cc_resolve"); + + error = krb5_cc_initialize(m_ctx, m_ccache, m_principal); + checkResult(error, "krb5_cc_initialize"); + // store the credential + error = krb5_cc_store_cred(m_ctx, m_ccache, m_creds); + HDFS_AUTH_LOG(INFO) << LOG_DESC("init Krb5Context success") << m_config->desc(); +} + +void Krb5Context::checkResult(krb5_error_code const& error, std::string const& method) +{ + if (!error) + { + HDFS_AUTH_LOG(INFO) << LOG_DESC("init Krb5Context: ") << method << " success"; + return; + } + auto msg = krb5_get_error_message(m_ctx, error); + HDFS_AUTH_LOG(ERROR) << LOG_DESC("init Krb5Context failed") << LOG_KV("method", method) + << LOG_KV("reason", msg); + BOOST_THROW_EXCEPTION( + WeDPRException() << errinfo_comment( + "load Krb5Context failed, method: " + method + ", reason: " + std::string(msg))); +} \ No newline at end of file diff --git a/cpp/wedpr-storage/ppc-storage/src/hdfs/auth/Krb5CredLoader.h b/cpp/wedpr-storage/ppc-storage/src/hdfs/auth/Krb5CredLoader.h new file mode 100644 index 00000000..e2caeb30 --- /dev/null +++ b/cpp/wedpr-storage/ppc-storage/src/hdfs/auth/Krb5CredLoader.h @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2022 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 Krb5CredLoader.h + * @author: yujiechen + * @date 2024-12-1 + */ +#pragma once +#include "ppc-framework/protocol/Krb5AuthConfig.h" +#include +#include +#include + +namespace ppc::storage +{ +class Krb5Context +{ +public: + using Ptr = std::shared_ptr; + Krb5Context(ppc::protocol::Krb5AuthConfig::Ptr const& config) : m_config(config) {} + + virtual ~Krb5Context() + { + if (m_principal) + { + krb5_free_principal(m_ctx, m_principal); + } + if (m_creds) + { + krb5_free_cred_contents(m_ctx, m_creds); + } + if (m_ctx) + { + krb5_free_context(m_ctx); + } + if (m_profilePtr) + { + profile_release(m_profile); + } + } + + virtual void init(); + +private: + void checkResult(krb5_error_code const& error, std::string const& method); + +protected: + ppc::protocol::Krb5AuthConfig::Ptr m_config; + krb5_context m_ctx = NULL; + profile_t m_profile; + profile_t* m_profilePtr = NULL; + krb5_principal m_principal = NULL; + krb5_creds m_credsObj; + krb5_creds* m_creds = NULL; + krb5_ccache m_ccache = NULL; +}; + +class Krb5CredLoader +{ +public: + using Ptr = std::shared_ptr; + Krb5CredLoader() = default; + virtual ~Krb5CredLoader() = default; + + virtual Krb5Context::Ptr load(ppc::protocol::Krb5AuthConfig::Ptr const& config) const + { + return std::make_shared(config); + } +}; +} // namespace ppc::storage \ No newline at end of file diff --git a/cpp/wedpr-storage/ppc-storage/src/mysql/Common.h b/cpp/wedpr-storage/ppc-storage/src/mysql/Common.h new file mode 100644 index 00000000..1d18ee71 --- /dev/null +++ b/cpp/wedpr-storage/ppc-storage/src/mysql/Common.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2022 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 Common.h + * @author: yujiechen + * @date 2022-10-25 + */ +#pragma once +#include "../Common.h" +#define MYSQL_STORAGE_LOG(LEVEL) BCOS_LOG(LEVEL) << LOG_BADGE("MYSQL_STORAGE") + +namespace ppc::storage +{ +DERIVE_PPC_EXCEPTION(ConnectMySQLError); +DERIVE_PPC_EXCEPTION(ExecMySQLError); +DERIVE_PPC_EXCEPTION(ParseMySQLResultError); +DERIVE_PPC_EXCEPTION(UnSupportedDataSchema); +DERIVE_PPC_EXCEPTION(NotSetMySQLConnectionOption); +} // namespace ppc::storage \ No newline at end of file diff --git a/cpp/wedpr-storage/ppc-storage/src/mysql/MySQLStorage.cpp b/cpp/wedpr-storage/ppc-storage/src/mysql/MySQLStorage.cpp new file mode 100644 index 00000000..c8899196 --- /dev/null +++ b/cpp/wedpr-storage/ppc-storage/src/mysql/MySQLStorage.cpp @@ -0,0 +1,403 @@ +/* + * Copyright (C) 2022 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 MySQLStorage.cpp + * @author: yujiechen + * @date 2022-10-25 + */ +#include "MySQLStorage.h" +#include +#include + +using namespace ppc::storage; +using namespace ppc::io; +using namespace ppc::protocol; +using namespace bcos; + +MySQLStorage::MySQLStorage( + ppc::protocol::SQLConnectionOption::Ptr const& _opt, uint16_t _sessionPoolSize) + : m_opt(_opt), + m_sessionPoolSize(_sessionPoolSize), + m_timer(std::make_shared(1000 * 60 * 1, "mysqlTimer")) +{ + if (!m_opt) + { + BOOST_THROW_EXCEPTION(NotSetMySQLConnectionOption() + << errinfo_comment("Must set the mysql-connection-option!")); + } + if (m_opt->database.empty()) + { + useDataBase(nullptr); + } + else + { + useDataBase(m_opt->database.c_str()); + } + + if (m_timer) + { + m_timer->registerTimeoutHandler([this] { refreshConnection(); }); + m_timer->start(); + } +} + +void MySQLStorage::refreshConnection() +{ + MYSQL_STORAGE_LOG(INFO) << LOG_DESC("refreshConnection"); + + if (m_opt->database.empty()) + { + useDataBase(nullptr); + } + else + { + useDataBase(m_opt->database.c_str()); + } + + if (m_timer) + { + m_timer->restart(); + } +} + +// use the database +void MySQLStorage::useDataBase(const char* _database) +{ + try + { + m_opt->database = _database ? _database : ""; + // destory the current session + destroyAllSession(); + insertSession(createSession()); + MYSQL_STORAGE_LOG(INFO) << LOG_DESC("use mysql success") + << LOG_KV("connectOpt", m_opt->desc()); + } + catch (std::exception const& e) + { + BOOST_THROW_EXCEPTION(ConnectMySQLError() << errinfo_comment( + "connect to mysql error: " + boost::diagnostic_information(e))); + } +} + +mysqlx_session_t* MySQLStorage::createSession() const +{ + const char* dataBase = m_opt->database.empty() ? nullptr : m_opt->database.c_str(); + try + { + return connectDataBase(dataBase, false); + } + catch (std::exception const& e) + { + return connectDataBase(dataBase, true); + } +} + +mysqlx_session_t* MySQLStorage::connectDataBase(const char* _database, bool _disableSSl) const +{ + // allocate new session according to _database + mysqlx_error_t* error = NULL; + std::stringstream conn; + conn << m_opt->user << ":" << m_opt->password << "@" << m_opt->host; + if (_database) + { + conn << "/" << _database; + } + if (_disableSSl) + { + conn << "?ssl-mode=disabled&mysql41"; + } + MYSQL_STORAGE_LOG(INFO) << LOG_DESC("MySQLStorage connect") << LOG_KV("conn", conn.str()); + auto session = mysqlx_get_session_from_url(conn.str().c_str(), &error); + if (!session) + { + auto errorMsg = std::string(mysqlx_error_message(error)); + MYSQL_STORAGE_LOG(ERROR) << LOG_DESC("connect to mysql error") << m_opt->desc() + << LOG_KV("code", mysqlx_error_num(error)) + << LOG_KV("msg", errorMsg); + // free the error + mysqlx_free(error); + BOOST_THROW_EXCEPTION( + ConnectMySQLError() << errinfo_comment("connect to mysql error: " + errorMsg)); + } + return session; +} + +// exec the sql-query-command +QueryResult::Ptr MySQLStorage::execQuery(bool _parseByColumn, const char* _command, ...) const +{ + // parse the args + va_list args; + va_start(args, _command); + auto result = execSQL(_command, args); + va_end(args); + // query no data + uint32_t columnSize = mysqlx_column_get_count((mysqlx_result_t*)result->result()); + if (!columnSize) + { + return nullptr; + } + MYSQL_STORAGE_LOG(TRACE) << LOG_DESC("execQuery success: ") << LOG_KV("command", _command) + << LOG_KV("columnSize", columnSize); + auto queryResult = std::make_shared(); + parseMetaData(queryResult, result, columnSize); + if (_parseByColumn) + { + parseResultByColumn(queryResult, result, columnSize); + } + parseResultByRow(queryResult, result, columnSize); + return queryResult; +} + +void MySQLStorage::parseMetaData( + QueryResult::Ptr _queryResult, SQLResultContext::Ptr const& _result, uint32_t _columnSize) const +{ + for (uint32_t col = 0; col < _columnSize; col++) + { + _queryResult->mutableMetaData().emplace_back( + std::string(mysqlx_column_get_name((mysqlx_result_t*)_result->result(), col))); + } +} + +// exec the sql-write-command: insert/update/delete +void MySQLStorage::execCommit(const char* _command, ...) const +{ + // parse the args + va_list args; + va_start(args, _command); + auto result = execSQL(_command, args); + va_end(args); + MYSQL_STORAGE_LOG(TRACE) << LOG_DESC("execCommit success: ") << _command; +} + +Statement::Ptr MySQLStorage::generateStatement(const char* _command, ...) const +{ + // parse the args + va_list args; + va_start(args, _command); + auto result = generateSQLStatement(_command, args); + va_end(args); + return result; +} + +SQLResultContext::Ptr MySQLStorage::execStatement(Statement::Ptr _statement) const +{ + auto stmt = (mysqlx_stmt_t*)(_statement->statementContext()); + // execute the sql command + auto res = mysqlx_execute(stmt); + if (!res) + { + auto errorMsg = mysqlx_error_message((void*)stmt); + MYSQL_STORAGE_LOG(ERROR) << LOG_DESC("execStatement error") + << LOG_KV("code", mysqlx_error((void*)stmt)) + << LOG_KV("msg", errorMsg ? errorMsg : "None"); + BOOST_THROW_EXCEPTION(ExecMySQLError() << bcos::errinfo_comment( + "exec sql error: " + std::string(errorMsg ? errorMsg : "None"))); + } + MYSQL_STORAGE_LOG(TRACE) << LOG_DESC("execStatement success"); + + auto result = std::make_shared((mysqlx_result_t*)res); + // takeSession from the statement + result->setSession(_statement->takeSession()); + result->setReturnSessionCallback( + boost::bind(&MySQLStorage::returnSession, this, boost::placeholders::_1)); + return result; +} + +void MySQLStorage::appendStatement(Statement::Ptr _statement, ...) const +{ + va_list args; + va_start(args, _statement); + appendStatement(_statement, args); + va_end(args); +} + +void MySQLStorage::appendStatement(Statement::Ptr _stmt, va_list& args) const +{ + auto stmt = (mysqlx_stmt_t*)(_stmt->statementContext()); + // get the data type + int type = va_arg(args, int); + while (type != (int)FieldDataType::TERMINATE) + { + // get the value + switch (type) + { + case FieldDataType::SINT: + { + bindStmt(stmt, PARAM_SINT(va_arg(args, int64_t)), PARAM_END); + break; + } + case FieldDataType::UINT: + { + bindStmt(stmt, PARAM_UINT(va_arg(args, uint64_t)), PARAM_END); + break; + } + case FieldDataType::DOUBLE: + case FieldDataType::FLOAT: + { + bindStmt(stmt, PARAM_FLOAT(va_arg(args, double)), PARAM_END); + break; + } + case FieldDataType::STRING: + { + bindStmt(stmt, PARAM_STRING(va_arg(args, char*)), PARAM_END); + break; + } + case FieldDataType::BYTES: + { + bcos::byte* data = va_arg(args, bcos::byte*); + size_t len = va_arg(args, size_t); + bindStmt(stmt, PARAM_BYTES(data, len), PARAM_END); + break; + } + default: + { + BOOST_THROW_EXCEPTION( + ExecMySQLError() << bcos::errinfo_comment( + "unsupported data type for statement: " + std::to_string(type))); + } + } + type = va_arg(args, int); + } +} + +Statement::Ptr MySQLStorage::generateSQLStatement(const char* _command, va_list& args) const +{ + auto session = allocateSession(); + // Note: the session will be return back when statement destroied + auto statement = std::make_shared( + mysqlx_sql_new(session, _command, MYSQLX_NULL_TERMINATED), session); + // for return session + statement->setReturnSessionCallback( + boost::bind(&MySQLStorage::returnSession, this, boost::placeholders::_1)); + MYSQL_STORAGE_LOG(TRACE) << LOG_DESC("generateSQLStatement") << LOG_KV("command", _command); + if (!statement->statementContext()) + { + auto errorMsgPtr = mysqlx_error_message(mysqlx_error((void*)session)); + std::string errorMsg = std::string(errorMsgPtr ? errorMsgPtr : "None"); + MYSQL_STORAGE_LOG(ERROR) << LOG_DESC("generateSQLStatement error") + << LOG_KV("command", _command) + << LOG_KV("code", mysqlx_error((void*)session)) + << LOG_KV("msg", errorMsg); + BOOST_THROW_EXCEPTION( + ExecMySQLError() << bcos::errinfo_comment("generate sql statement error: " + errorMsg)); + } + appendStatement(statement, args); + return statement; +} + +void MySQLStorage::parseResult(ppc::io::DataBatch::Ptr _result, + SQLResultContext::Ptr const& _mysqlResult, mysqlx_row_t* _rowData, uint32_t _col) const +{ + auto colType = mysqlx_column_get_type((mysqlx_result_t*)_mysqlResult->result(), _col); + switch (colType) + { + case mysqlx_data_type_enum::MYSQLX_TYPE_BOOL: + case mysqlx_data_type_enum::MYSQLX_TYPE_SINT: + { + int64_t element; + auto ret = mysqlx_get_sint(_rowData, _col, &element); + appendResult(_rowData, _result, ret, std::move(element)); + _result->setDataSchema(DataSchema::Sint); + break; + } + case mysqlx_data_type_enum::MYSQLX_TYPE_UINT: + { + uint64_t element; + auto ret = mysqlx_get_uint(_rowData, _col, &element); + appendResult(_rowData, _result, ret, std::move(element)); + _result->setDataSchema(DataSchema::Uint); + break; + } + case mysqlx_data_type_enum::MYSQLX_TYPE_DOUBLE: + { + double element; + auto ret = mysqlx_get_double(_rowData, _col, &element); + appendResult(_rowData, _result, ret, std::move(element)); + _result->setDataSchema(DataSchema::Double); + break; + } + case mysqlx_data_type_enum::MYSQLX_TYPE_FLOAT: + { + float element; + auto ret = mysqlx_get_float(_rowData, _col, &element); + appendResult(_rowData, _result, ret, std::move(element)); + _result->setDataSchema(DataSchema::Float); + break; + } + case mysqlx_data_type_enum::MYSQLX_TYPE_BYTES: + case mysqlx_data_type_enum::MYSQLX_TYPE_STRING: + { + bool readFinished = false; + uint64_t offset = 0; + _result->append(bcos::bytes()); + // Note: the huge data larger then c_maxElementLen will not been readed-finished at-one-time + while (!readFinished) + { + bcos::bytes element; + element.resize(c_maxElementLen); + // Note: the elementLen should not be zero, otherwise, will trigger "The output buffer + // cannot have zero length" error + size_t elementLen = element.size(); + auto ret = mysqlx_get_bytes(_rowData, _col, offset, (void*)element.data(), &elementLen); + offset += elementLen; + readFinished = appendResult(_rowData, _result, ret, bcos::bytes(), false); + // append the element to line + _result->appendToLine(std::move(element)); + } + // Note: the last one 0x00-bytes means terminate, should been ignored + _result->resizeElement(_result->size() - 1, offset - 1); + _result->setDataSchema(DataSchema::Bytes); + break; + } + default: + { + BOOST_THROW_EXCEPTION(ParseMySQLResultError() << bcos::errinfo_comment( + "unsupported data type: " + std::to_string(colType))); + } + } +} + +void MySQLStorage::parseResultByColumn( + QueryResult::Ptr _queryResult, SQLResultContext::Ptr const& _result, uint32_t _columnSize) const +{ + _queryResult->mutableData().resize(_columnSize); + for (uint64_t i = 0; i < _columnSize; i++) + { + auto batchData = std::make_shared(); + _queryResult->mutableData()[i] = (std::move(batchData)); + } + + while (auto rowData = mysqlx_row_fetch_one((mysqlx_result_t*)_result->result())) + { + for (uint32_t col = 0; col < _columnSize; col++) + { + parseResult((_queryResult->mutableData())[col], _result, rowData, col); + } + } +} + +void MySQLStorage::parseResultByRow( + QueryResult::Ptr _queryResult, SQLResultContext::Ptr const& _result, uint32_t _columnSize) const +{ + while (auto rowData = mysqlx_row_fetch_one((mysqlx_result_t*)_result->result())) + { + auto batchData = std::make_shared(); + for (uint32_t col = 0; col < _columnSize; col++) + { + parseResult(batchData, _result, rowData, col); + } + _queryResult->mutableData().emplace_back(std::move(batchData)); + } +} diff --git a/cpp/wedpr-storage/ppc-storage/src/mysql/MySQLStorage.h b/cpp/wedpr-storage/ppc-storage/src/mysql/MySQLStorage.h new file mode 100644 index 00000000..ad3feef7 --- /dev/null +++ b/cpp/wedpr-storage/ppc-storage/src/mysql/MySQLStorage.h @@ -0,0 +1,271 @@ +/* + * Copyright (C) 2022 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 MySQLStorage.h + * @author: yujiechen + * @date 2022-10-25 + */ +#pragma once +#include "Common.h" +#include "ppc-framework/storage/SQLStorage.h" +#include +#include +#include + +namespace ppc::storage +{ +class MySQLStatement : public Statement +{ +public: + using Ptr = std::shared_ptr; + MySQLStatement(mysqlx_stmt_t* _statement, mysqlx_session_t* _session) + : m_statement(_statement), m_session(_session) + {} + + ~MySQLStatement() override + { + // return the session + if (m_callback) + { + m_callback(m_session); + } + } + + void* statementContext() override { return (void*)m_statement; } + void* takeSession() override + { + auto session = m_session; + m_session = nullptr; + return (void*)session; + } + + void setReturnSessionCallback(std::function const& _callback) + { + m_callback = _callback; + } + +private: + mysqlx_stmt_t* m_statement; + mysqlx_session_t* m_session; + std::function m_callback; +}; + +class MySQLResultContext : public SQLResultContext +{ +public: + using Ptr = std::shared_ptr; + MySQLResultContext(mysqlx_result_t* _result) : m_result(_result) {} + ~MySQLResultContext() override + { + if (m_result) + { + mysqlx_free(m_result); + } + if (m_callback) + { + m_callback(m_session); + } + } + + // get the sql-result + void* result() override { return (void*)m_result; } + virtual void setSession(void* _session) { m_session = (mysqlx_session_t*)_session; } + + void setReturnSessionCallback(std::function const& _callback) + { + m_callback = _callback; + } + +private: + mysqlx_result_t* m_result; + mysqlx_session_t* m_session; + std::function m_callback; +}; + +class MySQLStorage : public SQLStorage +{ +public: + // TODO: configure the session-pool-size + using Ptr = std::shared_ptr; + MySQLStorage( + ppc::protocol::SQLConnectionOption::Ptr const& _opt, uint16_t _sessionPoolSize = 16); + ~MySQLStorage() override + { + if (m_timer) + { + m_timer->stop(); + } + destroyAllSession(); + } + + // use the database + void useDataBase(const char* _database) override; + + // exec the sql-query-command, throws exception when query-error + QueryResult::Ptr execQuery(bool _parseByColumn, const char* _command, ...) const override; + // exec the sql-write-command: insert/update/delete, throws exception when exec-error + void execCommit(const char* _command, ...) const override; + + std::string const& databaseName() const override { return m_opt->database; } + + Statement::Ptr generateStatement(const char* _command, ...) const override; + SQLResultContext::Ptr execStatement(Statement::Ptr _statement) const override; + void appendStatement(Statement::Ptr _statement, ...) const override; + +protected: + virtual void refreshConnection(); + virtual mysqlx_session_t* connectDataBase(const char* _database, bool _disableSSl) const; + mysqlx_session_t* createSession() const; + virtual void destroySession(mysqlx_session_t* _session) const + { + if (_session) + { + // close the session + mysqlx_session_close(_session); + } + } + // destroy the current session + virtual void destroyAllSession() + { + std::vector sessionPool; + { + bcos::WriteGuard l(x_sessionPool); + sessionPool.swap(m_sessionPool); + } + for (auto const& it : sessionPool) + { + destroySession(it); + } + } + + void parseMetaData(QueryResult::Ptr _queryResult, SQLResultContext::Ptr const& _result, + uint32_t _columnSize) const; + + // parse the queried-result by row + void parseResultByRow(QueryResult::Ptr _queryResult, SQLResultContext::Ptr const& _result, + uint32_t _columnSize) const; + // parse the queried result by column + void parseResultByColumn(QueryResult::Ptr _queryResult, SQLResultContext::Ptr const& _result, + uint32_t _columnSize) const; + // parse the result according to the type + void parseResult(ppc::io::DataBatch::Ptr _result, SQLResultContext::Ptr const& _mysqlResult, + mysqlx_row_t* _rowData, uint32_t _col) const; + + template + bool inline appendResult(mysqlx_row_t* _rowData, ppc::io::DataBatch::Ptr _result, int _retCode, + T&& _element, bool _append = true) const + { + bool readFinished = true; + if (RESULT_ERROR == _retCode) + { + std::string errorMsg = mysqlx_error_message(_rowData); + BOOST_THROW_EXCEPTION(ParseMySQLResultError() << bcos::errinfo_comment( + "parse sql-result error, code:" + std::to_string(_retCode) + + ", error: " + errorMsg)); + } + // the data has not been read-finished yet + if (RESULT_MORE_DATA == _retCode) + { + readFinished = false; + } + if (_append) + { + _result->append(std::move(_element)); + } + return readFinished; + } + + template + void bindStmt(mysqlx_stmt_t* stmt, Args... args) const + { + auto result = mysqlx_stmt_bind(stmt, args...); + if (result != RESULT_OK) + { + MYSQL_STORAGE_LOG(ERROR) << LOG_DESC("bindStmt error") << LOG_KV("code", result) + << LOG_KV("msg", mysqlx_error_message(stmt)); + BOOST_THROW_EXCEPTION( + ExecMySQLError() << bcos::errinfo_comment( + "bindStmt error: " + std::string(mysqlx_error_message(stmt)))); + } + } + + Statement::Ptr generateSQLStatement(const char* _command, va_list& _args) const; + void appendStatement(Statement::Ptr stmt, va_list& args) const; + + SQLResultContext::Ptr execSQL(const char* _command, va_list& _args) const + { + auto statement = generateSQLStatement(_command, _args); + return execStatement(statement); + } + + + mysqlx_session_t* allocateSession() const + { + // Note: can't new multiple mysql-session at the same times + bcos::WriteGuard l(x_sessionPool); + // all session has been used-up, allocate a new session + if (m_sessionPool.empty()) + { + MYSQL_STORAGE_LOG(DEBUG) << LOG_DESC("allocateSession for the session pool is empty"); + return createSession(); + } + MYSQL_STORAGE_LOG(DEBUG) << LOG_DESC("allocateSession from the session pool") + << LOG_KV("poolSize", m_sessionPool.size()); + // obtain session from the sessionPool + auto session = m_sessionPool.back(); + m_sessionPool.pop_back(); + return session; + } + + // Note: the session can be only returned after the result obtained + void returnSession(mysqlx_session_t* _session) const + { + if (!_session) + { + return; + } + bcos::UpgradableGuard l(x_sessionPool); + if (m_sessionPool.size() >= m_sessionPoolSize) + { + MYSQL_STORAGE_LOG(DEBUG) + << LOG_DESC("returnSession: destroy the session for the pool-size over limit") + << LOG_KV("poolSize", m_sessionPool.size()); + destroySession(_session); + return; + } + bcos::UpgradeGuard ul(l); + m_sessionPool.emplace_back(_session); + MYSQL_STORAGE_LOG(DEBUG) << LOG_DESC("returnSession") + << LOG_KV("poolSize", m_sessionPool.size()); + } + + void insertSession(mysqlx_session_t* _session) + { + bcos::WriteGuard l(x_sessionPool); + m_sessionPool.emplace_back(_session); + } + +private: + ppc::protocol::SQLConnectionOption::Ptr m_opt; + // TODO: support session-pool + std::vector mutable m_sessionPool; + bcos::SharedMutex mutable x_sessionPool; + + uint16_t m_sessionPoolSize = 16; + std::shared_ptr m_timer; + + int const c_maxElementLen = 65536; +}; +} // namespace ppc::storage \ No newline at end of file diff --git a/cpp/wedpr-storage/ppc-storage/src/redis/RedisStorage.cpp b/cpp/wedpr-storage/ppc-storage/src/redis/RedisStorage.cpp new file mode 100644 index 00000000..2a057110 --- /dev/null +++ b/cpp/wedpr-storage/ppc-storage/src/redis/RedisStorage.cpp @@ -0,0 +1,62 @@ +/** + * Copyright (C) 2022 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 RedisStorage.cpp + * @author: yujiechen + * @date 2022-10-24 + */ +#include "RedisStorage.h" +#include + +using namespace ppc::storage; +using namespace sw::redis; + +bool RedisStorage::exists(const std::string& _key) +{ + // return 1 if key exists; return 0 if key doesn't exist + return (m_redis->exists(_key) == 0 ? false : true); +} + +void RedisStorage::setValue( + const std::string& _key, const std::string& _value, int32_t _expirationSeconds) +{ + m_redis->set(_key, _value); + // Note: when _expirationSeconds is set to -1, never trigger expiration + if (_expirationSeconds) + { + expireKey(_key, _expirationSeconds); + } +} + +// std::nullopt if the key doesn't exist +std::optional RedisStorage::getValue(const std::string& _key) +{ + OptionalString result = m_redis->get(_key); + if (!result) + { + return std::nullopt; + } + return std::string(result.value()); +} + +bool RedisStorage::expireKey(const std::string& _key, uint32_t _expirationSeconds) +{ + return m_redis->expire(_key, _expirationSeconds); +} + +uint64_t RedisStorage::deleteKey(const std::string& _key) +{ + return m_redis->del(_key); +} diff --git a/cpp/wedpr-storage/ppc-storage/src/redis/RedisStorage.h b/cpp/wedpr-storage/ppc-storage/src/redis/RedisStorage.h new file mode 100644 index 00000000..374c2030 --- /dev/null +++ b/cpp/wedpr-storage/ppc-storage/src/redis/RedisStorage.h @@ -0,0 +1,80 @@ +/** + * Copyright (C) 2022 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 RedisStorage.h + * @author: yujiechen + * @date 2022-10-24 + */ +#pragma once + +#include "ppc-framework/storage/CacheStorage.h" +#include + +namespace ppc::storage +{ + +class RedisStorage : public CacheStorage +{ +public: + using Ptr = std::shared_ptr; + RedisStorage(const sw::redis::ConnectionOptions& _connectionOpts, + const sw::redis::ConnectionPoolOptions& _poolOptions) + { + m_redis = std::make_shared(_connectionOpts, _poolOptions); + } + ~RedisStorage() override {} + +public: + /// Note: all these interfaces throws exception when error happened + /** + * @brief: check whether the key exists + * @param _key: key + * @return whether the key exists + */ + bool exists(const std::string& _key) override; + + /** + * @brief: set key value + * @param _expirationTime: timeout of key, seconds + */ + void setValue(const std::string& _key, const std::string& _value, + int32_t _expirationSeconds = -1) override; + + /** + * @brief: get value by key + * @param _key: key + * @return value + */ + std::optional getValue(const std::string& _key) override; + + /** + * @brief: set a timeout on key + * @param _expirationTime: timeout of key, ms + * @return whether setting is successful + */ + bool expireKey(const std::string& _key, uint32_t _expirationTime) override; + + /** + * @brief: delete key + * @param _key: key + * @return the number of key deleted + */ + uint64_t deleteKey(const std::string& _key) override; + +private: + std::shared_ptr m_redis; +}; + +} // namespace ppc::storage \ No newline at end of file diff --git a/cpp/wedpr-transport/ppc-front/CMakeLists.txt b/cpp/wedpr-transport/ppc-front/CMakeLists.txt new file mode 100644 index 00000000..8966cbae --- /dev/null +++ b/cpp/wedpr-transport/ppc-front/CMakeLists.txt @@ -0,0 +1,13 @@ +cmake_minimum_required(VERSION 3.14) + +aux_source_directory(ppc-front SRCS) + + +add_library(${FRONT_TARGET} ${SRCS}) +target_link_libraries(${FRONT_TARGET} PUBLIC ${TARS_PROTOCOL_TARGET} TBB::tbb) + +#if (TESTS) +# enable_testing() +# set(CTEST_OUTPUT_ON_FAILURE TRUE) +# add_subdirectory(test) +#endif () \ No newline at end of file diff --git a/cpp/wedpr-transport/ppc-front/ppc-front/CallbackManager.cpp b/cpp/wedpr-transport/ppc-front/ppc-front/CallbackManager.cpp new file mode 100644 index 00000000..e32a1be6 --- /dev/null +++ b/cpp/wedpr-transport/ppc-front/ppc-front/CallbackManager.cpp @@ -0,0 +1,199 @@ +/** + * 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 CallbackManager.cpp + * @author: yujiechen + * @date 2024-08-30 + */ +#include "CallbackManager.h" +#include "Common.h" +#include "ppc-framework/protocol/Protocol.h" +#include + +using namespace bcos; +using namespace ppc; +using namespace ppc::front; +using namespace ppc::protocol; + +void CallbackManager::addCallback( + std::string const& traceID, long timeout, ppc::protocol::MessageCallback msgCallback) +{ + if (!msgCallback) + { + return; + } + auto callback = std::make_shared(msgCallback); + // set the timeout handler + if (timeout > 0) + { + callback->timeoutHandler = std::make_shared( + *m_ioService, boost::posix_time::milliseconds(timeout)); + auto self = weak_from_this(); + callback->timeoutHandler->async_wait([self, traceID](const boost::system::error_code& e) { + auto front = self.lock(); + if (front) + { + front->onMessageTimeout(e, traceID); + } + }); + } + // insert the callback into m_traceID2Callback + WriteGuard l(x_traceID2Callback); + m_traceID2Callback.insert(std::make_pair(traceID, callback)); +} + +Callback::Ptr CallbackManager::pop(std::string const& traceID) +{ + bcos::UpgradableGuard l(x_traceID2Callback); + auto it = m_traceID2Callback.find(traceID); + if (it == m_traceID2Callback.end()) + { + return nullptr; + } + auto callback = it->second; + m_traceID2Callback.erase(it); + return callback; +} + +void CallbackManager::onMessageTimeout( + const boost::system::error_code& e, std::string const& traceID) +{ + // the timer has been canceled + if (e) + { + return; + } + try + { + auto callback = pop(traceID); + if (!callback) + { + return; + } + if (callback->timeoutHandler) + { + callback->timeoutHandler->cancel(); + } + auto errorMsg = "send message with traceID=" + traceID + " timeout"; + auto error = std::make_shared(PPCRetCode::TIMEOUT, errorMsg); + m_threadPool->enqueue( + [callback, error]() { callback->msgCallback(error, nullptr, nullptr); }); + FRONT_LOG(WARNING) << LOG_BADGE("onMessageTimeout") << LOG_KV("traceID", traceID); + } + catch (std::exception const& e) + { + FRONT_LOG(WARNING) << LOG_BADGE("onMessageTimeout") << LOG_KV("traceID", traceID) + << LOG_KV("error", boost::diagnostic_information(e)); + } +} + + +void CallbackManager::handleCallback(bcos::Error::Ptr const& error, std::string const& traceID, + Message::Ptr message, SendResponseFunction resFunc) +{ + auto callback = pop(traceID); + if (!callback) + { + return; + } + if (callback->timeoutHandler) + { + callback->timeoutHandler->cancel(); + } + if (!message) + { + return; + } + m_threadPool->enqueue([error, callback, message, resFunc] { + try + { + callback->msgCallback(error, message, resFunc); + } + catch (std::exception const& e) + { + FRONT_LOG(WARNING) << LOG_DESC("handleCallback exception") + << LOG_KV("error", boost::diagnostic_information(e)); + } + }); +} + + +void CallbackManager::registerTopicHandler( + std::string const& topic, ppc::protocol::MessageDispatcherCallback callback) +{ + bcos::WriteGuard l(x_topicHandlers); + m_topicHandlers.insert(std::make_pair(topic, callback)); +} + +void CallbackManager::registerMessageHandler( + std::string const& componentType, ppc::protocol::MessageDispatcherCallback callback) +{ + bcos::WriteGuard l(x_msgHandlers); + m_msgHandlers.insert(std::make_pair(componentType, callback)); +} + +MessageDispatcherCallback CallbackManager::getHandlerByTopic(std::string const& topic) +{ + bcos::ReadGuard l(x_topicHandlers); + auto it = m_topicHandlers.find(topic); + if (it != m_topicHandlers.end()) + { + return it->second; + } + return nullptr; +} + +MessageDispatcherCallback CallbackManager::getHandlerByComponentType( + std::string const& componentType) +{ + bcos::ReadGuard l(x_msgHandlers); + auto it = m_msgHandlers.find(componentType); + if (it != m_msgHandlers.end()) + { + return it->second; + } + return nullptr; +} + +void CallbackManager::onReceiveMessage(std::string const& topic, Message::Ptr msg) +{ + auto callback = getHandlerByTopic(topic); + if (!callback) + { + callback = getHandlerByComponentType(msg->header()->optionalField()->componentType()); + } + if (!callback) + { + if (topic.empty()) + { + return; + } + FRONT_LOG(TRACE) << LOG_DESC("onReceiveMessage: not find the handler, put into the buffer") + << LOG_KV("topic", topic); + addMsgCache(topic, msg); + return; + } + m_threadPool->enqueue([callback, msg]() { + try + { + callback(std::move(msg)); + } + catch (Exception e) + { + FRONT_LOG(WARNING) << LOG_DESC("onReceiveMessage: dispatcher exception") + << LOG_KV("error", boost::diagnostic_information(e)); + } + }); +} \ No newline at end of file diff --git a/cpp/wedpr-transport/ppc-front/ppc-front/CallbackManager.h b/cpp/wedpr-transport/ppc-front/ppc-front/CallbackManager.h new file mode 100644 index 00000000..819faa05 --- /dev/null +++ b/cpp/wedpr-transport/ppc-front/ppc-front/CallbackManager.h @@ -0,0 +1,124 @@ +/** + * 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 CallbackManager.h + * @author: yujiechen + * @date 2024-08-30 + */ +#pragma once +#include "ppc-framework/protocol/Message.h" +#include +#include +#include +#include +#include +#include +#define TBB_PREVIEW_CONCURRENT_ORDERED_CONTAINERS 1 +#include +#include + +namespace ppc::front +{ +class Callback +{ +public: + using Ptr = std::shared_ptr; + Callback(ppc::protocol::MessageCallback callback) : msgCallback(std::move(callback)) {} + + ppc::protocol::MessageCallback msgCallback; + std::shared_ptr timeoutHandler; +}; +class CallbackManager : public std::enable_shared_from_this +{ +public: + using MsgQueueType = bcos::ConcurrentQueue; + using Ptr = std::shared_ptr; + CallbackManager( + bcos::ThreadPool::Ptr threadPool, std::shared_ptr ioService) + : m_threadPool(std::move(threadPool)), m_ioService(std::move(ioService)) + {} + virtual ~CallbackManager() = default; + + virtual void addCallback( + std::string const& traceID, long timeout, ppc::protocol::MessageCallback msgCallback); + + virtual Callback::Ptr pop(std::string const& traceID); + + virtual void handleCallback(bcos::Error::Ptr const& error, std::string const& traceID, + ppc::protocol::Message::Ptr message, ppc::protocol::SendResponseFunction resFunc); + + virtual void onReceiveMessage(std::string const& topic, ppc::protocol::Message::Ptr msg); + + virtual void registerTopicHandler( + std::string const& topic, ppc::protocol::MessageDispatcherCallback callback); + + virtual void registerMessageHandler( + std::string const& componentType, ppc::protocol::MessageDispatcherCallback callback); + + virtual ppc::protocol::Message::Ptr pop(std::string const& topic, int timeoutMs) + { + auto it = m_msgCache.find(topic); + if (it == m_msgCache.end()) + { + return nullptr; + } + auto msgQueue = it->second; + if (msgQueue->empty()) + { + return nullptr; + } + auto result = msgQueue->tryPop(timeoutMs); + return result.second; + } + +private: + void onMessageTimeout(const boost::system::error_code& e, std::string const& traceID); + void addMsgCache(std::string const& topic, ppc::protocol::Message::Ptr msg) + { + auto it = m_msgCache.find(topic); + if (it == m_msgCache.end()) + { + m_msgCache.insert(std::make_pair(topic, std::make_shared())); + } + auto msgQueue = m_msgCache[topic]; + // push + msgQueue->push(std::move(msg)); + } + + ppc::protocol::MessageDispatcherCallback getHandlerByTopic(std::string const& topic); + ppc::protocol::MessageDispatcherCallback getHandlerByComponentType( + std::string const& componentType); + +private: + bcos::ThreadPool::Ptr m_threadPool; + std::shared_ptr m_ioService; + // traceID => callback + std::unordered_map m_traceID2Callback; + mutable bcos::SharedMutex x_traceID2Callback; + + // topic => messageDispatcherCallback + std::map m_topicHandlers; + mutable bcos::SharedMutex x_topicHandlers; + + // componentType => messageDispatcherCallback + std::map m_msgHandlers; + mutable bcos::SharedMutex x_msgHandlers; + + // the messageCache for the message with no topic handler defined + uint64_t m_maxMsgCacheSize = 10000; + // TODO: check the queueSize + tbb::concurrent_unordered_map> m_msgCache; +}; +} // namespace ppc::front \ No newline at end of file diff --git a/cpp/wedpr-transport/ppc-front/ppc-front/Common.h b/cpp/wedpr-transport/ppc-front/ppc-front/Common.h new file mode 100644 index 00000000..74b24cd2 --- /dev/null +++ b/cpp/wedpr-transport/ppc-front/ppc-front/Common.h @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2022 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 Common.h + * @author: shawnhe + * @date 2022-10-25 + */ + +#pragma once +#include "ppc-framework/Common.h" +#include +#include +#include +#include +#include +#include +#include +#include + +namespace ppc::front +{ +#define FRONT_LOG(LEVEL) BCOS_LOG(LEVEL) << "[FRONT]" + +#define HOLDING_MESSAGE_TIMEOUT_M 30 +#define CHANNEL_THREAD_POOL_MODULE "t_channel_manager" + +} // namespace ppc::front \ No newline at end of file diff --git a/cpp/wedpr-transport/ppc-front/ppc-front/Front.cpp b/cpp/wedpr-transport/ppc-front/ppc-front/Front.cpp new file mode 100644 index 00000000..ed974de0 --- /dev/null +++ b/cpp/wedpr-transport/ppc-front/ppc-front/Front.cpp @@ -0,0 +1,211 @@ +/** + * Copyright (C) 2022 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 Front.cpp + * @author: shawnhe + * @date 2022-10-20 + */ +#include "Front.h" +#include "FrontImpl.h" +#include "ppc-framework/protocol/Constant.h" +#include "ppc-utilities/Utilities.h" + +using namespace ppc; +using namespace bcos; +using namespace ppc::protocol; +using namespace ppc::front; + +Front::Front(ppc::front::PPCMessageFaceFactory::Ptr ppcMsgFactory, IFront::Ptr front) + : m_messageFactory(std::move(ppcMsgFactory)), m_front(std::move(front)) +{ + m_fetcher = std::make_shared(10 * 1000, "metaFetcher"); + m_fetcher->registerTimeoutHandler([this]() { + try + { + fetchGatewayMetaInfo(); + } + catch (std::exception const& e) + { + FRONT_LOG(WARNING) << LOG_DESC("fetch the gateway information failed") + << LOG_KV("error", boost::diagnostic_information(e)); + } + }); +} + +void Front::start() +{ + m_front->start(); + m_fetcher->start(); +} + +void Front::stop() +{ + m_fetcher->stop(); + m_front->stop(); +} + +void Front::fetchGatewayMetaInfo() +{ + auto self = weak_from_this(); + m_front->asyncGetAgencies(m_front->nodeInfo()->copiedComponents(), + [self](bcos::Error::Ptr error, std::set agencies) { + auto front = self.lock(); + if (!front) + { + return; + } + if (error && error->errorCode() != 0) + { + FRONT_LOG(WARNING) + << LOG_DESC("asyncGetAgencies failed") << LOG_KV("code", error->errorCode()) + << LOG_KV("msg", error->errorMessage()); + return; + } + std::vector agencyList(agencies.begin(), agencies.end()); + bcos::UpgradableGuard l(front->x_agencyList); + if (front->m_agencyList == agencyList) + { + return; + } + bcos::UpgradeGuard ul(l); + front->m_agencyList = agencyList; + FRONT_LOG(INFO) << LOG_DESC("Update agencies information") + << LOG_KV("agencies", printVector(agencyList)); + }); + m_fetcher->restart(); +} + +/** + * @brief: send message to other party by gateway + * @param _agencyID: agency ID of receiver + * @param _message: ppc message data + * @param _callback: callback called when the message sent successfully + * @param _respCallback: callback called when receive the response from peer + * @return void + */ +void Front::asyncSendMessage(const std::string& _agencyID, front::PPCMessageFace::Ptr _message, + uint32_t _timeout, ErrorCallbackFunc _callback, CallbackFunc _respCallback) +{ + auto front = std::dynamic_pointer_cast(m_front); + auto routeInfo = front->routerInfoBuilder()->build(); + routeInfo->setDstInst(_agencyID); + routeInfo->setTopic(_message->taskID()); + auto type = ((uint16_t)_message->taskType() << 8) | _message->algorithmType(); + routeInfo->setComponentType(std::to_string(type)); + bcos::bytes data; + _message->encode(data); + auto self = weak_from_this(); + ppc::protocol::MessageCallback msgCallback = nullptr; + if (_respCallback) + { + msgCallback = [self, _agencyID, _respCallback]( + Error::Ptr error, Message::Ptr msg, SendResponseFunction resFunc) { + auto front = self.lock(); + if (!front) + { + return; + } + auto responseCallback = [resFunc](PPCMessageFace::Ptr msg) { + if (!msg) + { + return; + } + std::shared_ptr payload = std::make_shared(); + msg->encode(*payload); + resFunc(std::move(payload)); + }; + if (msg == nullptr) + { + _respCallback(error, _agencyID, nullptr, responseCallback); + } + // get the agencyID + _respCallback(error, msg->header()->optionalField()->srcInst(), + front->m_messageFactory->decodePPCMessage(msg), responseCallback); + }; + } + // ROUTE_THROUGH_TOPIC will hold the topic + m_front->asyncSendMessage((uint16_t)RouteType::ROUTE_THROUGH_TOPIC, routeInfo, + bcos::bytesConstRef((bcos::byte*)data.data(), data.size()), _message->seq(), _timeout, + _callback, msgCallback); + // release the data + bcos::bytes().swap(data); +} + +// send response when receiving message from given agencyID +void Front::asyncSendResponse(bcos::bytes const& dstNode, std::string const& traceID, + PPCMessageFace::Ptr message, ErrorCallbackFunc _callback) +{ + bcos::bytes data; + message->encode(data); + m_front->asyncSendResponse(bcos::bytesConstRef((bcos::byte*)dstNode.data(), dstNode.size()), + traceID, bcos::bytesConstRef((bcos::byte*)data.data(), data.size()), 0, _callback); +} + +/** + * @brief notice task info to gateway + * @param _taskInfo the latest task information + */ +bcos::Error::Ptr Front::notifyTaskInfo(std::string const& taskID) +{ + return m_front->registerTopic(taskID); +} + +// erase the task-info when task finished +bcos::Error::Ptr Front::eraseTaskInfo(std::string const& _taskID) +{ + FRONT_LOG(INFO) << LOG_DESC("eraseTaskInfo") << LOG_KV("front", m_front); + return m_front->unRegisterTopic(_taskID); +} + +// register message handler for algorithm +void Front::registerMessageHandler(uint8_t _taskType, uint8_t _algorithmType, + std::function _handler) +{ + uint16_t type = ((uint16_t)_taskType << 8) | _algorithmType; + auto self = weak_from_this(); + m_front->registerMessageHandler(std::to_string(type), [self, type, _handler]( + ppc::protocol::Message::Ptr msg) { + auto front = self.lock(); + if (!front) + { + return; + } + try + { + if (msg == nullptr) + { + _handler(nullptr); + return; + } + _handler(front->m_messageFactory->decodePPCMessage(msg)); + auto length = msg->length(); + // release the payload of the large packet after the msg decoded + if (length >= ppc::protocol::LARGE_MSG_THRESHOLD) + { + FRONT_LOG(INFO) << LOG_DESC("RecvMsg: Release large payload for node after used") + << LOG_KV("msgSize", length); + // release the payload + msg->releasePayload(); + } + } + catch (std::exception const& e) + { + FRONT_LOG(WARNING) << LOG_DESC("Call handler for component failed") + << LOG_KV("componentType", type) + << LOG_KV("error", boost::diagnostic_information(e)); + } + }); + m_front->registerComponent(std::to_string(type)); +} \ No newline at end of file diff --git a/cpp/wedpr-transport/ppc-front/ppc-front/Front.h b/cpp/wedpr-transport/ppc-front/ppc-front/Front.h new file mode 100644 index 00000000..5ddd224b --- /dev/null +++ b/cpp/wedpr-transport/ppc-front/ppc-front/Front.h @@ -0,0 +1,86 @@ +/** + * Copyright (C) 2022 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 Front.h + * @author: shawnhe + * @date 2022-10-20 + */ + +#pragma once +#include "bcos-utilities/Timer.h" +#include "ppc-framework/front/FrontInterface.h" +#include "ppc-framework/front/IFront.h" +#include "ppc-framework/protocol/PPCMessageFace.h" + +namespace ppc::front +{ +class Front : public FrontInterface, public std::enable_shared_from_this +{ +public: + using Ptr = std::shared_ptr; + Front(ppc::front::PPCMessageFaceFactory::Ptr ppcMsgFactory, IFront::Ptr front); + ~Front() override {} + + void start() override; + void stop() override; + + /** + * @brief: send message to other party by gateway + * @param _agencyID: agency ID of receiver + * @param _message: ppc message data + * @param _callback: callback called when the message sent successfully + * @param _respCallback: callback called when receive the response from peer + * @return void + */ + void asyncSendMessage(const std::string& _agencyID, front::PPCMessageFace::Ptr _message, + uint32_t _timeout, ErrorCallbackFunc _callback, CallbackFunc _respCallback) override; + + // send response when receiving message from given agencyID + void asyncSendResponse(bcos::bytes const& dstNode, std::string const& traceID, + front::PPCMessageFace::Ptr message, ErrorCallbackFunc _callback) override; + /** + * @brief notice task info to gateway + * @param _taskInfo the latest task information + */ + bcos::Error::Ptr notifyTaskInfo(std::string const& taskID) override; + + // erase the task-info when task finished + bcos::Error::Ptr eraseTaskInfo(std::string const& _taskID) override; + + // register message handler for algorithm + void registerMessageHandler(uint8_t _taskType, uint8_t _algorithmType, + std::function _handler) override; + + std::vector agencies() const override + { + bcos::ReadGuard l(x_agencyList); + return m_agencyList; + } + +protected: + void fetchGatewayMetaInfo(); + +private: + IFront::Ptr m_front; + + // the agency list + std::vector m_agencyList; + mutable bcos::SharedMutex x_agencyList; + + std::shared_ptr m_fetcher; + + ppc::front::PPCMessageFaceFactory::Ptr m_messageFactory; +}; +} // namespace ppc::front \ No newline at end of file diff --git a/cpp/wedpr-transport/ppc-front/ppc-front/FrontConfigImpl.h b/cpp/wedpr-transport/ppc-front/ppc-front/FrontConfigImpl.h new file mode 100644 index 00000000..0e294403 --- /dev/null +++ b/cpp/wedpr-transport/ppc-front/ppc-front/FrontConfigImpl.h @@ -0,0 +1,77 @@ +/** + * 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 FrontConfigImpl.h + * @author: yujiechen + * @date 2024-08-22 + */ + +#pragma once +#include "ppc-framework/front/FrontConfig.h" +#include "ppc-framework/protocol/INodeInfo.h" +#include + +namespace ppc::front +{ +class FrontConfigImpl : public FrontConfig +{ +public: + using Ptr = std::shared_ptr; + FrontConfigImpl(ppc::protocol::INodeInfoFactory::Ptr nodeInfoFactory) + : FrontConfig(), m_nodeInfoFactory(std::move(nodeInfoFactory)) + {} + FrontConfigImpl(ppc::protocol::INodeInfoFactory::Ptr nodeInfoFactory, int threadPoolSize, + std::string nodeID) + : FrontConfig(threadPoolSize, nodeID), m_nodeInfoFactory(std::move(nodeInfoFactory)) + {} + + ~FrontConfigImpl() override = default; + + ppc::protocol::INodeInfo::Ptr generateNodeInfo() const override + { + auto nodeInfo = m_nodeInfoFactory->build( + bcos::bytesConstRef((bcos::byte*)m_nodeID.data(), m_nodeID.size()), + m_selfEndPoint.entryPoint()); + nodeInfo->setComponents(std::set(m_components.begin(), m_components.end())); + return nodeInfo; + } + +private: + ppc::protocol::INodeInfoFactory::Ptr m_nodeInfoFactory; +}; + +class FrontConfigBuilderImpl : public FrontConfigBuilder +{ +public: + using Ptr = std::shared_ptr; + FrontConfigBuilderImpl(ppc::protocol::INodeInfoFactory::Ptr nodeInfoFactory) + : m_nodeInfoFactory(nodeInfoFactory) + {} + ~FrontConfigBuilderImpl() override = default; + + FrontConfig::Ptr build() const override + { + return std::make_shared(m_nodeInfoFactory); + } + FrontConfig::Ptr build(int threadPoolSize, std::string nodeID) const override + { + return std::make_shared( + m_nodeInfoFactory, threadPoolSize, std::move(nodeID)); + } + +private: + ppc::protocol::INodeInfoFactory::Ptr m_nodeInfoFactory; +}; +} // namespace ppc::front diff --git a/cpp/wedpr-transport/ppc-front/ppc-front/FrontFactory.cpp b/cpp/wedpr-transport/ppc-front/ppc-front/FrontFactory.cpp new file mode 100644 index 00000000..d2359786 --- /dev/null +++ b/cpp/wedpr-transport/ppc-front/ppc-front/FrontFactory.cpp @@ -0,0 +1,46 @@ +/** + * 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 FrontFactory.cpp + * @author: yujiechen + * @date 2024-9-04 + */ +#include "FrontFactory.h" +#include "FrontImpl.h" + +using namespace ppc::front; +using namespace ppc::protocol; + +IFront::Ptr FrontFactory::build(INodeInfoFactory::Ptr nodeInfoFactory, + MessagePayloadBuilder::Ptr messageFactory, MessageOptionalHeaderBuilder::Ptr routerInfoBuilder, + ppc::gateway::IGateway::Ptr const& gateway, FrontConfig::Ptr config) +{ + auto threadPool = std::make_shared("front", config->threadPoolSize()); + auto nodeInfo = nodeInfoFactory->build( + bcos::bytesConstRef((bcos::byte*)config->nodeID().data(), config->nodeID().size()), + config->selfEndPoint().entryPoint()); + // set the component information + auto configuredComponents = config->getComponents(); + nodeInfo->setComponents( + std::set(configuredComponents.begin(), configuredComponents.end())); + // set the meta + nodeInfo->setMeta(config->meta()); + + FRONT_LOG(INFO) << LOG_DESC("build front") << LOG_KV("nodeID", config->nodeID()) + << LOG_KV("endPoint", config->selfEndPoint().entryPoint()) + << LOG_KV("meta", config->meta()); + return std::make_shared(threadPool, nodeInfo, messageFactory, routerInfoBuilder, + gateway, std::make_shared()); +} \ No newline at end of file diff --git a/cpp/wedpr-transport/ppc-front/ppc-front/FrontFactory.h b/cpp/wedpr-transport/ppc-front/ppc-front/FrontFactory.h new file mode 100644 index 00000000..1d29ca90 --- /dev/null +++ b/cpp/wedpr-transport/ppc-front/ppc-front/FrontFactory.h @@ -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 FrontFactory.h + * @author: yujiechen + * @date 2024-9-04 + */ +#pragma once +#include "ppc-framework/front/FrontConfig.h" +#include "ppc-framework/front/IFront.h" +#include "ppc-framework/gateway/IGateway.h" +#include "ppc-framework/protocol/INodeInfo.h" + +namespace ppc::front +{ +class FrontFactory +{ +public: + using Ptr = std::shared_ptr; + FrontFactory() = default; + virtual ~FrontFactory() = default; + + IFront::Ptr build(ppc::protocol::INodeInfoFactory::Ptr nodeInfoFactory, + ppc::protocol::MessagePayloadBuilder::Ptr messageFactory, + ppc::protocol::MessageOptionalHeaderBuilder::Ptr routerInfoBuilder, + ppc::gateway::IGateway::Ptr const& gateway, FrontConfig::Ptr config); +}; +} // namespace ppc::front \ No newline at end of file diff --git a/cpp/wedpr-transport/ppc-front/ppc-front/FrontImpl.cpp b/cpp/wedpr-transport/ppc-front/ppc-front/FrontImpl.cpp new file mode 100644 index 00000000..0441d1fa --- /dev/null +++ b/cpp/wedpr-transport/ppc-front/ppc-front/FrontImpl.cpp @@ -0,0 +1,328 @@ +/** + * 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 FrontImpl.cpp + * @author: yujiechen + * @date 2024-08-30 + */ +#include "FrontImpl.h" +#include "NodeDiscovery.h" +#include "ppc-utilities/Utilities.h" + +using namespace bcos; +using namespace ppc; +using namespace ppc::front; +using namespace ppc::protocol; + +FrontImpl::FrontImpl(std::shared_ptr threadPool, + ppc::protocol::INodeInfo::Ptr nodeInfo, MessagePayloadBuilder::Ptr messageFactory, + ppc::protocol::MessageOptionalHeaderBuilder::Ptr routerInfoBuilder, + ppc::gateway::IGateway::Ptr const& gateway, std::shared_ptr ioService) + : m_threadPool(std::move(threadPool)), + m_nodeInfo(std::move(nodeInfo)), + m_messageFactory(std::move(messageFactory)), + m_routerInfoBuilder(std::move(routerInfoBuilder)), + m_ioService(std::move(ioService)), + m_gatewayClient(gateway), + m_nodeDiscovery(std::make_shared(gateway)) +{ + m_nodeID = m_nodeInfo->nodeID().toBytes(); + m_callbackManager = std::make_shared(m_threadPool, m_ioService); +} + + +/** + * @brief start the IFront + * + * @param front the IFront to start + */ +void FrontImpl::start() +{ + if (m_running) + { + FRONT_LOG(INFO) << LOG_DESC("The front has already been started"); + return; + } + m_running = true; + if (m_nodeDiscovery) + { + m_nodeDiscovery->start(); + } + m_thread = std::make_shared([&] { + bcos::pthread_setThreadName("front_io_service"); + while (m_running) + { + try + { + m_ioService->run(); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + if (m_running && m_ioService->stopped()) + { + m_ioService->restart(); + } + } + catch (std::exception& e) + { + FRONT_LOG(WARNING) + << LOG_DESC("Exception in Front Thread:") << boost::diagnostic_information(e); + } + } + FRONT_LOG(INFO) << "Front exit"; + }); + FRONT_LOG(INFO) << LOG_DESC("start front success"); +} + + +/** + * @brief stop the IFront + * + * @param front the IFront to stop + */ +void FrontImpl::stop() +{ + if (!m_running) + { + FRONT_LOG(INFO) << LOG_DESC("The front has already been stopped"); + return; + } + m_running = false; + if (m_nodeDiscovery) + { + m_nodeDiscovery->stop(); + } + if (m_ioService) + { + m_ioService->stop(); + } + if (m_thread) + { + // stop the thread + if (m_thread->get_id() != std::this_thread::get_id()) + { + m_thread->join(); + } + else + { + m_thread->detach(); + } + } + FRONT_LOG(INFO) << LOG_DESC("stop front success"); +} + +void FrontImpl::asyncSendResponse(bcos::bytesConstRef dstNode, std::string const& traceID, + bcos::bytesConstRef payload, int seq, ppc::protocol::ReceiveMsgFunc errorCallback) +{ + // generate the frontMessage + auto frontMessage = m_messageFactory->build(); + frontMessage->setTraceID(traceID); + frontMessage->setSeq(seq); + frontMessage->setDataPtr(payload); + + auto routeInfo = m_routerInfoBuilder->build(); + routeInfo->setSrcNode(m_nodeID); + routeInfo->setDstNode(dstNode.toBytes()); + + asyncSendMessageToGateway(true, std::move(frontMessage), RouteType::ROUTE_THROUGH_NODEID, + traceID, routeInfo, -1, errorCallback); +} + +/** + * @brief async send message + * + * @param routeType the route type + * @param routeInfo the route info, include + * - topic the topic + * - dstInst the dst agency(must set when 'route by agency' and 'route by + * component') + * - dstNodeID the dst nodeID(must set when 'route by nodeID') + * - 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 FrontImpl::asyncSendMessage(uint16_t routeType, MessageOptionalHeader::Ptr const& routeInfo, + bcos::bytesConstRef payload, int seq, long timeout, ReceiveMsgFunc errorCallback, + MessageCallback callback) +{ + // generate the frontMessage + MessagePayload::Ptr frontMessage = m_messageFactory->build(); + auto traceID = ppc::generateUUID(); + frontMessage->setTraceID(traceID); + frontMessage->setSeq(seq); + frontMessage->setDataPtr(payload); + m_callbackManager->addCallback(traceID, timeout, callback); + auto self = weak_from_this(); + // send the message to the gateway + asyncSendMessageToGateway(false, std::move(frontMessage), (ppc::protocol::RouteType)routeType, + traceID, routeInfo, timeout, + [self, traceID, routeInfo, errorCallback](bcos::Error::Ptr error) { + auto front = self.lock(); + if (!front) + { + return; + } + // send success + if (error && error->errorCode() != 0) + { + // send failed + FRONT_LOG(WARNING) + << LOG_DESC("asyncSendMessage failed") + << LOG_KV("routeInfo", printOptionalField(routeInfo)) + << LOG_KV("traceID", traceID) << LOG_KV("code", error->errorCode()) + << LOG_KV("msg", error->errorMessage()); + // try to trigger the callback + front->handleCallback(error, traceID, nullptr); + } + // Note: be careful block here when use push + if (errorCallback) + { + errorCallback(error); + } + }); +} + +void FrontImpl::handleCallback( + bcos::Error::Ptr const& error, std::string const& traceID, Message::Ptr message) +{ + auto self = weak_from_this(); + m_callbackManager->handleCallback(error, traceID, std::move(message), + [self, message](std::shared_ptr&& payload) { + auto front = self.lock(); + if (!front) + { + return; + } + auto frontMessage = front->m_messageFactory->build(); + // set the traceID + frontMessage->setTraceID(message->header()->traceID()); + ///// populate the route info + auto routerInfo = front->m_routerInfoBuilder->build(message->header()->optionalField()); + // set the dstNodeID + routerInfo->setDstNode(message->header()->optionalField()->srcNode()); + // set the srcNodeID + routerInfo->setSrcNode(message->header()->optionalField()->dstNode()); + front->asyncSendMessageToGateway(true, std::move(frontMessage), + RouteType::ROUTE_THROUGH_NODEID, message->header()->traceID(), routerInfo, 0, + [routerInfo](bcos::Error::Ptr error) { + if (!error || error->errorCode() == 0) + { + return; + } + FRONT_LOG(WARNING) << LOG_DESC("send response message error") + << LOG_KV("routeInfo", printOptionalField(routerInfo)) + << LOG_KV("code", error->errorCode()) + << LOG_KV("msg", error->errorMessage()); + }); + }); +} + +void FrontImpl::asyncSendMessageToGateway(bool responsePacket, MessagePayload::Ptr&& frontMessage, + RouteType routeType, std::string const& traceID, MessageOptionalHeader::Ptr const& routeInfo, + long timeout, ReceiveMsgFunc callback) +{ + if (responsePacket) + { + frontMessage->setRespPacket(); + } + routeInfo->setSrcNode(m_nodeID); + auto payload = std::make_shared(); + frontMessage->encode(*payload); + FRONT_LOG(TRACE) << LOG_DESC("asyncSendMessageToGateway") << LOG_KV("routeType", routeType) + << LOG_KV("response", responsePacket) << LOG_KV("traceID", traceID) + << printOptionalField(routeInfo) + << LOG_KV("payloadSize", frontMessage->length()); + m_gatewayClient->asyncSendMessage( + routeType, routeInfo, traceID, std::move(*payload), timeout, callback); +} + + +/** + * @brief: receive message from gateway, call by gateway + * @param _message: received ppc message + * @return void + */ +void FrontImpl::onReceiveMessage(Message::Ptr const& msg, ReceiveMsgFunc callback) +{ + try + { + // response to the gateway + if (callback) + { + m_threadPool->enqueue([callback] { callback(nullptr); }); + } + FRONT_LOG(TRACE) << LOG_BADGE("onReceiveMessage") << LOG_KV("msg", printMessage(msg)); + auto frontMessage = m_messageFactory->build(bcos::ref(*(msg->payload()))); + // release the payload buffer since it useless now + msg->setFrontMessage(frontMessage, true); + + // the response packet, dispatcher by callback + if (frontMessage->isRespPacket()) + { + handleCallback(nullptr, msg->header()->traceID(), msg); + return; + } + // dispatcher by topic + m_callbackManager->onReceiveMessage(msg->header()->optionalField()->topic(), msg); + } + catch (Exception const& e) + { + FRONT_LOG(WARNING) << LOG_DESC("onReceiveMessage exception") + << LOG_KV("msg", printMessage(msg)) + << LOG_KV("error", boost::diagnostic_information(e)); + } +} + +// the sync interface for asyncSendMessage +bcos::Error::Ptr FrontImpl::push(uint16_t routeType, MessageOptionalHeader::Ptr const& routeInfo, + bcos::bytesConstRef payload, int seq, long timeout) +{ + auto promise = std::make_shared>(); + asyncSendMessage( + routeType, routeInfo, payload, seq, timeout, + [promise](bcos::Error::Ptr error) { promise->set_value(error); }, nullptr); + return promise->get_future().get(); +} + +void FrontImpl::asyncGetPeers(GetPeersInfoHandler::Ptr getPeersCallback) +{ + m_gatewayClient->asyncGetPeers( + [getPeersCallback](bcos::Error::Ptr error, std::string peersInfo) { + getPeersCallback->onPeersInfo(error, peersInfo); + }); +} + +void FrontImpl::registerComponent(std::string const& component) +{ + // Note: the node will report the latest components + auto ret = m_nodeInfo->addComponent(component); + FRONT_LOG(INFO) << LOG_DESC("registerComponent") << LOG_KV("component", component) + << LOG_KV("insert", ret); +} + +void FrontImpl::updateMetaInfo(std::string const& meta) +{ + // Note: the node will report the latest components + m_nodeInfo->setMeta(meta); + FRONT_LOG(INFO) << LOG_DESC("updateMetaInfo") << LOG_KV("meta", meta); +} + +void FrontImpl::unRegisterComponent(std::string const& component) +{ + // Note: the node will report the latest components + auto ret = m_nodeInfo->eraseComponent(component); + FRONT_LOG(INFO) << LOG_DESC("unRegisterComponent") << LOG_KV("component", component) + << LOG_KV("erase", ret); +} \ No newline at end of file diff --git a/cpp/wedpr-transport/ppc-front/ppc-front/FrontImpl.h b/cpp/wedpr-transport/ppc-front/ppc-front/FrontImpl.h new file mode 100644 index 00000000..2977d16d --- /dev/null +++ b/cpp/wedpr-transport/ppc-front/ppc-front/FrontImpl.h @@ -0,0 +1,217 @@ +/** + * 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 FrontImpl.h + * @author: yujiechen + * @date 2024-08-30 + */ +#pragma once +#include "CallbackManager.h" +#include "Common.h" +#include "ppc-framework/front/IFront.h" +#include "ppc-framework/front/INodeDiscovery.h" +#include "ppc-framework/gateway/IGateway.h" +#include +#include +#include + +namespace ppc::front +{ +class FrontImpl : public IFront, public IFrontClient, public std::enable_shared_from_this +{ +public: + using Ptr = std::shared_ptr; + FrontImpl(std::shared_ptr threadPool, ppc::protocol::INodeInfo::Ptr nodeInfo, + ppc::protocol::MessagePayloadBuilder::Ptr messageFactory, + ppc::protocol::MessageOptionalHeaderBuilder::Ptr routerInfoBuilder, + ppc::gateway::IGateway::Ptr const& gateway, + std::shared_ptr ioService); + ~FrontImpl() override = default; + + /** + * @brief start the IFront + * + * @param front the IFront to start + */ + void start() override; + /** + * @brief stop the IFront + * + * @param front the IFront to stop + */ + void stop() override; + + bcos::Error::Ptr push(uint16_t routeType, + ppc::protocol::MessageOptionalHeader::Ptr const& routeInfo, bcos::bytesConstRef payload, + int seq, long timeout) override; + /** + * @brief async send message + * + * @param routeType the route type + * @param routeInfo the route info, include + * - topic the topic + * - dstInst the dst agency(must set when 'route by agency' and 'route by + * component') + * - dstNodeID the dst nodeID(must set when 'route by nodeID') + * - 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(uint16_t routeType, + ppc::protocol::MessageOptionalHeader::Ptr const& routeInfo, bcos::bytesConstRef payload, + int seq, long timeout, ppc::protocol::ReceiveMsgFunc errorCallback, + ppc::protocol::MessageCallback callback) override; + + /** + * @brief: receive message from gateway, call by gateway + * @param _message: received ppc message + * @return void + */ + void onReceiveMessage( + ppc::protocol::Message::Ptr const& _msg, ppc::protocol::ReceiveMsgFunc _callback) override; + + ppc::protocol::Message::Ptr pop(std::string const& topic, long timeoutMs) override + { + return m_callbackManager->pop(topic, timeoutMs); + } + + ppc::protocol::Message::Ptr peek(std::string const& topic) override + { + return m_callbackManager->pop(topic, 0); + } + /** + * + * @param front the front object + * @param topic the topic + * @param callback the callback called when receive specified topic + */ + void registerTopicHandler( + std::string const& topic, ppc::protocol::MessageDispatcherCallback callback) override + { + m_callbackManager->registerTopicHandler(topic, callback); + } + + void registerMessageHandler(std::string const& componentType, + ppc::protocol::MessageDispatcherCallback callback) override + { + m_callbackManager->registerMessageHandler(componentType, callback); + } + + /** + * @brief register the nodeInfo to the gateway + * @param nodeInfo the nodeInfo + */ + bcos::Error::Ptr registerNodeInfo(ppc::protocol::INodeInfo::Ptr const& nodeInfo) override + { + FRONT_LOG(INFO) << LOG_DESC("registerNodeInfo") + << LOG_KV("nodeInfo", printNodeInfo(m_nodeInfo)); + return m_gatewayClient->registerNodeInfo(m_nodeInfo); + } + + /** + * @brief unRegister the nodeInfo to the gateway + */ + bcos::Error::Ptr unRegisterNodeInfo() override + { + FRONT_LOG(INFO) << LOG_DESC("unRegisterNodeInfo"); + return m_gatewayClient->unRegisterNodeInfo(bcos::ref(m_nodeID)); + } + + /** + * @brief register the topic + * + * @param topic the topic to register + */ + bcos::Error::Ptr registerTopic(std::string const& topic) override + { + FRONT_LOG(INFO) << LOG_DESC("register topic: ") << topic; + return m_gatewayClient->registerTopic(bcos::ref(m_nodeID), topic); + } + + void asyncGetAgencies(std::vector const& components, + std::function)> callback) override + { + m_gatewayClient->asyncGetAgencies(components, callback); + } + + void asyncGetPeers(GetPeersInfoHandler::Ptr getPeersCallback) override; + + /** + * @brief unRegister the topic + * + * @param topic the topic to unregister + */ + bcos::Error::Ptr unRegisterTopic(std::string const& topic) override + { + FRONT_LOG(INFO) << LOG_DESC("unregister topic: ") << topic; + return m_gatewayClient->unRegisterTopic(bcos::ref(m_nodeID), topic); + } + + ppc::protocol::MessageOptionalHeaderBuilder::Ptr const routerInfoBuilder() const + { + return m_routerInfoBuilder; + } + ppc::protocol::MessagePayloadBuilder::Ptr const payloadFactory() const + { + return m_messageFactory; + } + + void asyncSendResponse(bcos::bytesConstRef dstNode, std::string const& traceID, + bcos::bytesConstRef payload, int seq, ppc::protocol::ReceiveMsgFunc errorCallback) override; + + ppc::protocol::INodeInfo::Ptr const& nodeInfo() override { return m_nodeInfo; } + + void registerComponent(std::string const& component) override; + void unRegisterComponent(std::string const& component) override; + + std::vector selectNodesByRoutePolicy( + int16_t routeType, ppc::protocol::MessageOptionalHeader::Ptr const& routeInfo) override + { + return m_gatewayClient->selectNodesByRoutePolicy( + (ppc::protocol::RouteType)routeType, routeInfo); + } + + INodeDiscovery::Ptr const getNodeDiscovery() override { return m_nodeDiscovery; } + void updateMetaInfo(std::string const& meta) override; + +private: + void asyncSendMessageToGateway(bool responsePacket, + ppc::protocol::MessagePayload::Ptr&& frontMessage, ppc::protocol::RouteType routeType, + std::string const& traceID, ppc::protocol::MessageOptionalHeader::Ptr const& routeInfo, + long timeout, ppc::protocol::ReceiveMsgFunc callback); + + void handleCallback(bcos::Error::Ptr const& error, std::string const& traceID, + ppc::protocol::Message::Ptr message); + +private: + bcos::bytes m_nodeID; + std::shared_ptr m_threadPool; + ppc::protocol::INodeInfo::Ptr m_nodeInfo; + INodeDiscovery::Ptr m_nodeDiscovery; + ppc::protocol::MessagePayloadBuilder::Ptr m_messageFactory; + ppc::protocol::MessageOptionalHeaderBuilder::Ptr m_routerInfoBuilder; + + ppc::gateway::IGateway::Ptr m_gatewayClient; + std::shared_ptr m_ioService; + + CallbackManager::Ptr m_callbackManager; + + bool m_running = false; + // the thread to run ioservice + std::shared_ptr m_thread; +}; +} // namespace ppc::front \ No newline at end of file diff --git a/cpp/wedpr-transport/ppc-front/ppc-front/LocalFrontBuilder.h b/cpp/wedpr-transport/ppc-front/ppc-front/LocalFrontBuilder.h new file mode 100644 index 00000000..9dc04758 --- /dev/null +++ b/cpp/wedpr-transport/ppc-front/ppc-front/LocalFrontBuilder.h @@ -0,0 +1,44 @@ +/** + * 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 LocalFrontBuilder.h + * @author: yujiechen + * @date 2024-09-4 + */ +#pragma once +#include "ppc-framework/front/IFront.h" + +namespace ppc::front +{ +class LocalFrontBuilder : public IFrontBuilder +{ +public: + using Ptr = std::shared_ptr; + LocalFrontBuilder(IFront::Ptr front) { m_front = front; } + LocalFrontBuilder() = default; + ~LocalFrontBuilder() override = default; + + IFrontClient::Ptr buildClient(std::string, std::function onUnHealthHandler, + bool removeHandlerOnUnhealth) const override + { + return m_front; + } + + void setFront(IFront::Ptr front) { m_front = std::move(front); } + +private: + IFront::Ptr m_front; +}; +} // namespace ppc::front \ No newline at end of file diff --git a/cpp/wedpr-transport/ppc-front/ppc-front/NodeDiscovery.cpp b/cpp/wedpr-transport/ppc-front/ppc-front/NodeDiscovery.cpp new file mode 100644 index 00000000..c0d8e922 --- /dev/null +++ b/cpp/wedpr-transport/ppc-front/ppc-front/NodeDiscovery.cpp @@ -0,0 +1,77 @@ +/** + * 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 NodeDiscovery.cpp + * @author: yujiechen + * @date 2024-11-06 + */ +#include "NodeDiscovery.h" +#include "Common.h" + +using namespace ppc::front; + +NodeDiscovery::NodeDiscovery(ppc::gateway::IGateway::Ptr gatewayClient) + : m_gatewayClient(std::move(gatewayClient)) +{ + // fetch the meta information every 10s + m_metaFetcher = std::make_shared(10 * 1000, "metaFetcher"); +} + +std::vector NodeDiscovery::getAliveNodeList() const +{ + bcos::ReadGuard l(x_aliveNodeList); + return m_aliveNodeList; +} + +void NodeDiscovery::start() +{ + auto self = weak_from_this(); + m_metaFetcher->registerTimeoutHandler([self]() { + auto fetcher = self.lock(); + if (!fetcher) + { + return; + } + fetcher->fetchMetaInfoFromGateway(); + }); + if (m_metaFetcher) + { + m_metaFetcher->start(); + } +} + +void NodeDiscovery::stop() +{ + if (m_metaFetcher) + { + m_metaFetcher->stop(); + } +} + +void NodeDiscovery::fetchMetaInfoFromGateway() +{ + try + { + auto nodeList = m_gatewayClient->getAliveNodeList(); + bcos::WriteGuard l(x_aliveNodeList); + m_aliveNodeList = nodeList; + } + catch (std::exception const& e) + { + FRONT_LOG(WARNING) << LOG_DESC("fetchMetaInfoFromGateway information failed") + << LOG_KV("error", boost::diagnostic_information(e)); + } + m_metaFetcher->restart(); +} \ No newline at end of file diff --git a/cpp/wedpr-transport/ppc-front/ppc-front/NodeDiscovery.h b/cpp/wedpr-transport/ppc-front/ppc-front/NodeDiscovery.h new file mode 100644 index 00000000..712a109e --- /dev/null +++ b/cpp/wedpr-transport/ppc-front/ppc-front/NodeDiscovery.h @@ -0,0 +1,49 @@ +/** + * 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 NodeDiscovery.h + * @author: yujiechen + * @date 2024-11-06 + */ +#pragma once +#include "ppc-framework/front/INodeDiscovery.h" +#include "ppc-framework/gateway/IGateway.h" +#include +#include + +namespace ppc::front +{ +class NodeDiscovery : public INodeDiscovery, public std::enable_shared_from_this +{ +public: + using Ptr = std::shared_ptr; + NodeDiscovery(ppc::gateway::IGateway::Ptr gatewayClient); + ~NodeDiscovery() override = default; + + std::vector> getAliveNodeList() const override; + void start() override; + void stop() override; + +protected: + virtual void fetchMetaInfoFromGateway(); + +private: + std::shared_ptr m_metaFetcher; + ppc::gateway::IGateway::Ptr m_gatewayClient; + + std::vector m_aliveNodeList; + mutable bcos::SharedMutex x_aliveNodeList; +}; +} // namespace ppc::front \ No newline at end of file diff --git a/cpp/wedpr-transport/ppc-front/ppc-front/PPCChannel.cpp b/cpp/wedpr-transport/ppc-front/ppc-front/PPCChannel.cpp new file mode 100644 index 00000000..445ac80f --- /dev/null +++ b/cpp/wedpr-transport/ppc-front/ppc-front/PPCChannel.cpp @@ -0,0 +1,183 @@ +/** + * Copyright (C) 2022 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 PPCChannel.cpp + * @author: shawnhe + * @date 2022-10-27 + */ + +#include "PPCChannel.h" + +using namespace bcos; +using namespace ppc::front; +using namespace ppc::protocol; + + +/** + * @brief: receive message, note that one message will consume one handler + * @param _messageType: the message type is defined by each crypto algorithm + * @param _seq: message seq + * @param _secondsTimeout: timeout by seconds + * @return void + */ +void PPCChannel::asyncReceiveMessage(uint8_t _messageType, uint32_t _seq, uint32_t _secondsTimeout, + std::function _handler) +{ + if (!_handler) + { + return; + } + + WriteGuard lock(x_handler_message); + + auto message = getAndRemoveMessage(messageKey(_messageType, _seq)); + if (message) + { + // trigger handler by message + handleCallback(nullptr, message, std::move(_handler)); + } + else + { + auto messageHandler = std::make_shared(); + messageHandler->handler = std::move(_handler); + + if (_secondsTimeout == 0) + { + _secondsTimeout = HOLDING_MESSAGE_TIMEOUT_M * 60; + } + + // create timer to handle timeout + messageHandler->timer = std::make_shared( + *m_ioService, boost::posix_time::seconds(_secondsTimeout)); + + messageHandler->timer->async_wait( + [self = weak_from_this(), _messageType, _seq](boost::system::error_code _error) { + if (!_error) + { + auto channel = self.lock(); + if (channel) + { + // remove timeout handler + auto timeoutHandler = + channel->getAndRemoveHandler(channel->messageKey(_messageType, _seq)); + + if (timeoutHandler) + { + FRONT_LOG(DEBUG) << LOG_BADGE("channelWaitingMsgTimeout") + << LOG_KV("messageType", (int)_messageType); + + // trigger handler by error + auto error = std::make_shared( + PPCRetCode::TIMEOUT, "timeout waiting for message"); + auto handler = timeoutHandler->handler; + channel->handleCallback(error, nullptr, std::move(handler)); + } + } + } + }); + + addHandler(messageKey(_messageType, _seq), std::move(messageHandler)); + } +} + + +/** + * @brief: used for front to dispatch message + * @param _messageType: the message type is defined by each crypto algorithm + * @return void + */ +void PPCChannel::onMessageArrived(uint8_t _messageType, PPCMessageFace::Ptr _message) +{ + WriteGuard lock(x_handler_message); + + auto seq = _message->seq(); + auto messageHandler = getAndRemoveHandler(messageKey(_messageType, seq)); + if (messageHandler) + { + // clear timer + if (messageHandler->timer) + { + messageHandler->timer->cancel(); + } + + // trigger event by buffer + handleCallback(nullptr, std::move(_message), std::move(messageHandler->handler)); + } + else + { + addMessage(messageKey(_messageType, seq), std::move(_message)); + } +} + + +void PPCChannel::addHandler(uint64_t _messageKey, MessageHandler::Ptr _handler) +{ + WriteGuard lock(x_handlers); + m_handlers[_messageKey] = std::move(_handler); +} + + +PPCChannel::MessageHandler::Ptr PPCChannel::getAndRemoveHandler(uint64_t _messageKey) +{ + WriteGuard lock(x_handlers); + auto it = m_handlers.find(_messageKey); + if (it == m_handlers.end()) + { + return nullptr; + } + + auto ret = std::move(it->second); + m_handlers.erase(_messageKey); + return ret; +} + + +void PPCChannel::addMessage(uint64_t _messageKey, PPCMessageFace::Ptr _message) +{ + m_messages[_messageKey] = std::move(_message); +} + + +PPCMessageFace::Ptr PPCChannel::getAndRemoveMessage(uint64_t _messageKey) +{ + auto it = m_messages.find(_messageKey); + if (it == m_messages.end()) + { + return nullptr; + } + + auto ret = std::move(it->second); + m_messages.erase(_messageKey); + return ret; +} + + +void PPCChannel::handleCallback(bcos::Error::Ptr _error, PPCMessageFace::Ptr _message, + std::function&& _callback) +{ + if (!_callback) + { + return; + } + + if (m_threadPool) + { + m_threadPool->enqueue([_error, _message, _callback]() { _callback(_error, _message); }); + } + else + { + _callback(std::move(_error), std::move(_message)); + } +} diff --git a/cpp/wedpr-transport/ppc-front/ppc-front/PPCChannel.h b/cpp/wedpr-transport/ppc-front/ppc-front/PPCChannel.h new file mode 100644 index 00000000..3f5e4edf --- /dev/null +++ b/cpp/wedpr-transport/ppc-front/ppc-front/PPCChannel.h @@ -0,0 +1,126 @@ +/** + * Copyright (C) 2022 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 PPCChannel.h + * @author: shawnhe + * @date 2022-10-27 + */ + +#pragma once + +#include "Common.h" +#include "Front.h" +#include "ppc-framework/front/Channel.h" +#include + +namespace ppc::front +{ +class PPCChannel : public Channel, public std::enable_shared_from_this +{ +public: + using Ptr = std::shared_ptr; + PPCChannel(std::shared_ptr _ioService, front::Front::Ptr _front, + std::shared_ptr _threadPool) + : m_ioService(std::move(_ioService)), + m_front(std::move(_front)), + m_threadPool(std::move(_threadPool)) + {} + + ~PPCChannel() override + { + std::unordered_map().swap(m_handlers); + std::unordered_map().swap(m_messages); + FRONT_LOG(INFO) << LOG_DESC("the PPCChannel destroyed"); + } + +public: + /** + * @brief notice task info to gateway by front + * @param _taskInfo the latest task information + */ + bcos::Error::Ptr notifyTaskInfo(std::string const& taskID) override + { + return m_front->notifyTaskInfo(std::move(taskID)); + }; + + /** + * @brief: send message + * @param _agencyID: message receiver + * @return void + */ + void asyncSendMessage(const std::string& _agencyID, front::PPCMessageFace::Ptr _message, + uint32_t _timeout, ErrorCallbackFunc _callback, CallbackFunc _respCallback) override + { + m_front->asyncSendMessage(_agencyID, std::move(_message), _timeout, std::move(_callback), + std::move(_respCallback)); + } + + /** + * @brief: receive message, note that one message will consume one handler + * @param _messageType: the message type is defined by each crypto algorithm + * @param _seq: message seq + * @param _secondsTimeout: timeout by seconds + * @return void + */ + void asyncReceiveMessage(uint8_t _messageType, uint32_t _seq, uint32_t _secondsTimeout, + std::function _handler) override; + + + /** + * @brief: used for front to dispatch message + * @param _messageType: the message type is defined by each crypto algorithm + * @return void + */ + void onMessageArrived(uint8_t _messageType, front::PPCMessageFace::Ptr _message) override; + + + static inline uint64_t messageKey(uint8_t _messageType, uint32_t _seq) + { + uint64_t key = ((uint64_t)_messageType << 32) | _seq; + return key; + } + +protected: + struct MessageHandler + { + using Ptr = std::shared_ptr; + std::function handler; + std::shared_ptr timer; + }; + +private: + void addHandler(uint64_t _messageKey, MessageHandler::Ptr _handler); + MessageHandler::Ptr getAndRemoveHandler(uint64_t _messageKey); + + void addMessage(uint64_t _messageKey, front::PPCMessageFace::Ptr _message); + front::PPCMessageFace::Ptr getAndRemoveMessage(uint64_t _messageKey); + + void handleCallback(bcos::Error::Ptr _error, front::PPCMessageFace::Ptr _message, + std::function&& _callback); + +private: + std::shared_ptr m_ioService; + Front::Ptr m_front; + std::shared_ptr m_threadPool; + + mutable boost::shared_mutex x_handlers; + // key: messageType || seq + std::unordered_map m_handlers; + std::unordered_map m_messages; + + // coordinate handler and message + mutable boost::shared_mutex x_handler_message; +}; +} // namespace ppc::front \ No newline at end of file diff --git a/cpp/wedpr-transport/ppc-front/ppc-front/PPCChannelManager.cpp b/cpp/wedpr-transport/ppc-front/ppc-front/PPCChannelManager.cpp new file mode 100644 index 00000000..c42b88d3 --- /dev/null +++ b/cpp/wedpr-transport/ppc-front/ppc-front/PPCChannelManager.cpp @@ -0,0 +1,136 @@ +/** + * Copyright (C) 2022 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 PPCChannelManager.cpp + * @author: shawnhe + * @date 2022-10-27 + */ + + +#include "PPCChannelManager.h" + +#include + +using namespace bcos; +using namespace ppc::front; +using namespace ppc::protocol; + +void PPCChannelManager::registerMsgHandlerForChannel(uint8_t _taskType, uint8_t _algorithmType) +{ + FRONT_LOG(INFO) << LOG_BADGE("registerMsgHandlerForChannel") << LOG_KV("taskType", _taskType) + << LOG_KV("algorithmType", _algorithmType); + m_front->registerMessageHandler( + _taskType, _algorithmType, [self = weak_from_this()](PPCMessageFace::Ptr _message) { + auto channelManager = self.lock(); + if (channelManager) + { + channelManager->onMessageArrived(std::move(_message)); + } + }); +} + +Channel::Ptr PPCChannelManager::buildChannelForTask(const std::string& _taskID) +{ + FRONT_LOG(INFO) << LOG_BADGE("buildChannelForTask") << LOG_KV("taskID", _taskID); + + WriteGuard lock(x_message_channel); + + // new a channel + auto channel = std::make_shared(m_ioService, m_front, m_threadPool); + m_channels[_taskID] = channel; + + // check to see if any message has arrived + auto it = m_holdingMessages.find(_taskID); + if (it != m_holdingMessages.end()) + { + auto holdingMessages = it->second; + if (holdingMessages->timer) + { + holdingMessages->timer->cancel(); + } + for (auto& msg : holdingMessages->messages) + { + channel->onMessageArrived(msg->messageType(), msg); + } + + // remove holding message + m_holdingMessages.erase(_taskID); + } + + return std::static_pointer_cast(channel); +} + + +void PPCChannelManager::removeChannelByTask(const std::string& _taskID) +{ + FRONT_LOG(INFO) << LOG_BADGE("removeChannelByTask") << LOG_KV("taskID", _taskID); + + WriteGuard lock(x_message_channel); + m_channels.erase(_taskID); +} + + +void PPCChannelManager::onMessageArrived(PPCMessageFace::Ptr _message) +{ + WriteGuard lock(x_message_channel); + + auto taskID = _message->taskID(); + + auto itC = m_channels.find(taskID); + if (itC != m_channels.end()) + { + itC->second->onMessageArrived(_message->messageType(), _message); + } + else + { + // hold the message + auto itM = m_holdingMessages.find(taskID); + if (itM != m_holdingMessages.end()) + { + itM->second->messages.emplace_back(_message); + } + else + { + auto holdingMessages = std::make_shared(); + holdingMessages->messages = std::vector(); + holdingMessages->messages.emplace_back(_message); + + // create timer to handle timeout + holdingMessages->timer = std::make_shared( + *m_ioService, boost::posix_time::minutes(HOLDING_MESSAGE_TIMEOUT_M)); + + holdingMessages->timer->async_wait( + [self = weak_from_this(), taskID](boost::system::error_code _error) { + if (!_error) + { + auto channelManager = self.lock(); + if (channelManager) + { + // remove timeout message + channelManager->removeHoldingMessages(taskID); + } + } + }); + + m_holdingMessages[taskID] = holdingMessages; + } + } +} + +void PPCChannelManager::removeHoldingMessages(const std::string& _taskID) +{ + WriteGuard lock(x_message_channel); + m_holdingMessages.erase(_taskID); +} diff --git a/cpp/wedpr-transport/ppc-front/ppc-front/PPCChannelManager.h b/cpp/wedpr-transport/ppc-front/ppc-front/PPCChannelManager.h new file mode 100644 index 00000000..506b2416 --- /dev/null +++ b/cpp/wedpr-transport/ppc-front/ppc-front/PPCChannelManager.h @@ -0,0 +1,88 @@ +/** + * Copyright (C) 2022 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 PPCChannelManager.h + * @author: shawnhe + * @date 2022-10-27 + */ + +#pragma once + +#include "PPCChannel.h" +#include + +namespace ppc::front +{ +class PPCChannelManager : public std::enable_shared_from_this +{ +public: + using Ptr = std::shared_ptr; + PPCChannelManager(std::shared_ptr _ioService, front::Front::Ptr _front) + : m_ioService(std::move(_ioService)), m_front(std::move(_front)){}; + + ~PPCChannelManager() + { + std::unordered_map().swap(m_holdingMessages); + std::unordered_map().swap(m_channels); + FRONT_LOG(INFO) << LOG_DESC("the PPCChannelManager destroyed"); + } + + void setThreadPool(std::shared_ptr _threadPool) + { + m_threadPool = std::move(_threadPool); + } + + /** + * if the algorithm need to use channel, register the handler of the algorithm in this function. + */ + void registerMsgHandlerForChannel(uint8_t _taskType, uint8_t _algorithmType); + + /** + * build a channel for each task + */ + Channel::Ptr buildChannelForTask(const std::string& _taskID); + + /** + * clean up channel at the end of the task + */ + void removeChannelByTask(const std::string& _taskID); + +protected: + struct HoldingMessage + { + using Ptr = std::shared_ptr; + std::vector messages; + std::shared_ptr timer; + }; + +private: + void onMessageArrived(front::PPCMessageFace::Ptr _message); + void removeHoldingMessages(const std::string& _taskID); + + +private: + std::shared_ptr m_ioService; + front::Front::Ptr m_front; + std::shared_ptr m_threadPool; + + /** + * hold the message for the situation that + * one party receives message from the other side while the Channel has not been registered. + */ + mutable boost::shared_mutex x_message_channel; + std::unordered_map m_holdingMessages; + std::unordered_map m_channels; +}; +} // namespace ppc::front diff --git a/cpp/wedpr-transport/ppc-front/test/CMakeLists.txt b/cpp/wedpr-transport/ppc-front/test/CMakeLists.txt new file mode 100644 index 00000000..af0aa6db --- /dev/null +++ b/cpp/wedpr-transport/ppc-front/test/CMakeLists.txt @@ -0,0 +1,13 @@ +file(GLOB_RECURSE SOURCES "unittests/*.cpp") + +# cmake settings +set(FRONT_TEST_BINARY_NAME test-ppc-front) + +add_executable(${FRONT_TEST_BINARY_NAME} ${SOURCES}) +target_include_directories(${FRONT_TEST_BINARY_NAME} PRIVATE .) + +target_compile_options(${FRONT_TEST_BINARY_NAME} PRIVATE -Wno-error -Wno-unused-variable) + +target_link_libraries(${FRONT_TEST_BINARY_NAME} ${FRONT_TARGET} ${PROTOCOL_TARGET} ${BOOST_UNIT_TEST}) + +add_test(NAME test-front WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} COMMAND ${FRONT_TEST_BINARY_NAME}) \ No newline at end of file diff --git a/cpp/wedpr-transport/ppc-front/test/unittests/PPCChannelTest.cpp b/cpp/wedpr-transport/ppc-front/test/unittests/PPCChannelTest.cpp new file mode 100644 index 00000000..e5ae7866 --- /dev/null +++ b/cpp/wedpr-transport/ppc-front/test/unittests/PPCChannelTest.cpp @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2022 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 PPCChannelTest.cpp + * @author: shawnhe + * @date 2022-10-29 + */ +#if 0 + +#include "ppc-front/ppc-front/PPCChannel.h" +#include "ppc-front/ppc-front/PPCChannelManager.h" +#include "protocol/src/PPCMessage.h" +#include +#include +#include +#include + +using namespace ppc; +using namespace ppc::front; + +using namespace bcos; +using namespace bcos::test; + +BOOST_FIXTURE_TEST_SUITE(PPCChannelTest, TestPromptFixture) + +BOOST_AUTO_TEST_CASE(test_ppcChannel) +{ + auto threadPool = std::make_shared("TEST_POOL_MODULE", 4); + auto ioService = std::make_shared(); + auto front = std::make_shared(ioService, "1001", threadPool); + + auto channelManager = std::make_shared(ioService, front); + // Note: must start here, otherwise the ioservice will not work + //front->start(); + + // register message handler + channelManager->registerMsgHandlerForChannel( + uint8_t(protocol::TaskType::PSI), uint8_t(protocol::TaskAlgorithmType::CM_PSI_2PC)); + + // receive message + auto messageFactory = std::make_shared(); + auto message = messageFactory->buildPPCMessage(); + message->setVersion(1); + message->setTaskType(uint8_t(protocol::TaskType::PSI)); + message->setAlgorithmType(uint8_t(protocol::TaskAlgorithmType::CM_PSI_2PC)); + message->setMessageType(4); + message->setSeq(5); + message->setTaskID("T_123456"); + message->setSender("1001"); + message->setData(std::make_shared(10, 'a')); + front->onReceiveMessage(message, nullptr); + + auto payload = std::make_shared(); + message->encode(*payload); + auto newMsg = messageFactory->buildPPCMessage(payload); + newMsg->setSeq(6); + front->onReceiveMessage(newMsg, nullptr); + + // build channel + auto channel = channelManager->buildChannelForTask("T_123456"); + + std::atomic flag = 0; + + channel->asyncReceiveMessage( + 4, 5, 1, [&flag](bcos::Error::Ptr, const PPCMessageFace::Ptr& _message) { + BOOST_CHECK(_message->seq() == 5); + BOOST_CHECK(_message->sender() == "1001"); + BOOST_CHECK(_message->data()->size() == 10); + flag++; + }); + + newMsg = messageFactory->buildPPCMessage(payload); + newMsg->setSeq(8); + front->onReceiveMessage(newMsg, nullptr); + + channel->asyncReceiveMessage( + 4, 6, 1, [&flag](bcos::Error::Ptr, const PPCMessageFace::Ptr& _message) { + BOOST_CHECK(_message->seq() == 6); + BOOST_CHECK(_message->sender() == "1001"); + BOOST_CHECK(_message->data()->size() == 10); + flag++; + }); + + // timeout + channel->asyncReceiveMessage( + 4, 7, 1, [&flag](const bcos::Error::Ptr& _error, const PPCMessageFace::Ptr& _message) { + BOOST_CHECK(_error->errorCode() == protocol::PPCRetCode::TIMEOUT); + flag++; + }); + + channel->asyncReceiveMessage( + 4, 8, 1, [&flag](bcos::Error::Ptr, const PPCMessageFace::Ptr& _message) { + BOOST_CHECK(_message->seq() == 8); + BOOST_CHECK(_message->sender() == "1001"); + BOOST_CHECK(_message->data()->size() == 10); + flag++; + }); + + while (flag != 4) + { + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } + + //front->stop(); +} +BOOST_AUTO_TEST_SUITE_END() +#endif \ No newline at end of file diff --git a/cpp/wedpr-transport/ppc-front/test/unittests/main.cpp b/cpp/wedpr-transport/ppc-front/test/unittests/main.cpp new file mode 100644 index 00000000..2c06f9b5 --- /dev/null +++ b/cpp/wedpr-transport/ppc-front/test/unittests/main.cpp @@ -0,0 +1,2 @@ +#define BOOST_TEST_MAIN +#include \ No newline at end of file diff --git a/cpp/wedpr-transport/ppc-gateway/CMakeLists.txt b/cpp/wedpr-transport/ppc-gateway/CMakeLists.txt new file mode 100644 index 00000000..142780b5 --- /dev/null +++ b/cpp/wedpr-transport/ppc-gateway/CMakeLists.txt @@ -0,0 +1,19 @@ +cmake_minimum_required(VERSION 3.14) +find_package(Boost COMPONENTS filesystem) + +file(GLOB_RECURSE SRCS ppc-gateway/*.cpp) + + +add_library(${GATEWAY_TARGET} ${SRCS}) +target_link_libraries(${GATEWAY_TARGET} PUBLIC ${TOOLS_TARGET} jsoncpp_static Boost::filesystem + ${BCOS_BOOSTSSL_TARGET} ${BCOS_UTILITIES_TARGET} + ${PROTOCOL_TARGET} + ${TARS_PROTOCOL_TARGET} ${PB_PROTOCOL_TARGET} TBB::tbb) + + +# ut +if (TESTS) + enable_testing() + set(CTEST_OUTPUT_ON_FAILURE TRUE) + add_subdirectory(test) +endif () diff --git a/cpp/wedpr-transport/ppc-gateway/ppc-gateway/Common.h b/cpp/wedpr-transport/ppc-gateway/ppc-gateway/Common.h new file mode 100644 index 00000000..ecf94259 --- /dev/null +++ b/cpp/wedpr-transport/ppc-gateway/ppc-gateway/Common.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2022 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 Common.h + * @author: shawnhe + * @date 2022-10-23 + */ + +#pragma once + +#include "ppc-framework/Common.h" +#include +#include +#include +#include +#include +#include + +namespace ppc::gateway +{ +#define GATEWAY_LOG(LEVEL) BCOS_LOG(LEVEL) << "[GATEWAY]" +#define SERVICE_LOG(LEVEL) BCOS_LOG(LEVEL) << "[GATEWAY][SERVICE]" +#define SERVICE_ROUTER_LOG(LEVEL) BCOS_LOG(LEVEL) << "[GATEWAY][SERVICE][ROUTER]" +#define LOCAL_ROUTER_LOG(LEVEL) BCOS_LOG(LEVEL) << "[GATEWAY][LOCAL_ROUTER]" +#define PEER_ROUTER_LOG(LEVEL) BCOS_LOG(LEVEL) << "[GATEWAY][PEER_ROUTER]" +#define ROUTER_MGR_LOG(LEVEL) BCOS_LOG(LEVEL) << "[GATEWAY][ROUTER_MGR]" + +// HTTP HEADER DEFINE +#define HEAD_TASK_ID "x-ptp-session-id" +#define HEAD_ALGO_TYPE "x-ptp-algorithm-type" +#define HEAD_TASK_TYPE "x-ptp-task-type" +#define HEAD_SENDER_ID "x-ptp-sender-id" +#define HEAD_MESSAGE_TYPE "x-ptp-message-type" +#define HEAD_IS_RESPONSE "x-ptp-is-response" +#define HEAD_SEQ "x-ptp-seq" +#define HEAD_UUID "x-ptp-uuid" +} // namespace ppc::gateway \ No newline at end of file diff --git a/cpp/wedpr-transport/ppc-gateway/ppc-gateway/GatewayConfigContext.cpp b/cpp/wedpr-transport/ppc-gateway/ppc-gateway/GatewayConfigContext.cpp new file mode 100644 index 00000000..374bf909 --- /dev/null +++ b/cpp/wedpr-transport/ppc-gateway/ppc-gateway/GatewayConfigContext.cpp @@ -0,0 +1,71 @@ +/** + * Copyright (C) 2022 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 GatewayConfigContext.cpp + * @author: shawnhe + * @date 2022-10-23 + */ + +#include "GatewayConfigContext.h" +#include + +using namespace bcos; +using namespace ppc::gateway; +using namespace bcos::boostssl::context; + +GatewayConfigContext::GatewayConfigContext(std::shared_ptr _config) + : m_config(_config) +{ + if (!m_config->gatewayConfig().networkConfig.disableSsl) + { + GATEWAY_LOG(INFO) << LOG_DESC("GatewayConfigContext: initContextConfig"); + initContextConfig(); + GATEWAY_LOG(INFO) << LOG_DESC("GatewayConfigContext: initContextConfig success"); + } +} +void GatewayConfigContext::initContextConfig() +{ + m_contextConfig = std::make_shared(); + auto const& gatewayConfig = m_config->gatewayConfig().networkConfig; + // non-sm-ssl + if (!gatewayConfig.enableSM) + { + ContextConfig::CertConfig certConfig; + certConfig.caCert = gatewayConfig.caCertPath; + certConfig.nodeCert = gatewayConfig.sslCertPath; + certConfig.nodeKey = gatewayConfig.sslKeyPath; + m_contextConfig->setCertConfig(certConfig); + m_contextConfig->setSslType("ssl"); + // parse the nodeID + NodeInfoTools::initCert2PubHexHandler()(certConfig.nodeCert, m_nodeID); + GATEWAY_LOG(INFO) << LOG_DESC("initConfig: rpc work in non-sm-ssl model") + << LOG_KV("caCert", certConfig.caCert) + << LOG_KV("nodeCert", certConfig.nodeCert) + << LOG_KV("nodeKey", certConfig.nodeKey) << LOG_KV("nodeID", m_nodeID); + GATEWAY_LOG(INFO) << LOG_DESC("initContextConfig: non-sm-ssl"); + return; + } + // sm-ssl + boostssl::context::ContextConfig::SMCertConfig certConfig; + certConfig.caCert = gatewayConfig.smCaCertPath; + certConfig.nodeCert = gatewayConfig.smSslCertPath; + certConfig.nodeKey = gatewayConfig.smSslKeyPath; + certConfig.enNodeCert = gatewayConfig.smEnSslCertPath; + certConfig.enNodeKey = gatewayConfig.smEnSslKeyPath; + m_contextConfig->setSmCertConfig(certConfig); + m_contextConfig->setSslType("sm_ssl"); + NodeInfoTools::initCert2PubHexHandler()(certConfig.enNodeCert, m_nodeID); + GATEWAY_LOG(INFO) << LOG_DESC("initContextConfig: sm-ssl") << LOG_KV("nodeID", m_nodeID); +} diff --git a/cpp/wedpr-transport/ppc-gateway/ppc-gateway/GatewayConfigContext.h b/cpp/wedpr-transport/ppc-gateway/ppc-gateway/GatewayConfigContext.h new file mode 100644 index 00000000..33d936e8 --- /dev/null +++ b/cpp/wedpr-transport/ppc-gateway/ppc-gateway/GatewayConfigContext.h @@ -0,0 +1,59 @@ +/** + * Copyright (C) 2022 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 GatewayConfigContext.h + * @author: shawnhe + * @date 2022-10-23 + */ + +#pragma once + +#include "Common.h" +#include "bcos-boostssl/context/NodeInfoTools.h" +#include +#include +#include +#include + +namespace ppc::tools +{ +class PPCConfig; +} +namespace ppc::gateway +{ +class GatewayConfigContext +{ +public: + using Ptr = std::shared_ptr; + GatewayConfigContext(std::shared_ptr _config); + virtual ~GatewayConfigContext() = default; + [[nodiscard]] std::shared_ptr contextConfig() const + { + return m_contextConfig; + } + std::shared_ptr const& config() const { return m_config; } + + std::string const& nodeID() const { return m_nodeID; } + +private: + void initContextConfig(); + +private: + std::shared_ptr m_config; + std::shared_ptr m_contextConfig; + std::string m_nodeID; +}; + +} // namespace ppc::gateway \ No newline at end of file diff --git a/cpp/wedpr-transport/ppc-gateway/ppc-gateway/GatewayConfigLoader.cpp b/cpp/wedpr-transport/ppc-gateway/ppc-gateway/GatewayConfigLoader.cpp new file mode 100644 index 00000000..7f7d3bd3 --- /dev/null +++ b/cpp/wedpr-transport/ppc-gateway/ppc-gateway/GatewayConfigLoader.cpp @@ -0,0 +1,151 @@ +/** + * 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 GatewayConfigLoader.cpp + * @author: yujiechen + * @date 2024-08-26 + */ +#include "GatewayConfigLoader.h" +#include "Common.h" +#include "bcos-utilities/FileUtility.h" +#include "ppc-tools/src/config/PPCConfig.h" +#include + +using namespace ppc; +using namespace bcos; +using namespace ppc::tools; +using namespace ppc::gateway; +using namespace bcos::boostssl; + +// load p2p connected peers +void GatewayConfigLoader::loadP2pConnectedNodes() +{ + std::string nodeFilePath = + m_config->gatewayConfig().nodePath + "/" + m_config->gatewayConfig().nodeFileName; + // load p2p connected nodes + auto jsonContent = readContentsToString(boost::filesystem::path(nodeFilePath)); + if (!jsonContent || jsonContent->empty()) + { + BOOST_THROW_EXCEPTION( + WeDPRException() << errinfo_comment( + "loadP2pConnectedNodes: unable to read nodes json file, path=" + nodeFilePath)); + } + + parseConnectedJson(*jsonContent.get(), *m_nodeIPEndpointSet); + GATEWAY_LOG(INFO) << LOG_DESC("loadP2pConnectedNodes success!") + << LOG_KV("nodePath", m_config->gatewayConfig().nodePath) + << LOG_KV("nodeFileName", m_config->gatewayConfig().nodeFileName) + << LOG_KV("nodes", m_nodeIPEndpointSet->size()); +} + +void GatewayConfigLoader::parseConnectedJson( + const std::string& _json, EndPointSet& _nodeIPEndpointSet) +{ + /* + {"nodes":["127.0.0.1:30355","127.0.0.1:30356"}]} + */ + Json::Value root; + Json::Reader jsonReader; + try + { + if (!jsonReader.parse(_json, root)) + { + GATEWAY_LOG(ERROR) << "unable to parse connected nodes json" << LOG_KV("json:", _json); + BOOST_THROW_EXCEPTION( + WeDPRException() << errinfo_comment("GatewayConfig: unable to parse p2p " + "connected nodes json")); + } + Json::Value jNodes = root["nodes"]; + if (jNodes.isArray()) + { + unsigned int jNodesSize = jNodes.size(); + for (unsigned int i = 0; i < jNodesSize; i++) + { + std::string host = jNodes[i].asString(); + + NodeIPEndpoint endpoint; + hostAndPort2Endpoint(host, endpoint); + _nodeIPEndpointSet.insert(endpoint); + + GATEWAY_LOG(INFO) << LOG_DESC("add one connected node") << LOG_KV("host", host); + } + } + } + catch (const std::exception& e) + { + GATEWAY_LOG(ERROR) << LOG_KV( + "parseConnectedJson error: ", boost::diagnostic_information(e)); + BOOST_THROW_EXCEPTION(e); + } +} + +bool GatewayConfigLoader::isValidPort(int port) +{ + if (port <= 1024 || port > 65535) + return false; + return true; +} + +void GatewayConfigLoader::hostAndPort2Endpoint(const std::string& _host, NodeIPEndpoint& _endpoint) +{ + std::string ip; + uint16_t port; + + std::vector s; + boost::split(s, _host, boost::is_any_of("]"), boost::token_compress_on); + if (s.size() == 2) + { // ipv6 + ip = s[0].data() + 1; + port = boost::lexical_cast(s[1].data() + 1); + } + else if (s.size() == 1) + { // ipv4 + std::vector v; + boost::split(v, _host, boost::is_any_of(":"), boost::token_compress_on); + if (v.size() < 2) + { + BOOST_THROW_EXCEPTION( + WeDPRException() << errinfo_comment("GatewayConfig: invalid host , host=" + _host)); + } + ip = v[0]; + port = boost::lexical_cast(v[1]); + } + else + { + GATEWAY_LOG(ERROR) << LOG_DESC("not valid host value") << LOG_KV("host", _host); + BOOST_THROW_EXCEPTION(WeDPRException() << errinfo_comment( + "GatewayConfig: the host is invalid, host=" + _host)); + } + + if (!isValidPort(port)) + { + GATEWAY_LOG(ERROR) << LOG_DESC("the port is not valid") << LOG_KV("port", port); + BOOST_THROW_EXCEPTION( + WeDPRException() << errinfo_comment( + "GatewayConfig: the port is invalid, port=" + std::to_string(port))); + } + + boost::system::error_code ec; + boost::asio::ip::address ip_address = boost::asio::ip::make_address(ip, ec); + if (ec.value() != 0) + { + GATEWAY_LOG(ERROR) << LOG_DESC("the host is invalid, make_address error") + << LOG_KV("host", _host); + BOOST_THROW_EXCEPTION( + WeDPRException() << errinfo_comment( + "GatewayConfig: the host is invalid make_address error, host=" + _host)); + } + _endpoint = NodeIPEndpoint{ip_address, port}; +} diff --git a/cpp/wedpr-transport/ppc-gateway/ppc-gateway/GatewayConfigLoader.h b/cpp/wedpr-transport/ppc-gateway/ppc-gateway/GatewayConfigLoader.h new file mode 100644 index 00000000..4d523797 --- /dev/null +++ b/cpp/wedpr-transport/ppc-gateway/ppc-gateway/GatewayConfigLoader.h @@ -0,0 +1,55 @@ +/** + * 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 GatewayConfigLoader.h + * @author: yujiechen + * @date 2024-08-26 + */ +#pragma once +#include "bcos-boostssl/interfaces/NodeInfoDef.h" + +namespace ppc::tools +{ +class PPCConfig; +} +namespace ppc::gateway +{ +class GatewayConfigLoader +{ +public: + using EndPointSet = std::set; + using Ptr = std::shared_ptr; + GatewayConfigLoader(std::shared_ptr config) + : m_config(std::move(config)), m_nodeIPEndpointSet(std::make_shared()) + { + loadP2pConnectedNodes(); + } + virtual ~GatewayConfigLoader() = default; + + EndPointSet const& nodeIPEndpointSet() const { return *m_nodeIPEndpointSet; } + + std::shared_ptr const& nodeIPEndpointSetPtr() const { return m_nodeIPEndpointSet; } + +protected: + void parseConnectedJson(const std::string& _json, EndPointSet& nodeIPEndpointSet); + void loadP2pConnectedNodes(); + void hostAndPort2Endpoint(const std::string& _host, bcos::boostssl::NodeIPEndpoint& _endpoint); + bool isValidPort(int port); + +private: + std::shared_ptr m_config; + std::shared_ptr m_nodeIPEndpointSet; +}; +} // namespace ppc::gateway \ No newline at end of file diff --git a/cpp/wedpr-transport/ppc-gateway/ppc-gateway/GatewayFactory.cpp b/cpp/wedpr-transport/ppc-gateway/ppc-gateway/GatewayFactory.cpp new file mode 100644 index 00000000..1c330acc --- /dev/null +++ b/cpp/wedpr-transport/ppc-gateway/ppc-gateway/GatewayFactory.cpp @@ -0,0 +1,79 @@ +/** + * 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 GatewayFactory.cpp + * @author: yujiechen + * @date 2024-08-26 + */ +#include "GatewayFactory.h" +#include "Common.h" +#include "bcos-boostssl/utility/NewTimer.h" +#include "bcos-boostssl/websocket/WsInitializer.h" +#include "ppc-gateway/p2p/Service.h" +#include "ppc-gateway/p2p/router/RouterTableImpl.h" +#include "ppc-gateway/protocol/P2PMessageImpl.h" +#include "ppc-tools/src/config/PPCConfig.h" +#include "protocol/src/v1/MessageHeaderImpl.h" +#include "protocol/src/v1/MessageImpl.h" + +using namespace ppc; +using namespace bcos; +using namespace ppc::tools; +using namespace ppc::protocol; +using namespace ppc::gateway; +using namespace bcos::boostssl::ws; +using namespace bcos::boostssl; + +Service::Ptr GatewayFactory::buildService() const +{ + auto gwConfig = m_config->gatewayConfig(); + auto wsConfig = std::make_shared(); + wsConfig->setModel(WsModel::Mixed); + wsConfig->setListenIP(gwConfig.networkConfig.listenIp); + wsConfig->setListenPort(gwConfig.networkConfig.listenPort); + wsConfig->setSmSSL(gwConfig.networkConfig.enableSM); + wsConfig->setMaxMsgSize(gwConfig.maxAllowedMsgSize); + wsConfig->setReconnectPeriod(gwConfig.reconnectTime); + // default HeartbeatPeriod is 10s + wsConfig->setThreadPoolSize(gwConfig.networkConfig.threadPoolSize); + // connected peers + wsConfig->setConnectPeers(m_gatewayConfig->nodeIPEndpointSetPtr()); + wsConfig->setDisableSsl(gwConfig.networkConfig.disableSsl); + wsConfig->setContextConfig(m_contextConfig->contextConfig()); + + auto wsInitializer = std::make_shared(); + // set the messageFactory + auto msgBuilder = + std::make_shared(std::make_shared()); + wsInitializer->setMessageFactory(std::make_shared(msgBuilder)); + // set the config + wsInitializer->setConfig(wsConfig); + auto p2pService = std::make_shared(m_contextConfig->nodeID(), + std::make_shared(), m_config->gatewayConfig().unreachableDistance, + "Gateway-Service"); + p2pService->setTimerFactory(std::make_shared()); + p2pService->setNodeEndpoints(m_gatewayConfig->nodeIPEndpointSet()); + + wsInitializer->initWsService(p2pService); + return p2pService; +} + +IGateway::Ptr GatewayFactory::build(ppc::front::IFrontBuilder::Ptr const& frontBuilder) const +{ + auto service = buildService(); + return std::make_shared(service, frontBuilder, + std::make_shared(), m_config->agencyID(), + m_config->seqSyncPeriod()); +} \ No newline at end of file diff --git a/cpp/wedpr-transport/ppc-gateway/ppc-gateway/GatewayFactory.h b/cpp/wedpr-transport/ppc-gateway/ppc-gateway/GatewayFactory.h new file mode 100644 index 00000000..bef50884 --- /dev/null +++ b/cpp/wedpr-transport/ppc-gateway/ppc-gateway/GatewayFactory.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 GatewayFactory.h + * @author: yujiechen + * @date 2024-08-26 + */ +#pragma once +#include "GatewayConfigContext.h" +#include "GatewayConfigLoader.h" +#include "bcos-boostssl/websocket/WsConfig.h" +#include "gateway/GatewayImpl.h" +#include "ppc-gateway/p2p/Service.h" + +namespace ppc::tools +{ +class PPCConfig; +} +namespace ppc::gateway +{ +class GatewayFactory +{ +public: + using Ptr = std::shared_ptr; + GatewayFactory(std::shared_ptr config) : m_config(std::move(config)) + { + m_contextConfig = std::make_shared(m_config); + m_gatewayConfig = std::make_shared(m_config); + } + virtual ~GatewayFactory() = default; + + IGateway::Ptr build(ppc::front::IFrontBuilder::Ptr const& frontBuilder) const; + +protected: + Service::Ptr buildService() const; + +private: + std::shared_ptr m_config; + GatewayConfigContext::Ptr m_contextConfig; + GatewayConfigLoader::Ptr m_gatewayConfig; +}; +} // namespace ppc::gateway \ No newline at end of file diff --git a/cpp/wedpr-transport/ppc-gateway/ppc-gateway/gateway/GatewayImpl.cpp b/cpp/wedpr-transport/ppc-gateway/ppc-gateway/gateway/GatewayImpl.cpp new file mode 100644 index 00000000..bc6822b9 --- /dev/null +++ b/cpp/wedpr-transport/ppc-gateway/ppc-gateway/gateway/GatewayImpl.cpp @@ -0,0 +1,339 @@ +/** + * 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, + uint16_t seqSyncPeriod) + : 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_gatewayInfoFactory)) +{ + 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)); + m_gatewayRouterManager = std::make_shared( + m_service, m_gatewayInfoFactory, m_localRouter, m_peerRouter, seqSyncPeriod); + + m_service->registerOnNewSession([this](WsSession::Ptr _session) { + if (!_session) + { + return; + } + m_p2pRouterManager->onNewSession(_session->nodeId()); + }); + + m_service->registerOnDeleteSession([this](WsSession::Ptr _session) { + if (!_session) + { + return; + } + m_p2pRouterManager->onEraseSession(_session->nodeId()); + }); + + m_p2pRouterManager->registerUnreachableHandler([this](std::string const& unreachableNode) { + m_gatewayRouterManager->removeUnreachableP2pNode(unreachableNode); + }); + + m_service->registerDisconnectHandler([this](WsSession::Ptr _session) { + if (!_session) + { + return; + } + m_gatewayRouterManager->removeUnreachableP2pNode(_session->nodeId()); + }); +} + +void GatewayImpl::start() +{ + if (m_running) + { + GATEWAY_LOG(INFO) << LOG_DESC("Gateway has already been started"); + return; + } + m_running = true; + if (m_service) + { + m_service->start(); + } + if (m_p2pRouterManager) + { + m_p2pRouterManager->start(); + } + if (m_gatewayRouterManager) + { + m_gatewayRouterManager->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; + if (m_service) + { + m_service->stop(); + } + if (m_p2pRouterManager) + { + m_p2pRouterManager->stop(); + } + if (m_gatewayRouterManager) + { + m_gatewayRouterManager->stop(); + } + PEER_ROUTER_LOG(INFO) << LOG_DESC("Stop gateway success"); +} + +void GatewayImpl::asyncSendbroadcastMessage(ppc::protocol::RouteType routeType, + MessageOptionalHeader::Ptr const& routeInfo, std::string const& traceID, bcos::bytes&& payload) +{ + // dispatcher to all the local front + routeInfo->setDstNode(bcos::bytes()); + routeInfo->setSrcInst(m_agency); + + auto p2pMessage = m_msgBuilder->build(routeType, routeInfo, std::move(payload)); + p2pMessage->setSeq(traceID); + + 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, + ppc::protocol::MessageOptionalHeader::Ptr const& routeInfo, std::string const& traceID, + bcos::bytes&& payload, long timeout, ReceiveMsgFunc callback) +{ + routeInfo->setSrcInst(m_agency); + // check the localRouter + auto p2pMessage = m_msgBuilder->build(routeType, routeInfo, std::move(payload)); + p2pMessage->setSeq(traceID); + p2pMessage->setPacketType((uint16_t)GatewayPacketType::P2PMessage); + GATEWAY_LOG(TRACE) << LOG_DESC("asyncSendMessage") + << LOG_KV("msg", printP2PMessage(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", printP2PMessage(p2pMessage)); + m_localRouter->dispatcherMessage(p2pMessage, callback); + return; + } + // try to find the dstP2PNode + auto selectedP2PNodes = + m_peerRouter->selectRouter(routeType, p2pMessage->header()->optionalField()); + if (selectedP2PNodes.empty()) + { + GATEWAY_LOG(INFO) << LOG_DESC("can't find the gateway to send the message") + << LOG_KV("detail", printP2PMessage(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()); + // Note: the callback can only been called once since it binds the callback seq + auto callback = [p2pMessage, session, self](Error::Ptr error) { + auto gateway = self.lock(); + if (!gateway) + { + return; + } + // Note: no need to sendResponse for the response packet + if (p2pMessage->isRespPacket()) + { + 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()) + << printP2PMessage(p2pMessage); + 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", printP2PMessage(p2pMessage)); + callback(std::make_shared(CommonError::NotFoundFrontServiceDispatchMsg, + "unable to find the node to dispatcher this message, message detail: " + + printP2PMessage(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", printP2PMessage(p2pMessage)); + m_localRouter->dispatcherMessage(p2pMessage, nullptr); +} + +bcos::Error::Ptr GatewayImpl::registerNodeInfo(ppc::protocol::INodeInfo::Ptr const& nodeInfo) +{ + auto self = weak_from_this(); + m_localRouter->registerNodeInfo( + nodeInfo, + [nodeInfo, self]() { + // remove the unhealth node + GATEWAY_LOG(INFO) << LOG_DESC("Remove the unhealth node") << printNodeInfo(nodeInfo); + auto gateway = self.lock(); + if (!gateway) + { + return; + } + gateway->m_localRouter->unRegisterNode(nodeInfo->nodeID().toBytes()); + gateway->m_localRouter->increaseSeq(); + }, + true); + return nullptr; +} + +bcos::Error::Ptr GatewayImpl::unRegisterNodeInfo(bcos::bytesConstRef nodeID) +{ + m_localRouter->unRegisterNode(nodeID.toBytes()); + return nullptr; +} + +bcos::Error::Ptr GatewayImpl::registerTopic(bcos::bytesConstRef nodeID, std::string const& topic) +{ + m_localRouter->registerTopic(nodeID, topic); + return nullptr; +} + +bcos::Error::Ptr GatewayImpl::unRegisterTopic(bcos::bytesConstRef nodeID, std::string const& topic) +{ + m_localRouter->unRegisterTopic(nodeID, topic); + return nullptr; +} + +void GatewayImpl::asyncGetPeers(std::function callback) +{ + if (!callback) + { + return; + } + try + { + auto infos = m_peerRouter->gatewayInfos(); + Json::Value peers; + peers["agency"] = m_agency; + peers["nodeID"] = m_service->nodeID(); + // add the local gatewayInfo + Json::Value localGatewayInfo; + m_localRouter->routerInfo()->toJson(localGatewayInfo); + peers["gateway"] = localGatewayInfo; + peers["peers"] = Json::Value(Json::arrayValue); + for (auto const& it : infos) + { + auto gatewayInfoList = it.second; + Json::Value agencyGatewayInfo; + agencyGatewayInfo["agency"] = it.first; + Json::Value peersInfo(Json::arrayValue); + for (auto const& gatewayInfo : gatewayInfoList) + { + Json::Value gatewayJson; + gatewayInfo->toJson(gatewayJson); + peersInfo.append(gatewayJson); + } + agencyGatewayInfo["gateway"] = peersInfo; + peers["peers"].append(agencyGatewayInfo); + } + Json::FastWriter fastWriter; + std::string statusStr = fastWriter.write(peers); + callback(nullptr, statusStr); + } + catch (std::exception const& e) + { + GATEWAY_LOG(WARNING) << LOG_DESC("asyncGetPeers exception") + << LOG_KV("error", boost::diagnostic_information(e)); + callback( + std::make_shared( + -1, "asyncGetPeers exception for " + std::string(boost::diagnostic_information(e))), + ""); + } +} + +void GatewayImpl::asyncGetAgencies(std::vector const& components, + std::function)> callback) +{ + if (!callback) + { + return; + } + auto agencies = m_peerRouter->agencies(components); + agencies.insert(m_agency); + callback(nullptr, agencies); +} \ No newline at end of file diff --git a/cpp/wedpr-transport/ppc-gateway/ppc-gateway/gateway/GatewayImpl.h b/cpp/wedpr-transport/ppc-gateway/ppc-gateway/gateway/GatewayImpl.h new file mode 100644 index 00000000..b3fd2664 --- /dev/null +++ b/cpp/wedpr-transport/ppc-gateway/ppc-gateway/gateway/GatewayImpl.h @@ -0,0 +1,113 @@ +/** + * 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/GatewayRouterManager.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, + uint16_t seqSyncPeriod = 5000); + ~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, + ppc::protocol::MessageOptionalHeader::Ptr const& routeInfo, std::string const& traceID, + bcos::bytes&& payload, long timeout, ppc::protocol::ReceiveMsgFunc callback) override; + + void asyncSendbroadcastMessage(ppc::protocol::RouteType routeType, + ppc::protocol::MessageOptionalHeader::Ptr const& routeInfo, std::string const& traceID, + bcos::bytes&& payload) override; + + + bcos::Error::Ptr registerNodeInfo(ppc::protocol::INodeInfo::Ptr const& nodeInfo) override; + bcos::Error::Ptr unRegisterNodeInfo(bcos::bytesConstRef nodeID) override; + bcos::Error::Ptr registerTopic(bcos::bytesConstRef nodeID, std::string const& topic) override; + bcos::Error::Ptr unRegisterTopic(bcos::bytesConstRef nodeID, std::string const& topic) override; + + void asyncGetPeers(std::function callback) override; + void asyncGetAgencies(std::vector const& components, + std::function)> callback) override; + + std::vector selectNodesByRoutePolicy(ppc::protocol::RouteType routeType, + ppc::protocol::MessageOptionalHeader::Ptr const& routeInfo) override + { + return m_peerRouter->selectTargetNodes(routeType, routeInfo); + } + + std::vector getAliveNodeList() const override + { + auto aliveNodeList = m_localRouter->routerInfo()->nodeList(); + std::vector result; + for (auto const& it : aliveNodeList) + { + result.emplace_back(it.second); + } + return result; + } + +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::P2PMessageBuilder::Ptr m_msgBuilder; + + ppc::front::IFrontBuilder::Ptr m_frontBuilder; + std::string m_agency; + + RouterManager::Ptr m_p2pRouterManager; + GatewayRouterManager::Ptr m_gatewayRouterManager; + + 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/wedpr-transport/ppc-gateway/ppc-gateway/gateway/SendMessageWithRetry.cpp b/cpp/wedpr-transport/ppc-gateway/ppc-gateway/gateway/SendMessageWithRetry.cpp new file mode 100644 index 00000000..4eb0a686 --- /dev/null +++ b/cpp/wedpr-transport/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: unable to send the message") + << printP2PMessage(m_p2pMessage); + if (m_respFunc) + { + m_respFunc(std::make_shared( + -1, "can't find the gateway to send the message, detail: " + + printP2PMessage(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", printP2PMessage(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", printP2PMessage(self->m_p2pMessage)); + // try again + self->trySendMessage(); + return; + } + GATEWAY_LOG(TRACE) << LOG_BADGE("asyncSendMessageByNodeID success") + << LOG_KV("msg", printP2PMessage(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", printP2PMessage(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/wedpr-transport/ppc-gateway/ppc-gateway/gateway/SendMessageWithRetry.h b/cpp/wedpr-transport/ppc-gateway/ppc-gateway/gateway/SendMessageWithRetry.h new file mode 100644 index 00000000..bfd63a85 --- /dev/null +++ b/cpp/wedpr-transport/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/P2PMessage.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::P2PMessage::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::P2PMessage::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/wedpr-transport/ppc-gateway/ppc-gateway/gateway/cache/MessageCache.cpp b/cpp/wedpr-transport/ppc-gateway/ppc-gateway/gateway/cache/MessageCache.cpp new file mode 100644 index 00000000..3eb7e418 --- /dev/null +++ b/cpp/wedpr-transport/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::P2PMessage::Ptr const& msg, ReceiveMsgFunc callback) +{ + // hold the message + GATEWAY_LOG(DEBUG) << LOG_BADGE("MessageCache: insertCache") << printP2PMessage(msg); + 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, "timeout")); + } + } +} \ No newline at end of file diff --git a/cpp/wedpr-transport/ppc-gateway/ppc-gateway/gateway/cache/MessageCache.h b/cpp/wedpr-transport/ppc-gateway/ppc-gateway/gateway/cache/MessageCache.h new file mode 100644 index 00000000..33549ad6 --- /dev/null +++ b/cpp/wedpr-transport/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/P2PMessage.h" +#include "tbb/concurrent_vector.h" +#include +#include +#include + +namespace ppc::gateway +{ +struct MessageInfo +{ + ppc::protocol::P2PMessage::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::P2PMessage::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/wedpr-transport/ppc-gateway/ppc-gateway/gateway/router/GatewayNodeInfo.h b/cpp/wedpr-transport/ppc-gateway/ppc-gateway/gateway/router/GatewayNodeInfo.h new file mode 100644 index 00000000..e12fe0d6 --- /dev/null +++ b/cpp/wedpr-transport/ppc-gateway/ppc-gateway/gateway/router/GatewayNodeInfo.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 GatewayNodeInfo.h + * @author: yujiechen + * @date 2024-08-26 + */ +#pragma once +#include "ppc-framework/Helper.h" +#include "ppc-framework/protocol/INodeInfo.h" +#include "ppc-utilities/Utilities.h" +#include +#include +#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; + 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; + 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, bcos::bytes const& fromNode, 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; + virtual bool existComponent(std::string const& component) const = 0; + virtual uint16_t nodeSize() const = 0; + virtual void toJson(Json::Value& jsonObject) const = 0; +}; + +class GatewayNodeInfoFactory +{ +public: + using Ptr = std::shared_ptr; + GatewayNodeInfoFactory() = default; + virtual ~GatewayNodeInfoFactory() = default; + + virtual GatewayNodeInfo::Ptr build() const = 0; + virtual GatewayNodeInfo::Ptr build(std::string const& p2pNode) 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; + +inline std::string printNodeStatus(GatewayNodeInfo::Ptr const& status) +{ + std::ostringstream stringstream; + stringstream << LOG_KV("p2pNodeID", printP2PIDElegantly(status->p2pNodeID())) + << LOG_KV("agency", status->agency()) << LOG_KV("statusSeq", status->statusSeq()) + << LOG_KV("nodeSize", status->nodeSize()); + auto nodeInfoList = status->nodeList(); + for (auto const& it : nodeInfoList) + { + stringstream << printNodeInfo(it.second); + } + return stringstream.str(); +} +} // namespace ppc::gateway \ No newline at end of file diff --git a/cpp/wedpr-transport/ppc-gateway/ppc-gateway/gateway/router/GatewayNodeInfoImpl.cpp b/cpp/wedpr-transport/ppc-gateway/ppc-gateway/gateway/router/GatewayNodeInfoImpl.cpp new file mode 100644 index 00000000..c23a695b --- /dev/null +++ b/cpp/wedpr-transport/ppc-gateway/ppc-gateway/gateway/router/GatewayNodeInfoImpl.cpp @@ -0,0 +1,301 @@ +/** + * 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-gateway/Common.h" +#include "wedpr-protocol/protobuf/src/Common.h" +#include "wedpr-protocol/protobuf/src/NodeInfoImpl.h" +#include "wedpr-protocol/tars/Common.h" + +using namespace ppctars; +using namespace ppc::protocol; +using namespace ppc::gateway; + + +// the gateway nodeID +std::string const& GatewayNodeInfoImpl::p2pNodeID() const +{ + return m_rawGatewayInfo->p2pnodeid(); +} +// the agency +std::string const& GatewayNodeInfoImpl::agency() const +{ + return m_rawGatewayInfo->agency(); +} + +uint32_t GatewayNodeInfoImpl::statusSeq() const +{ + return m_rawGatewayInfo->statusseq(); +} +void GatewayNodeInfoImpl::setStatusSeq(uint32_t statusSeq) +{ + m_rawGatewayInfo->set_statusseq(statusSeq); +} + +// 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::existComponent(std::string const& component) const +{ + bcos::ReadGuard l(x_nodeList); + for (auto const& it : m_nodeList) + { + if (it.second->componentExist(component)) + { + return true; + } + } + return false; +} + +void GatewayNodeInfoImpl::updateNodeList() +{ + // Note: can't use clear_nodelist here, for clear_nodelist will destroy the allocated nodelist, + // and cause double release coredump + releaseWithoutDestory(); + // re-encode nodeList + for (auto const& it : m_nodeList) + { + auto nodeInfo = std::dynamic_pointer_cast(it.second); + nodeInfo->encodeFields(); + m_rawGatewayInfo->mutable_nodelist()->UnsafeArenaAddAllocated( + nodeInfo->rawNodeInfo().get()); + } +} + +// Note: this is wrappered with lock +bool GatewayNodeInfoImpl::tryAddNodeInfo(INodeInfo::Ptr const& info) +{ + auto nodeID = info->nodeID().toBytes(); + auto existedNodeInfo = nodeInfo(nodeID); + // the node info has not been updated + if (existedNodeInfo != nullptr && existedNodeInfo->equal(info)) + { + auto meta = info->meta(); + // update the meta + if (meta != existedNodeInfo->meta()) + { + bcos::WriteGuard l(x_nodeList); + existedNodeInfo->setMeta(meta); + GATEWAY_LOG(INFO) << LOG_DESC("tryAddNodeInfo, update the meta, updated nodeInfo") + << printNodeInfo(existedNodeInfo); + } + // update the components + auto components = info->copiedComponents(); + if (components != existedNodeInfo->copiedComponents()) + { + bcos::WriteGuard l(x_nodeList); + existedNodeInfo->setComponents( + std::set(components.begin(), components.end())); + GATEWAY_LOG(INFO) << LOG_DESC("tryAddNodeInfo, update the components, updated nodeInfo") + << printNodeInfo(existedNodeInfo); + } + return false; + } + { + bcos::WriteGuard l(x_nodeList); + m_nodeList[nodeID] = info; + updateNodeList(); + } + return true; +} + +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); + updateNodeList(); + } + // 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) + { + auto front = it.second->getFront(); + if (front && it.second->components().count(component)) + { + result.emplace_back(front); + } + if (!result.empty() && !selectAll) + { + break; + } + } + return result; +} + + +std::vector> GatewayNodeInfoImpl::chooseRouterByAgency( + bool selectAll) const +{ + std::vector> result; + bcos::ReadGuard l(x_nodeList); + for (auto const& it : m_nodeList) + { + auto front = it.second->getFront(); + if (front) + { + result.emplace_back(front); + } + if (!result.empty() && !selectAll) + { + break; + } + } + return result; +} + +std::vector> GatewayNodeInfoImpl::chooseRouterByTopic( + bool selectAll, bcos::bytes const& fromNode, std::string const& topic) const +{ + std::vector> result; + // empty topic means broadcast message to all front + if (topic.empty()) + { + bcos::ReadGuard l(x_nodeList); + for (auto const& it : m_nodeList) + { + auto front = it.second->getFront(); + if (front) + { + result.emplace_back(front); + } + } + return result; + } + // the topic specified + bcos::ReadGuard l(x_topicInfo); + for (auto const& it : m_topicInfo) + { + INodeInfo::Ptr selectedNode = nullptr; + if (it.second.count(topic)) + { + selectedNode = nodeInfo(it.first); + } + // ignore the fromNode + if (selectedNode != nullptr && selectedNode->nodeID().toBytes() != fromNode) + { + auto front = selectedNode->getFront(); + if (front) + { + result.emplace_back(front); + } + } + 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 +{ + bcos::ReadGuard l(x_nodeList); + encodePBObject(data, m_rawGatewayInfo); +} + +void GatewayNodeInfoImpl::decode(bcos::bytesConstRef data) +{ + decodePBObject(m_rawGatewayInfo, data); + { + bcos::WriteGuard l(x_nodeList); + // decode into m_nodeList + m_nodeList.clear(); + for (int i = 0; i < m_rawGatewayInfo->nodelist_size(); i++) + { + std::shared_ptr rawNodeInfo( + m_rawGatewayInfo->mutable_nodelist(i)); + auto nodeInfoPtr = std::make_shared(rawNodeInfo); + m_nodeList.insert(std::make_pair(nodeInfoPtr->nodeID().toBytes(), nodeInfoPtr)); + } + } +} + +void GatewayNodeInfoImpl::toJson(Json::Value& jsonObject) const +{ + bcos::ReadGuard l(x_nodeList); + jsonObject["gatewayNodeID"] = p2pNodeID(); + jsonObject["agency"] = agency(); + + auto agencyNodeList = nodeList(); + Json::Value frontList(Json::arrayValue); + for (auto const& it : agencyNodeList) + { + Json::Value nodeInfo; + it.second->toJson(nodeInfo); + frontList.append(nodeInfo); + } + jsonObject["frontList"] = frontList; +} \ No newline at end of file diff --git a/cpp/wedpr-transport/ppc-gateway/ppc-gateway/gateway/router/GatewayNodeInfoImpl.h b/cpp/wedpr-transport/ppc-gateway/ppc-gateway/gateway/router/GatewayNodeInfoImpl.h new file mode 100644 index 00000000..aeab2c1d --- /dev/null +++ b/cpp/wedpr-transport/ppc-gateway/ppc-gateway/gateway/router/GatewayNodeInfoImpl.h @@ -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 GatewayNodeInfoImpl.h + * @author: yujiechen + * @date 2024-08-26 + */ +#pragma once +#include "GatewayNodeInfo.h" +#include "NodeInfo.pb.h" +#include +#include + +namespace ppc::gateway +{ +class GatewayNodeInfoImpl : public GatewayNodeInfo +{ +public: + using Ptr = std::shared_ptr; + GatewayNodeInfoImpl() : m_rawGatewayInfo(std::make_shared()) {} + GatewayNodeInfoImpl(std::string const& p2pNodeID) : GatewayNodeInfoImpl() + { + m_rawGatewayInfo->set_p2pnodeid(p2pNodeID); + } + GatewayNodeInfoImpl(std::string const& p2pNodeID, std::string const& agency) + : GatewayNodeInfoImpl(p2pNodeID) + { + m_rawGatewayInfo->set_agency(agency); + } + + GatewayNodeInfoImpl(bcos::bytesConstRef data) : GatewayNodeInfoImpl() { decode(data); } + + ~GatewayNodeInfoImpl() override { releaseWithoutDestory(); } + + // 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, bcos::bytes const& fromNode, 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::ReadGuard l(x_nodeList); + return m_nodeList; + } + uint32_t statusSeq() const override; + void setStatusSeq(uint32_t statusSeq) override; + + virtual uint16_t nodeSize() const override + { + bcos::ReadGuard l(x_nodeList); + return m_nodeList.size(); + } + + void toJson(Json::Value& jsonObject) const override; + + bool existComponent(std::string const& component) const override; + +private: + void updateNodeList(); + + void releaseWithoutDestory() + { + // return back the ownership to nodeList to shared_ptr + auto allocatedNodeListSize = m_rawGatewayInfo->nodelist_size(); + for (int i = 0; i < allocatedNodeListSize; i++) + { + m_rawGatewayInfo->mutable_nodelist()->UnsafeArenaReleaseLast(); + } + } + +private: + std::shared_ptr m_rawGatewayInfo; + // NodeID => nodeInfo + std::map m_nodeList; + mutable bcos::SharedMutex x_nodeList; + + // NodeID=>topics(Note serialized) + 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); + } + + GatewayNodeInfo::Ptr build(std::string const& p2pNode) const override + { + return std::make_shared(p2pNode); + } + +private: + std::string m_p2pNodeID; + std::string m_agency; +}; +} // namespace ppc::gateway \ No newline at end of file diff --git a/cpp/wedpr-transport/ppc-gateway/ppc-gateway/gateway/router/GatewayRouterManager.cpp b/cpp/wedpr-transport/ppc-gateway/ppc-gateway/gateway/router/GatewayRouterManager.cpp new file mode 100644 index 00000000..19f80e8e --- /dev/null +++ b/cpp/wedpr-transport/ppc-gateway/ppc-gateway/gateway/router/GatewayRouterManager.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 GatewayRouterManager.h + * @author: yujiechen + * @date 2024-08-26 + */ +#include "GatewayRouterManager.h" +#include "ppc-framework/Helper.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, uint16_t seqSyncPeriod) + : m_service(std::move(service)), + m_nodeStatusFactory(std::move(nodeStatusFactory)), + m_localRouter(std::move(localRouter)), + m_peerRouter(std::move(peerRouter)), + m_seqSyncPeriod(seqSyncPeriod) +{ + 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(m_seqSyncPeriod, "seqSync"); + // broadcast seq periodically + m_timer->registerTimeoutHandler([this]() { broadcastStatusSeq(); }); +} + + +void GatewayRouterManager::start() +{ + if (m_running) + { + ROUTER_MGR_LOG(INFO) << LOG_DESC("GatewayRouterManager has already been started"); + return; + } + m_running = true; + if (m_timer) + { + m_timer->start(); + } + ROUTER_MGR_LOG(INFO) << LOG_DESC("start GatewayRouterManager success"); +} + +void GatewayRouterManager::stop() +{ + if (!m_running) + { + ROUTER_MGR_LOG(INFO) << LOG_DESC("GatewayRouterManager has already been stopped"); + return; + } + m_running = false; + if (m_timer) + { + m_timer->stop(); + } + ROUTER_MGR_LOG(INFO) << LOG_DESC("stop GatewayRouterManager success"); +} + +void GatewayRouterManager::removeUnreachableP2pNode(std::string const& p2pNode) +{ + ROUTER_MGR_LOG(INFO) << LOG_DESC("removeUnreachableP2pNode") + << LOG_KV("p2pid", printP2PIDElegantly(p2pNode)); + { + // remove statusSeq info + WriteGuard l(x_p2pID2Seq); + m_p2pID2Seq.erase(p2pNode); + } + m_peerRouter->removeP2PID(p2pNode); +} + +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 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 + ROUTER_MGR_LOG(TRACE) + << LOG_DESC("onReceiveNodeSeqMessage: statusChanged, request the lastest nodeStatus") + << LOG_KV("node", printP2PIDElegantly(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); + ROUTER_MGR_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 from = (!p2pMessage->header()->srcGwNode().empty()) ? p2pMessage->header()->srcGwNode() : + session->nodeId(); + + auto nodeStatusData = m_localRouter->generateNodeStatus(); + if (!nodeStatusData) + { + ROUTER_MGR_LOG(WARNING) << LOG_DESC( + "onReceiveRequestNodeStatusMsg: generate nodeInfo error") + << LOG_KV("from", printP2PIDElegantly(from)); + return; + } + ROUTER_MGR_LOG(TRACE) << LOG_DESC( + "onReceiveRequestNodeStatusMsg: response the latest nodeStatus") + << LOG_KV("to", printP2PIDElegantly(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(); + + ROUTER_MGR_LOG(INFO) << LOG_DESC("onRecvResponseNodeStatusMsg") + << LOG_KV("node", printP2PIDElegantly(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; + } + ROUTER_MGR_LOG(INFO) << LOG_DESC("updatePeerNodeStatus") + << LOG_KV("node", printP2PIDElegantly(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/wedpr-transport/ppc-gateway/ppc-gateway/gateway/router/GatewayRouterManager.h b/cpp/wedpr-transport/ppc-gateway/ppc-gateway/gateway/router/GatewayRouterManager.h new file mode 100644 index 00000000..4224c290 --- /dev/null +++ b/cpp/wedpr-transport/ppc-gateway/ppc-gateway/gateway/router/GatewayRouterManager.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 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, + uint16_t seqSyncPeriod = 5000); + virtual void start(); + virtual void stop(); + + void removeUnreachableP2pNode(std::string const& p2pNode); + +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; + + uint16_t m_seqSyncPeriod; +}; +} // namespace ppc::gateway \ No newline at end of file diff --git a/cpp/wedpr-transport/ppc-gateway/ppc-gateway/gateway/router/LocalRouter.cpp b/cpp/wedpr-transport/ppc-gateway/ppc-gateway/gateway/router/LocalRouter.cpp new file mode 100644 index 00000000..5ada018c --- /dev/null +++ b/cpp/wedpr-transport/ppc-gateway/ppc-gateway/gateway/router/LocalRouter.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 LocalRouter.h + * @author: yujiechen + * @date 2024-08-26 + */ +#include "LocalRouter.h" +#include "ppc-framework/Helper.h" +#include "ppc-framework/gateway/GatewayProtocol.h" +#include "ppc-gateway/Common.h" + +using namespace bcos; +using namespace ppc::protocol; +using namespace ppc::gateway; + +bool LocalRouter::registerNodeInfo(ppc::protocol::INodeInfo::Ptr nodeInfo, + std::function onUnHealthHandler, bool removeHandlerOnUnhealth) +{ + LOCAL_ROUTER_LOG(INFO) << LOG_DESC("registerNodeInfo") << printNodeInfo(nodeInfo); + auto ret = m_routerInfo->tryAddNodeInfo(nodeInfo); + if (ret) + { + // only create the frontClient when update + nodeInfo->setFront(m_frontBuilder->buildClient( + nodeInfo->endPoint(), onUnHealthHandler, removeHandlerOnUnhealth)); + LOCAL_ROUTER_LOG(INFO) << LOG_DESC("registerNodeInfo: update the node") + << printNodeInfo(nodeInfo); + increaseSeq(); + } + return ret; +} +// Note: the change of the topic will not trigger router-update +void LocalRouter::registerTopic(bcos::bytesConstRef _nodeID, std::string const& topic) +{ + LOCAL_ROUTER_LOG(INFO) << LOG_DESC("registerTopic") << LOG_KV("topic", topic) + << LOG_KV("nodeID", printNodeID(_nodeID)); + 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) + { + LOCAL_ROUTER_LOG(INFO) << LOG_DESC("registerTopic, dispatcher the holding msg queue") + << LOG_KV("topic", topic) << LOG_KV("nodeID", printNodeID(_nodeID)); + dispatcherMessage(msgInfo.msg, msgInfo.callback, false); + } +} + +// Note: the change of the topic will not trigger router-update +void LocalRouter::unRegisterTopic(bcos::bytesConstRef _nodeID, std::string const& topic) +{ + LOCAL_ROUTER_LOG(INFO) << LOG_DESC("unRegisterTopic") << LOG_KV("topic", topic) + << LOG_KV("nodeID", printNodeID(_nodeID)); + m_routerInfo->unRegisterTopic(_nodeID.toBytes(), topic); +} + +bool LocalRouter::dispatcherMessage( + P2PMessage::Ptr const& msg, ReceiveMsgFunc callback, bool holding) +{ + auto frontList = chooseReceiver(msg); + auto commonCallback = [](bcos::Error::Ptr error) { + if (!error || error->errorCode() == 0) + { + return; + } + LOCAL_ROUTER_LOG(WARNING) << LOG_DESC("dispatcherMessage to front failed") + << LOG_KV("code", error->errorCode()) + << LOG_KV("msg", error->errorMessage()); + }; + // find the front + if (!frontList.empty()) + { + // Note: the callback can only been called once since it binds the callback seq + int i = 0; + for (auto const& front : frontList) + { + if (!front) + { + continue; + } + if (i == 0) + { + front->onReceiveMessage(msg->msg(), callback); + } + else + { + front->onReceiveMessage(msg->msg(), commonCallback); + } + i++; + } + return true; + } + // the case broadcast failed + if (msg->header() && msg->header()->optionalField() && + msg->header()->optionalField()->topic().empty()) + { + LOCAL_ROUTER_LOG(WARNING) << LOG_DESC("dispatcherMessage failed for no target found!") + << printP2PMessage(msg); + return false; + } + 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) + { + // send response when hodling the message + if (callback) + { + callback(nullptr); + } + m_cache->insertCache(msg->header()->optionalField()->topic(), msg, commonCallback); + return true; + } + return false; +} + +std::vector LocalRouter::chooseReceiver( + ppc::protocol::P2PMessage::Ptr const& msg) +{ + std::vector receivers; + auto const& dstInst = msg->header()->optionalField()->dstInst(); + if (!dstInst.empty() && 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()); + auto front = gatewayInfo ? gatewayInfo->getFront() : nullptr; + if (gatewayInfo != nullptr && front) + { + receivers.emplace_back(front); + } + return receivers; + } + case (uint16_t)RouteType::ROUTE_THROUGH_COMPONENT: + { + // Note: should check the dstInst when route-by-component + return m_routerInfo->chooseRouteByComponent( + selectAll, msg->header()->optionalField()->componentType()); + } + case (uint16_t)RouteType::ROUTE_THROUGH_AGENCY: + { + // Note: should check the dstInst when route-by-agency + return m_routerInfo->chooseRouterByAgency(selectAll); + } + case (uint16_t)RouteType::ROUTE_THROUGH_TOPIC: + { + // Note: should ignore the srcNode when route-by-topic + return m_routerInfo->chooseRouterByTopic(selectAll, + msg->header()->optionalField()->srcNode(), msg->header()->optionalField()->topic()); + } + default: + BOOST_THROW_EXCEPTION(WeDPRException() << errinfo_comment( + "chooseReceiver failed for unknown routeType, message detail: " + + printP2PMessage(msg))); + } +} diff --git a/cpp/wedpr-transport/ppc-gateway/ppc-gateway/gateway/router/LocalRouter.h b/cpp/wedpr-transport/ppc-gateway/ppc-gateway/gateway/router/LocalRouter.h new file mode 100644 index 00000000..e64aadb8 --- /dev/null +++ b/cpp/wedpr-transport/ppc-gateway/ppc-gateway/gateway/router/LocalRouter.h @@ -0,0 +1,90 @@ +/** + * 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/P2PMessage.h" +#include "ppc-framework/protocol/RouteType.h" + +namespace ppc::gateway +{ +class LocalRouter +{ +public: + using Ptr = std::shared_ptr; + LocalRouter(GatewayNodeInfoFactory::Ptr gatewayNodeInfoFactory, + ppc::front::IFrontBuilder::Ptr frontBuilder, MessageCache::Ptr msgCache) + : m_routerInfo(gatewayNodeInfoFactory->build()), + m_frontBuilder(std::move(frontBuilder)), + m_cache(std::move(msgCache)) + {} + + virtual ~LocalRouter() = default; + + virtual bool registerNodeInfo(ppc::protocol::INodeInfo::Ptr nodeInfo, + std::function onUnHealthHandler, bool removeHandlerOnUnhealth); + 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); + + virtual std::vector chooseReceiver( + ppc::protocol::P2PMessage::Ptr const& msg); + + virtual bool dispatcherMessage(ppc::protocol::P2PMessage::Ptr const& msg, + ppc::protocol::ReceiveMsgFunc callback, bool holding = true); + + std::shared_ptr generateNodeStatus() + { + auto data = std::make_shared(); + m_routerInfo->setStatusSeq(m_statusSeq); + m_routerInfo->encode(*data); + return data; + } + uint32_t statusSeq() { return m_statusSeq; } + + GatewayNodeInfo::Ptr const& routerInfo() const { return m_routerInfo; } + + 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; + mutable bcos::SharedMutex x_topicInfo; + + MessageCache::Ptr m_cache; +}; +} // namespace ppc::gateway \ No newline at end of file diff --git a/cpp/wedpr-transport/ppc-gateway/ppc-gateway/gateway/router/PeerRouterTable.cpp b/cpp/wedpr-transport/ppc-gateway/ppc-gateway/gateway/router/PeerRouterTable.cpp new file mode 100644 index 00000000..533578a0 --- /dev/null +++ b/cpp/wedpr-transport/ppc-gateway/ppc-gateway/gateway/router/PeerRouterTable.cpp @@ -0,0 +1,309 @@ +/** + * 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 "ppc-framework/Helper.h" +#include + +using namespace bcos; +using namespace ppc; +using namespace ppc::gateway; +using namespace ppc::protocol; + +void PeerRouterTable::updateGatewayInfo(GatewayNodeInfo::Ptr const& gatewayInfo) +{ + PEER_ROUTER_LOG(INFO) << LOG_DESC("updateGatewayInfo") + << LOG_KV("detail", printNodeStatus(gatewayInfo)); + auto nodeList = gatewayInfo->nodeList(); + + removeP2PNodeIDFromNodeIDInfos(gatewayInfo); + removeP2PNodeIDFromAgencyInfos(gatewayInfo->p2pNodeID()); + insertGatewayInfo(gatewayInfo); +} + +void PeerRouterTable::insertGatewayInfo(GatewayNodeInfo::Ptr const& gatewayInfo) +{ + auto nodeList = gatewayInfo->nodeList(); + bcos::WriteGuard l(x_mutex); + // insert new information for the gateway + 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); +} + +void PeerRouterTable::removeP2PNodeIDFromNodeIDInfos(GatewayNodeInfo::Ptr const& gatewayInfo) +{ + bcos::WriteGuard l(x_mutex); + // remove the origin information of the gateway + auto it = m_nodeID2GatewayInfos.begin(); + for (; it != m_nodeID2GatewayInfos.end();) + { + auto& gatewayInfos = it->second; + auto ptr = gatewayInfos.find(gatewayInfo); + if (ptr != gatewayInfos.end()) + { + gatewayInfos.erase(ptr); + } + if (gatewayInfos.empty()) + { + it = m_nodeID2GatewayInfos.erase(it); + continue; + } + it++; + } +} + +void PeerRouterTable::removeP2PNodeIDFromAgencyInfos(std::string const& p2pNode) +{ + bcos::WriteGuard l(x_mutex); + for (auto it = m_agency2GatewayInfos.begin(); it != m_agency2GatewayInfos.end();) + { + auto& gatewayInfos = it->second; + for (auto pGateway = gatewayInfos.begin(); pGateway != gatewayInfos.end();) + { + if ((*pGateway)->p2pNodeID() == p2pNode) + { + pGateway = gatewayInfos.erase(pGateway); + continue; + } + pGateway++; + } + if (gatewayInfos.empty()) + { + it = m_agency2GatewayInfos.erase(it); + continue; + } + it++; + } +} + +void PeerRouterTable::removeP2PID(std::string const& p2pNode) +{ + PEER_ROUTER_LOG(INFO) << LOG_DESC("PeerRouterTable: removeP2PID") + << LOG_KV("p2pID", printP2PIDElegantly(p2pNode)); + // remove P2PNode from m_nodeID2GatewayInfos + auto gatewayInfo = m_gatewayInfoFactory->build(p2pNode); + removeP2PNodeIDFromNodeIDInfos(gatewayInfo); + // remove P2PNode from m_agency2GatewayInfos + removeP2PNodeIDFromAgencyInfos(p2pNode); +} + +std::set PeerRouterTable::agencies(std::vector const& components) const +{ + std::set agencies; + bcos::ReadGuard l(x_mutex); + for (auto const& it : m_agency2GatewayInfos) + { + // get all agencies + if (components.empty()) + { + agencies.insert(it.first); + continue; + } + // get agencies according to component + for (auto const& gatewayInfo : it.second) + { + for (auto const& component : components) + { + if (gatewayInfo->existComponent(component)) + { + agencies.insert(it.first); + break; + } + } + } + } + return agencies; +} + +GatewayNodeInfos PeerRouterTable::selectRouter( + RouteType const& routeType, MessageOptionalHeader::Ptr const& routeInfo) const +{ + switch (routeType) + { + case RouteType::ROUTE_THROUGH_NODEID: + return selectRouterByNodeID(routeInfo); + case RouteType::ROUTE_THROUGH_COMPONENT: + return selectRouterByComponent(routeInfo); + case RouteType::ROUTE_THROUGH_AGENCY: + case RouteType::ROUTE_THROUGH_TOPIC: + return selectRouterByAgency(routeInfo); + default: + BOOST_THROW_EXCEPTION(WeDPRException() << errinfo_comment( + "selectRouter failed for encounter unsupported routeType: " + + std::to_string((uint16_t)routeType))); + } +} + +std::vector PeerRouterTable::selectTargetNodes( + RouteType const& routeType, MessageOptionalHeader::Ptr const& routeInfo) const +{ + std::set targetNodeList; + auto selectedP2PNodes = selectRouter(routeType, routeInfo); + if (selectedP2PNodes.empty()) + { + PEER_ROUTER_LOG(INFO) << LOG_DESC("selectTargetNodes with empty result") + << LOG_KV("routeType", routeType) + << LOG_KV("routeInfo", printOptionalField(routeInfo)); + return std::vector(); + } + for (auto const& it : selectedP2PNodes) + { + auto nodeList = it->nodeList(); + for (auto const& it : nodeList) + { + if (routeType == RouteType::ROUTE_THROUGH_COMPONENT) + { + if (it.second->componentExist(routeInfo->componentType())) + { + targetNodeList.insert(std::string(it.first.begin(), it.first.end())); + } + continue; + } + targetNodeList.insert(std::string(it.first.begin(), it.first.end())); + } + } + PEER_ROUTER_LOG(INFO) << LOG_DESC("selectTargetNodes, result: ") + << printCollection(targetNodeList) << LOG_KV("routeType", routeType) + << LOG_KV("routeInfo", printOptionalField(routeInfo)); + return std::vector(targetNodeList.begin(), targetNodeList.end()); +} + +GatewayNodeInfos PeerRouterTable::selectRouterByNodeID( + MessageOptionalHeader::Ptr const& routeInfo) const +{ + GatewayNodeInfos result; + bcos::ReadGuard l(x_mutex); + auto it = m_nodeID2GatewayInfos.find(routeInfo->dstNode()); + // no router found + if (it == m_nodeID2GatewayInfos.end()) + { + return result; + } + return it->second; +} + + +GatewayNodeInfos PeerRouterTable::selectRouterByAgency( + MessageOptionalHeader::Ptr const& routeInfo) const +{ + GatewayNodeInfos result; + bcos::ReadGuard l(x_mutex); + auto it = m_agency2GatewayInfos.find(routeInfo->dstInst()); + // no router found + if (it == m_agency2GatewayInfos.end()) + { + return result; + } + return it->second; +} + +// Note: selectRouterByComponent support not specified the dstInst +GatewayNodeInfos PeerRouterTable::selectRouterByComponent( + MessageOptionalHeader::Ptr const& routeInfo) const +{ + GatewayNodeInfos result; + auto dstInst = routeInfo->dstInst(); + std::vector selectedRouterInfos; + { + bcos::ReadGuard l(x_mutex); + if (dstInst.size() > 0) + { + // specified the dstInst + auto it = m_agency2GatewayInfos.find(dstInst); + // no router found + if (it == m_agency2GatewayInfos.end()) + { + return result; + } + selectedRouterInfos.emplace_back(it->second); + } + else + { + // the dstInst not specified, query from all agencies + for (auto const& it : m_agency2GatewayInfos) + { + selectedRouterInfos.emplace_back(it.second); + } + } + } + for (auto const& it : selectedRouterInfos) + { + selectRouterByComponent(result, routeInfo, it); + } + return result; +} + + +void PeerRouterTable::selectRouterByComponent(GatewayNodeInfos& choosedGateway, + MessageOptionalHeader::Ptr const& routeInfo, + GatewayNodeInfos const& singleAgencyGatewayInfos) const +{ + // foreach all gateways to find the component + for (auto const& it : singleAgencyGatewayInfos) + { + auto const& nodeListInfo = it->nodeList(); + for (auto const& nodeInfo : nodeListInfo) + { + if (nodeInfo.second->componentExist(routeInfo->componentType())) + { + choosedGateway.insert(it); + break; + } + } + } +} + + +void PeerRouterTable::asyncBroadcastMessage(ppc::protocol::P2PMessage::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; + } + PEER_ROUTER_LOG(TRACE) << LOG_DESC("asyncBroadcastMessage") + << LOG_KV("nodeID", printP2PIDElegantly(selectedNode->p2pNodeID())) + << LOG_KV("msg", printP2PMessage(msg)); + m_service->asyncSendMessageByNodeID(selectedNode->p2pNodeID(), msg); + } +} diff --git a/cpp/wedpr-transport/ppc-gateway/ppc-gateway/gateway/router/PeerRouterTable.h b/cpp/wedpr-transport/ppc-gateway/ppc-gateway/gateway/router/PeerRouterTable.h new file mode 100644 index 00000000..5600c46f --- /dev/null +++ b/cpp/wedpr-transport/ppc-gateway/ppc-gateway/gateway/router/PeerRouterTable.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 PeerRouterTable.h + * @author: yujiechen + * @date 2024-08-27 + */ +#pragma once +#include "GatewayNodeInfo.h" +#include "ppc-framework/protocol/P2PMessage.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, GatewayNodeInfoFactory::Ptr gatewayInfoFactory) + : m_service(std::move(service)), m_gatewayInfoFactory(std::move(gatewayInfoFactory)) + {} + virtual ~PeerRouterTable() = default; + + virtual void updateGatewayInfo(GatewayNodeInfo::Ptr const& gatewayInfo); + virtual void removeP2PID(std::string const& p2pNode); + virtual GatewayNodeInfos selectRouter(ppc::protocol::RouteType const& routeType, + ppc::protocol::MessageOptionalHeader::Ptr const& routeInfo) const; + + virtual std::vector selectTargetNodes(ppc::protocol::RouteType const& routeType, + ppc::protocol::MessageOptionalHeader::Ptr const& routeInfo) const; + + virtual void asyncBroadcastMessage(ppc::protocol::P2PMessage::Ptr const& msg) const; + + std::set agencies(std::vector const& components) const; + + std::map gatewayInfos() const + { + bcos::ReadGuard l(x_mutex); + return m_agency2GatewayInfos; + } + + +private: + virtual GatewayNodeInfos selectRouterByNodeID( + ppc::protocol::MessageOptionalHeader::Ptr const& routeInfo) const; + virtual GatewayNodeInfos selectRouterByComponent( + ppc::protocol::MessageOptionalHeader::Ptr const& routeInfo) const; + void selectRouterByComponent(GatewayNodeInfos& choosedGateway, + ppc::protocol::MessageOptionalHeader::Ptr const& routeInfo, + GatewayNodeInfos const& singleAgencyGatewayInfos) const; + virtual GatewayNodeInfos selectRouterByAgency( + ppc::protocol::MessageOptionalHeader::Ptr const& routeInfo) const; + void removeP2PNodeIDFromNodeIDInfos(GatewayNodeInfo::Ptr const& gatewayInfo); + void insertGatewayInfo(GatewayNodeInfo::Ptr const& gatewayInfo); + void removeP2PNodeIDFromAgencyInfos(std::string const& p2pNode); + +private: + Service::Ptr m_service; + GatewayNodeInfoFactory::Ptr m_gatewayInfoFactory; + // 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/wedpr-transport/ppc-gateway/ppc-gateway/p2p/Service.cpp b/cpp/wedpr-transport/ppc-gateway/ppc-gateway/p2p/Service.cpp new file mode 100644 index 00000000..87eae3de --- /dev/null +++ b/cpp/wedpr-transport/ppc-gateway/ppc-gateway/p2p/Service.cpp @@ -0,0 +1,379 @@ +/** + * 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" +#include "ppc-framework/Helper.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); + + SERVICE_LOG(INFO) << LOG_DESC("create P2PService") << LOG_KV("module", _moduleName) + << LOG_KV("nodeID", printP2PIDElegantly(m_nodeID)); + WsService::registerConnectHandler( + boost::bind(&Service::onP2PConnect, this, boost::placeholders::_1)); + WsService::registerDisconnectHandler( + boost::bind(&Service::onP2PDisconnect, this, boost::placeholders::_1)); +} + +void Service::stop() +{ + SERVICE_LOG(INFO) << LOG_DESC("stop service"); + // stop the timerFactory + if (m_timerFactory) + { + m_timerFactory.reset(); + } + WsService::stop(); +} + +void Service::onP2PConnect(WsSession::Ptr _session) +{ + SERVICE_LOG(INFO) << LOG_DESC("Receive new p2p connection") + << LOG_KV("p2pid", printP2PIDElegantly(_session->nodeId())) + << LOG_KV("endpoint", _session->endPoint()); + + RecursiveGuard l(x_nodeID2Session); + auto it = m_nodeID2Session.find(_session->nodeId()); + if (it != m_nodeID2Session.end() && it->second->isConnected()) + { + SERVICE_LOG(INFO) << LOG_DESC("onP2PConnect, drop the duplicated connection") + << LOG_KV("nodeID", printP2PIDElegantly(_session->nodeId())) + << LOG_KV("endpoint", _session->endPoint()); + updateNodeIDInfo(_session); + _session->drop(WsError::UserDisconnect); + return; + } + // the node-self + if (_session->nodeId() == m_nodeID) + { + updateNodeIDInfo(_session); + SERVICE_LOG(INFO) << LOG_DESC("onP2PConnect, drop the node-self connection") + << LOG_KV("nodeID", printP2PIDElegantly(_session->nodeId())) + << LOG_KV("endpoint", _session->endPoint()); + _session->drop(WsError::UserDisconnect); + return; + } + ///// Note: here allow all new session, even the ip not configured(support dynamic access) + bool updated = updateNodeIDInfo(_session); + // hit the m_nodeID2Session + if (it != m_nodeID2Session.end()) + { + it->second = _session; + } + else + { + // the new session + m_nodeID2Session.insert(std::make_pair(_session->nodeId(), _session)); + callNewSessionHandlers(_session); + } + SERVICE_LOG(INFO) << LOG_DESC("onP2PConnect established new session") + << LOG_KV("p2pid", printP2PIDElegantly(_session->nodeId())) + << LOG_KV("endpoint", _session->endPoint()); +} + + +bool 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; + SERVICE_LOG(INFO) << LOG_DESC("updateNodeIDInfo: update the nodeID") + << LOG_KV("nodeid", printP2PIDElegantly(p2pNodeID)) + << LOG_KV("endpoint", _session->endPoint()); + return true; + } + + SERVICE_LOG(INFO) << LOG_DESC("updateNodeIDInfo can't find endpoint") + << LOG_KV("nodeid", printP2PIDElegantly(p2pNodeID)) + << LOG_KV("endpoint", _session->endPoint()); + return false; +} + +bool Service::removeSessionInfo(WsSession::Ptr const& _session) +{ + RecursiveGuard l(x_nodeID2Session); + auto it = m_nodeID2Session.find(_session->nodeId()); + if (it != m_nodeID2Session.end() && it->second->endPointInfo() == _session->endPointInfo()) + { + SERVICE_LOG(INFO) << "onP2PDisconnect: remove from m_nodeID2Session" + << LOG_KV("p2pid", printP2PIDElegantly(_session->nodeId())) + << LOG_KV("endpoint", _session->endPoint()); + + m_nodeID2Session.erase(it); + callDeleteSessionHandlers(_session); + return true; + } + return false; +} + +void Service::onP2PDisconnect(WsSession::Ptr _session) +{ + // remove the session information + if (!removeSessionInfo(_session)) + { + return; + } + // update the session nodeID to empty + UpgradableGuard l(x_configuredNode2ID); + for (auto& it : m_configuredNode2ID) + { + // the node-self, no need to reset the nodeID + if (m_nodeID == _session->nodeId()) + { + continue; + } + // not with the same nodeID, can't reset the nodeID + if (it.second != _session->nodeId()) + { + continue; + } + UpgradeGuard ul(l); + it.second.clear(); + SERVICE_LOG(INFO) << "onP2PDisconnect: clear the nodeID information" + << LOG_KV("p2pid", printP2PIDElegantly(_session->nodeId())) + << LOG_KV("endpoint", _session->endPoint()); + break; + } +} + +bool Service::nodeConnected(std::string const& nodeID) +{ + bcos::RecursiveGuard l(x_nodeID2Session); + return m_nodeID2Session.count(nodeID); +} + +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() && nodeConnected(it.second)) + { + continue; + } + unconnectedPeers->insert(it.first); + SERVICE_LOG(DEBUG) << LOG_DESC("ready to reconnect") << LOG_KV("endpoint", 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; +} + +// Note: this only called by the sender; will not been called when forward +void Service::asyncSendMessageByNodeID( + std::string const& dstNodeID, MessageFace::Ptr msg, Options options, RespCallBack respFunc) +{ + auto p2pMsg = std::dynamic_pointer_cast(msg); + p2pMsg->header()->setDstGwNode(dstNodeID); + 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()) + { + SERVICE_LOG(TRACE) << LOG_DESC("asyncSendMessage directly") << printP2PMessage(p2pMsg); + return asyncSendMessage(dstNodeID, msg, options, respFunc); + } + // with nextHop, send the message to nextHop + SERVICE_LOG(TRACE) << LOG_DESC("asyncSendMessageWithForward to nextHop") + << printP2PMessage(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; + } + if (msg->seq().empty()) + { + msg->setSeq(m_messageFactory->newSeq()); + } + 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 " + std::string(printP2PIDElegantly(dstNodeID)) + + " failed for no network established, msg: " + printWsMessage(msg)); + respFunc(std::move(error), nullptr, nullptr); + } + SERVICE_LOG(WARNING) + << LOG_DESC("asyncSendMessageByNodeID failed for no network established, msg detail:") + << printWsMessage(msg); + } + catch (std::exception const& e) + { + SERVICE_LOG(ERROR) << "asyncSendMessageByNodeID" + << LOG_KV("dstNode", printP2PIDElegantly(dstNodeID)) + << LOG_KV("what", boost::diagnostic_information(e)); + if (respFunc) + { + respFunc(std::make_shared( + -1, "send message to " + std::string(printP2PIDElegantly(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) + { + SERVICE_LOG(TRACE) << LOG_DESC("onRecvMessage, dispatch for find the dst node") + << printP2PMessage(p2pMsg); + WsService::onRecvMessage(_msg, _session); + return; + } + // forward the message + if (p2pMsg->header()->ttl() >= m_routerTable->unreachableDistance()) + { + SERVICE_LOG(WARNING) << LOG_DESC("onRecvMessage: ttl expired") << printP2PMessage(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 + { + if (msg->seq().empty()) + { + msg->setSeq(m_messageFactory->newSeq()); + } + for (auto const& node : reachableNodes) + { + auto p2pMsg = std::dynamic_pointer_cast(msg); + p2pMsg->header()->setDstGwNode(node); + asyncSendMessageByNodeID(node, msg, options); + } + } + catch (std::exception& e) + { + SERVICE_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); +} + +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()->optionalField()->setDstInst( + requestMsg->header()->optionalField()->srcInst()); + respMessage->header()->optionalField()->setSrcInst( + requestMsg->header()->optionalField()->dstInst()); + } + respMessage->header()->setSrcGwNode(requestMsg->header()->dstGwNode()); + respMessage->header()->setDstGwNode(requestMsg->header()->srcGwNode()); + 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); + SERVICE_LOG(TRACE) << "sendRespMessageBySession: " + << LOG_KV("resp", printP2PMessage(respMessage)) + << LOG_KV("sessionNode", printP2PIDElegantly(session->nodeId())) + << LOG_KV("payloadSize", + respMessage->payload() ? respMessage->payload()->size() : 0); +} \ No newline at end of file diff --git a/cpp/wedpr-transport/ppc-gateway/ppc-gateway/p2p/Service.h b/cpp/wedpr-transport/ppc-gateway/ppc-gateway/p2p/Service.h new file mode 100644 index 00000000..5f85c406 --- /dev/null +++ b/cpp/wedpr-transport/ppc-gateway/ppc-gateway/p2p/Service.h @@ -0,0 +1,158 @@ +/** + * 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/P2PMessage.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 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()); + + 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; + } + + void setNodeEndpoints(std::set const& endPointList) + { + bcos::WriteGuard l(x_configuredNode2ID); + for (auto const& it : endPointList) + { + if (m_configuredNode2ID.count(it)) + { + continue; + } + m_configuredNode2ID.insert(std::make_pair(it, "")); + } + } + + // handlers called when new-session + void registerOnNewSession(std::function _handler) + { + m_newSessionHandlers.emplace_back(_handler); + } + // handlers called when delete-session + void registerOnDeleteSession(std::function _handler) + { + m_deleteSessionHandlers.emplace_back(_handler); + } + + void stop() override; + +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); + + virtual bool nodeConnected(std::string const& nodeID); + + void reconnect() override; + + bool updateNodeIDInfo(bcos::boostssl::ws::WsSession::Ptr const& _session); + bool 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); + + virtual void callNewSessionHandlers(bcos::boostssl::ws::WsSession::Ptr _session) + { + try + { + for (auto const& handler : m_newSessionHandlers) + { + handler(_session); + } + } + catch (std::exception const& e) + { + SERVICE_LOG(WARNING) << LOG_DESC("callNewSessionHandlers exception") + << LOG_KV("error", boost::diagnostic_information(e)); + } + } + virtual void callDeleteSessionHandlers(bcos::boostssl::ws::WsSession::Ptr _session) + { + try + { + for (auto const& handler : m_deleteSessionHandlers) + { + handler(_session); + } + } + catch (std::exception const& e) + { + SERVICE_LOG(WARNING) << LOG_DESC("callDeleteSessionHandlers exception") + << LOG_KV("error", boost::diagnostic_information(e)); + } + } + +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; + + // handlers called when new-session + std::vector> m_newSessionHandlers; + // handlers called when delete-session + std::vector> m_deleteSessionHandlers; +}; +} // namespace ppc::gateway \ No newline at end of file diff --git a/cpp/wedpr-transport/ppc-gateway/ppc-gateway/p2p/router/RouterManager.cpp b/cpp/wedpr-transport/ppc-gateway/ppc-gateway/p2p/router/RouterManager.cpp new file mode 100644 index 00000000..3c5f3b94 --- /dev/null +++ b/cpp/wedpr-transport/ppc-gateway/ppc-gateway/p2p/router/RouterManager.cpp @@ -0,0 +1,264 @@ +/** + * 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/Helper.h" +#include "ppc-framework/gateway/GatewayProtocol.h" +#include "ppc-framework/protocol/P2PMessage.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; + } + SERVICE_ROUTER_LOG(INFO) << LOG_BADGE("onReceiveRouterSeq") + << LOG_DESC("receive router seq and request router table") + << LOG_KV("peer", printP2PIDElegantly(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()))); + + SERVICE_ROUTER_LOG(INFO) << LOG_BADGE("onReceivePeersRouterTable") + << LOG_KV("peer", printP2PIDElegantly(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) +{ + SERVICE_ROUTER_LOG(INFO) << LOG_BADGE("onReceiveRouterTableRequest") + << LOG_KV("peer", printP2PIDElegantly(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; + } + } + + SERVICE_ROUTER_LOG(INFO) << LOG_BADGE("joinRouterTable") << LOG_DESC("create router entry") + << LOG_KV("dst", printP2PIDElegantly(_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) + { + SERVICE_ROUTER_LOG(DEBUG) << LOG_BADGE("joinRouterTable") + << LOG_DESC("router table not updated") + << LOG_KV("dst", printP2PIDElegantly(_generatedFrom)); + return; + } + onP2PNodesUnreachable(unreachableNodes); + m_statusSeq++; + broadcastRouterSeq(); +} + + +// called when the nodes become unreachable +void RouterManager::onP2PNodesUnreachable(std::set const& _p2pNodeIDs) +{ + try + { + std::vector> handlers; + { + ReadGuard readGuard(x_unreachableHandlers); + handlers = m_unreachableHandlers; + } + auto self = weak_from_this(); + m_service->threadPool()->enqueue([self, _p2pNodeIDs]() { + try + { + auto mgr = self.lock(); + if (!mgr) + { + return; + } + for (auto const& node : _p2pNodeIDs) + { + for (auto const& it : mgr->m_unreachableHandlers) + { + it(node); + } + } + } + catch (std::exception const& e) + { + SERVICE_ROUTER_LOG(WARNING) << LOG_DESC("call unreachable handlers error for ") + << boost::diagnostic_information(e); + } + }); + } + catch (std::exception const& e) + { + SERVICE_ROUTER_LOG(WARNING) << LOG_DESC("onP2PNodesUnreachable exception") + << LOG_KV("error", boost::diagnostic_information(e)); + } +} + +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); +} + +std::set RouterManager::onEraseSession(std::string const& sessionNodeID) +{ + eraseSeq(sessionNodeID); + std::set unreachableNodes; + if (m_service->routerTable()->erase(unreachableNodes, sessionNodeID)) + { + m_statusSeq++; + broadcastRouterSeq(); + } + onP2PNodesUnreachable(unreachableNodes); + SERVICE_ROUTER_LOG(INFO) << LOG_DESC("onEraseSession") + << LOG_KV("dst", printP2PIDElegantly(sessionNodeID)); + return unreachableNodes; +} + +bool RouterManager::eraseSeq(std::string const& _p2pNodeID) +{ + UpgradableGuard l(x_node2Seq); + if (!m_node2Seq.count(_p2pNodeID)) + { + return false; + } + UpgradeGuard ul(l); + m_node2Seq.erase(_p2pNodeID); + return true; +} + +std::set RouterManager::onNewSession(std::string const& sessionNodeID) +{ + std::set unreachableNodes; + auto entry = m_service->routerTableFactory()->createRouterEntry(); + entry->setDstNode(sessionNodeID); + entry->setDistance(0); + if (!m_service->routerTable()->update(unreachableNodes, m_service->nodeID(), entry)) + { + SERVICE_ROUTER_LOG(INFO) << LOG_DESC("onNewSession: RouterTable not changed") + << LOG_KV("dst", printP2PIDElegantly(sessionNodeID)); + return unreachableNodes; + } + m_statusSeq++; + broadcastRouterSeq(); + SERVICE_ROUTER_LOG(INFO) << LOG_DESC("onNewSession: update routerTable") + << LOG_KV("dst", printP2PIDElegantly(sessionNodeID)); + onP2PNodesUnreachable(unreachableNodes); + return unreachableNodes; +} \ No newline at end of file diff --git a/cpp/wedpr-transport/ppc-gateway/ppc-gateway/p2p/router/RouterManager.h b/cpp/wedpr-transport/ppc-gateway/ppc-gateway/p2p/router/RouterManager.h new file mode 100644 index 00000000..d55841db --- /dev/null +++ b/cpp/wedpr-transport/ppc-gateway/ppc-gateway/p2p/router/RouterManager.h @@ -0,0 +1,79 @@ +/** + * 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 +#include + +namespace ppc::gateway +{ +class RouterManager : public std::enable_shared_from_this +{ +public: + using Ptr = std::shared_ptr; + 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(); + std::set onEraseSession(std::string const& sessionNodeID); + std::set onNewSession(std::string const& sessionNodeID); + +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); + bool eraseSeq(std::string const& _p2pNodeID); + + void onP2PNodesUnreachable(std::set const& _p2pNodeIDs); + +private: + // for message forward + Service::Ptr m_service; + + std::shared_ptr m_routerTimer; + + // called when the given node unreachable + std::vector> m_unreachableHandlers; + mutable bcos::SharedMutex x_unreachableHandlers; + + 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/wedpr-transport/ppc-gateway/ppc-gateway/p2p/router/RouterTableImpl.cpp b/cpp/wedpr-transport/ppc-gateway/ppc-gateway/p2p/router/RouterTableImpl.cpp new file mode 100644 index 00000000..729af315 --- /dev/null +++ b/cpp/wedpr-transport/ppc-gateway/ppc-gateway/p2p/router/RouterTableImpl.cpp @@ -0,0 +1,275 @@ +/* + * 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-framework/Helper.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()); + + SERVICE_ROUTER_LOG(INFO) << LOG_BADGE("erase") << LOG_DESC("make the router unreachable") + << LOG_KV("dst", printP2PIDElegantly(_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()); + } + SERVICE_ROUTER_LOG(INFO) + << LOG_BADGE("updateDistanceForAllRouterEntries") + << LOG_DESC("update entry since the nextHop distance has been updated") + << LOG_KV("dst", printP2PIDElegantly(entry->dstNode())) + << LOG_KV("nextHop", printP2PIDElegantly(_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]] + { + SERVICE_ROUTER_LOG(TRACE) << LOG_BADGE("update") << LOG_DESC("receive entry") + << LOG_KV("dst", printP2PIDElegantly(_entry->dstNode())) + << LOG_KV("distance", _entry->distance()) + << LOG_KV("from", printP2PIDElegantly(_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)); + SERVICE_ROUTER_LOG(INFO) << LOG_BADGE("updateDstNodeEntry") + << LOG_DESC("insert new entry into the routerTable") + << LOG_KV("distance", _entry->distance()) + << LOG_KV("dst", printP2PIDElegantly(_entry->dstNode())) + << LOG_KV("nextHop", printP2PIDElegantly(_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); + SERVICE_ROUTER_LOG(INFO) << LOG_BADGE("updateDstNodeEntry") + << LOG_DESC("discover smaller distance, update entry") + << LOG_KV("distance", currentEntry->distance()) + << LOG_KV("oldDistance", currentDistance) + << LOG_KV("dst", printP2PIDElegantly(_entry->dstNode())) + << LOG_KV("nextHop", printP2PIDElegantly(_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(); + } + SERVICE_ROUTER_LOG(INFO) << LOG_BADGE("updateDstNodeEntry") + << LOG_DESC( + "distance of the nextHop entry " + "updated, update the current entry") + << LOG_KV("dst", printP2PIDElegantly(currentEntry->dstNode())) + << LOG_KV("nextHop", printP2PIDElegantly(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) << ","; }); + SERVICE_ROUTER_LOG(TRACE) + << LOG_BADGE("getAllReachableNode") << LOG_KV("nodes size", reachableNodes.size()) + << LOG_KV("nodes", nodes.str()); + } + + return reachableNodes; +} diff --git a/cpp/wedpr-transport/ppc-gateway/ppc-gateway/p2p/router/RouterTableImpl.h b/cpp/wedpr-transport/ppc-gateway/ppc-gateway/p2p/router/RouterTableImpl.h new file mode 100644 index 00000000..55ae8d8b --- /dev/null +++ b/cpp/wedpr-transport/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 "tars/RouterTable.h" +#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/wedpr-transport/ppc-gateway/ppc-gateway/p2p/router/RouterTableInterface.h b/cpp/wedpr-transport/ppc-gateway/ppc-gateway/p2p/router/RouterTableInterface.h new file mode 100644 index 00000000..e60d3096 --- /dev/null +++ b/cpp/wedpr-transport/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/wedpr-transport/ppc-gateway/ppc-gateway/protocol/P2PMessageImpl.cpp b/cpp/wedpr-transport/ppc-gateway/ppc-gateway/protocol/P2PMessageImpl.cpp new file mode 100644 index 00000000..daa711fb --- /dev/null +++ b/cpp/wedpr-transport/ppc-gateway/ppc-gateway/protocol/P2PMessageImpl.cpp @@ -0,0 +1,43 @@ +/** + * 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-22 + */ +#include "P2PMessageImpl.h" +#include "../Common.h" + +using namespace bcos; +using namespace ppc::protocol; + + +bool P2PMessageImpl::encode(bcos::boostssl::EncodedMsg& encodedMsg) +{ + try + { + // header + m_msg->header()->encode(encodedMsg.header); + // assign the payload back + encodedMsg.payload = m_msg->payload(); + return true; + } + catch (std::exception const& e) + { + GATEWAY_LOG(WARNING) << LOG_DESC("encode message failed") + << LOG_KV("error", boost::diagnostic_information(e)); + return false; + } +} \ No newline at end of file diff --git a/cpp/wedpr-transport/ppc-gateway/ppc-gateway/protocol/P2PMessageImpl.h b/cpp/wedpr-transport/ppc-gateway/ppc-gateway/protocol/P2PMessageImpl.h new file mode 100644 index 00000000..07a29edc --- /dev/null +++ b/cpp/wedpr-transport/ppc-gateway/ppc-gateway/protocol/P2PMessageImpl.h @@ -0,0 +1,64 @@ +/** + * 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-22 + */ +#pragma once +#include "ppc-framework/protocol/P2PMessage.h" +#include "ppc-utilities/Utilities.h" + +namespace ppc::protocol +{ +class P2PMessageImpl : public P2PMessage +{ +public: + using Ptr = std::shared_ptr; + P2PMessageImpl(Message::Ptr msg) : P2PMessage(msg) {} + ~P2PMessageImpl() override = default; + // encode and return the {header, payload} + bool encode(bcos::boostssl::EncodedMsg& _encodedMsg) override; +}; + +class P2PMessageBuilderImpl : public P2PMessageBuilder +{ +public: + using Ptr = std::shared_ptr; + P2PMessageBuilderImpl(MessageBuilder::Ptr msgBuilder) : m_msgBuilder(std::move(msgBuilder)) {} + ~P2PMessageBuilderImpl() override = default; + + P2PMessage::Ptr build() override + { + return std::make_shared(m_msgBuilder->build()); + } + + P2PMessage::Ptr build(ppc::protocol::RouteType routeType, + ppc::protocol::MessageOptionalHeader::Ptr const& routeInfo, bcos::bytes&& payload) override + { + return std::make_shared( + m_msgBuilder->build(routeType, routeInfo, std::move(payload))); + } + + bcos::boostssl::MessageFace::Ptr buildMessage() override + { + return std::make_shared(m_msgBuilder->build()); + } + std::string newSeq() override { return ppc::generateUUID(); } + +protected: + MessageBuilder::Ptr m_msgBuilder; +}; +} // namespace ppc::protocol \ No newline at end of file diff --git a/cpp/wedpr-transport/ppc-gateway/test/CMakeLists.txt b/cpp/wedpr-transport/ppc-gateway/test/CMakeLists.txt new file mode 100644 index 00000000..8b5234a0 --- /dev/null +++ b/cpp/wedpr-transport/ppc-gateway/test/CMakeLists.txt @@ -0,0 +1,17 @@ +file(GLOB_RECURSE SOURCES "unittests/*.cpp" "unittests/*.h") + +# cmake settings +set(GATEWAY_TEST_BINARY_NAME test-ppc-gateway) + +if (DEMO) + add_subdirectory(demo) +endif () + +add_executable(${GATEWAY_TEST_BINARY_NAME} ${SOURCES}) +target_include_directories(${GATEWAY_TEST_BINARY_NAME} PRIVATE .) + +target_compile_options(${GATEWAY_TEST_BINARY_NAME} PRIVATE -Wno-error -Wno-unused-variable) + +target_link_libraries(${GATEWAY_TEST_BINARY_NAME} ${GATEWAY_TARGET} ${FRONT_TARGET} ${PROTOCOL_TARGET} ${BOOST_UNIT_TEST}) + +add_test(NAME test-gateway WORKING_DIRECTORY WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} COMMAND ${GATEWAY_TEST_BINARY_NAME}) \ No newline at end of file diff --git a/cpp/wedpr-transport/ppc-gateway/test/data/config0.ini b/cpp/wedpr-transport/ppc-gateway/test/data/config0.ini new file mode 100644 index 00000000..a07e8157 --- /dev/null +++ b/cpp/wedpr-transport/ppc-gateway/test/data/config0.ini @@ -0,0 +1,32 @@ +[gateway] + ; host ip + listen_ip = 0.0.0.0 + ; Websocket server listening port + listen_port = 34745 + ; for thread pools + thread_count = 16 + ; disable encrypt communication + disable_ssl = true + ; ssl or sm_ssl + ssl_type = sm_ssl + +[cache] + type = 0 + proxy = 127.0.0.1:20002 + obServer = 127.0.0.1:10904 + cluster = REDIS_CLUSTER + user = 1194 + host = 127.0.0.1 + port = 6379 + password = 123456 + database = 1 + pool_size = 16 + +[agency] + ; the agency-id of self-party + id = "1001" + ; the agency info + agency.1001 = 127.0.0.1:34745,127.0.0.1:34746 + agency.1002 = 127.0.0.1:34755,127.0.0.1:34756 + protocol = 1 + url = /api/v1/invoke \ No newline at end of file diff --git a/cpp/wedpr-transport/ppc-gateway/test/demo/CMakeLists.txt b/cpp/wedpr-transport/ppc-gateway/test/demo/CMakeLists.txt new file mode 100644 index 00000000..939d6111 --- /dev/null +++ b/cpp/wedpr-transport/ppc-gateway/test/demo/CMakeLists.txt @@ -0,0 +1,8 @@ +file(GLOB_RECURSE SOURCES "*.cpp" "*.h") + +# cmake settings +set(GATEWAY_DEMO_BINARY_NAME gateway_demo) + +add_executable(${GATEWAY_DEMO_BINARY_NAME} gateway_demo.cpp) + +target_link_libraries(${GATEWAY_DEMO_BINARY_NAME} ${GATEWAY_TARGET} ${STORAGE_TARGET} ${FRONT_TARGET} ${PROTOCOL_TARGET} ${BOOST_UNIT_TEST}) \ No newline at end of file diff --git a/cpp/wedpr-transport/ppc-gateway/test/demo/gateway_demo.cpp b/cpp/wedpr-transport/ppc-gateway/test/demo/gateway_demo.cpp new file mode 100644 index 00000000..3d702dc7 --- /dev/null +++ b/cpp/wedpr-transport/ppc-gateway/test/demo/gateway_demo.cpp @@ -0,0 +1,136 @@ +/* + * Copyright (C) 2022 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 gateway_demo.cpp + * @author: shawnhe + * @date 2022-10-28 + */ +#if 0 +#include "ppc-gateway/ppc-gateway/Gateway.h" +#include "ppc-gateway/ppc-gateway/GatewayConfigContext.h" +#include "ppc-tools/src/config/PPCConfig.h" + +using namespace ppc; +using namespace ppctars; +using namespace ppc::front; +using namespace ppc::gateway; +using namespace ppc::storage; +using namespace ppc::protocol; + +using namespace bcos; +using namespace ppc::tools; +using namespace bcos::boostssl; +using namespace bcos::boostssl::ws; + + +inline static PPCMessageFace::Ptr buildMessage(std::string _taskID, uint32_t _seq) +{ + auto messageFactory = std::make_shared(); + auto message = messageFactory->buildPPCMessage(); + message->setVersion(1); + message->setTaskType(uint8_t(protocol::TaskType::PSI)); + message->setAlgorithmType(uint8_t(protocol::TaskAlgorithmType::CM_PSI_2PC)); + message->setMessageType(4); + message->setSeq(_seq); + message->setTaskID(_taskID); + message->setSender("1001"); + message->setData(std::make_shared(10, 'a')); + return message; +} + + +int main(int argc, char* argv[]) +{ + // config + auto config = std::make_shared(); + // not specify the certPath in air-mode + config->(nullptr, "../../../../ppc-gateway/test/data/config0.ini"); + auto gatewayConfig = config->gatewayConfig(); + + // global thread pool + auto threadPoolSize = gatewayConfig.networkConfig.threadPoolSize; + auto threadPool = std::make_shared(GATEWAY_THREAD_POOL_MODULE, threadPoolSize); + + auto ioService = std::make_shared(); + + // front factory + auto frontFactory = std::make_shared("1001", threadPool); + auto front = frontFactory->buildFront(ioService); + + // message factory + auto messageFactory = std::make_shared(); + auto wsMessageFactory = std::make_shared(); + + // Note: no-need the redis as cache in air-mode + auto gatewayFactory = std::make_shared(); + auto gateway = gatewayFactory->buildGateway( + ppc::protocol::NodeArch::AIR, config, nullptr, messageFactory, threadPool); + gateway->registerFront(front->selfEndPoint(), front); + gateway->start(); + + front->setGatewayInterface(gateway); + front->start(); + + std::atomic flag = 0; + front->registerMessageHandler(uint8_t(TaskType::PSI), uint8_t(TaskAlgorithmType::CM_PSI_2PC), + [&flag](const PPCMessageFace::Ptr& _message) { + std::cout << "message received\n" + << "type: " << unsigned(_message->messageType()) << std::endl; + std::cout << "sender: " << _message->sender() << std::endl; + std::cout << "seq: " << _message->seq() << std::endl; + flag++; + }); + + auto taskID = "02345678"; + auto info = std::make_shared(); + info->taskID = taskID; + info->serviceEndpoint = "endpoint1001"; + front->notifyTaskInfo(taskID); + + auto message = buildMessage(taskID, 0); + std::cout << "send message\n" + << "type: " << unsigned(message->messageType()) << std::endl; + std::cout << "sender: " << message->sender() << std::endl; + std::cout << "seq: " << message->seq() << std::endl; + front->asyncSendMessage("1001", message, 0, nullptr, nullptr); + + auto taskID1 = "12345678"; + auto message1 = buildMessage(taskID1, 1); + std::cout << "send message1\n" + << "type: " << unsigned(message1->messageType()) << std::endl; + std::cout << "sender: " << message1->sender() << std::endl; + std::cout << "seq: " << message1->seq() << std::endl; + front->asyncSendMessage("1001", message1, 0, nullptr, nullptr); + + auto message2 = buildMessage(taskID1, 2); + std::cout << "send message2\n" + << "type: " << unsigned(message2->messageType()) << std::endl; + std::cout << "sender: " << message2->sender() << std::endl; + std::cout << "seq: " << message2->seq() << std::endl; + front->asyncSendMessage("1001", message2, 0, nullptr, nullptr); + + std::this_thread::sleep_for(std::chrono::milliseconds(2000)); + + auto info1 = std::make_shared(); + info->taskID = taskID1; + info->serviceEndpoint = "endpoint1001"; + front->notifyTaskInfo(taskID1); + + while (flag != 3) + { + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } +} +#endif diff --git a/cpp/wedpr-transport/ppc-gateway/test/unittests/GatewayNodeInfoImplTest.cpp b/cpp/wedpr-transport/ppc-gateway/test/unittests/GatewayNodeInfoImplTest.cpp new file mode 100644 index 00000000..0a2f80e4 --- /dev/null +++ b/cpp/wedpr-transport/ppc-gateway/test/unittests/GatewayNodeInfoImplTest.cpp @@ -0,0 +1,135 @@ +/* + * Copyright (C) 2022 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 GatewayNodeInfoImplTest.cpp + * @author: yujiechen + * @date 2024-09-06 + */ +#include "ppc-gateway/gateway/router/GatewayNodeInfoImpl.h" +#include "ppc-gateway/gateway/router/GatewayNodeInfo.h" +#include "protobuf/src/NodeInfoImpl.h" +#include +#include +#include + +using namespace ppc; +using namespace ppc::protocol; +using namespace ppc::gateway; +using namespace bcos::test; + +BOOST_FIXTURE_TEST_SUITE(NodeInfoTest, TestPromptFixture) + +INodeInfo::Ptr fakeNodeInfo(INodeInfoFactory::Ptr factory, std::string const& nodeID, + std::string const& endPoint, std::set const& components) +{ + auto nodeInfo = + factory->build(bcos::bytesConstRef((bcos::byte*)nodeID.data(), nodeID.size()), endPoint); + // nodeInfo->setNodeID(bcos::bytesConstRef((bcos::byte*)nodeID.data(), nodeID.size())); + // nodeInfo->setEndPoint(endPoint); + nodeInfo->setComponents(components); + return nodeInfo; +} + +void checkNodeInfo(INodeInfo::Ptr nodeInfo, INodeInfo::Ptr decodedNodeInfo) +{ + BOOST_CHECK(nodeInfo->nodeID().toBytes() == decodedNodeInfo->nodeID().toBytes()); + BOOST_CHECK(nodeInfo->endPoint() == decodedNodeInfo->endPoint()); + auto const& components = nodeInfo->components(); + for (auto const& decodedComp : decodedNodeInfo->components()) + { + BOOST_CHECK(components.count(decodedComp)); + } +} + +void testNodeInfoEncodeDecode(INodeInfoFactory::Ptr factory, INodeInfo::Ptr nodeInfo) +{ + bcos::bytes encodedData; + nodeInfo->encode(encodedData); + + auto decodedNodeInfo = factory->build(bcos::ref(encodedData)); + checkNodeInfo(nodeInfo, decodedNodeInfo); +} + +void registerNode(GatewayNodeInfoImpl::Ptr gatewayNodeInfo, int nodeSize) +{ + auto nodeInfoFactory = std::make_shared(); + std::string nodeID = "testn+NodeID"; + std::string endPoint = "testEndpoint"; + for (int i = 0; i < nodeSize; i++) + { + std::set components; + for (int j = 0; j < 100; j++) + { + components.insert("component_" + std::to_string(i) + "_" + std::to_string(j)); + } + auto populatedNodeID = nodeID + std::to_string(i); + auto nodeInfo = fakeNodeInfo(nodeInfoFactory, populatedNodeID, endPoint, components); + testNodeInfoEncodeDecode(nodeInfoFactory, nodeInfo); + gatewayNodeInfo->tryAddNodeInfo(nodeInfo); + } +} + +GatewayNodeInfo::Ptr fakeGatewayNodeInfo(GatewayNodeInfoFactory::Ptr factory, uint32_t statusSeq) +{ + auto gatewayNodeInfo = factory->build(); + gatewayNodeInfo->setStatusSeq(statusSeq); + return gatewayNodeInfo; +} + +void checkGatewayNodeInfo(GatewayNodeInfoImpl::Ptr gatewayNodeInfo, int expectedNodeSize, + int expectedStatusSeq, std::string const& expectedAgency, std::string const& expectedP2pNode) +{ + BOOST_CHECK(gatewayNodeInfo->nodeSize() == expectedNodeSize); + BOOST_CHECK(gatewayNodeInfo->statusSeq() == expectedStatusSeq); + BOOST_CHECK(gatewayNodeInfo->agency() == expectedAgency); + BOOST_CHECK(gatewayNodeInfo->p2pNodeID() == expectedP2pNode); + + // check concurrency + tbb::parallel_for(tbb::blocked_range(0U, 5), [&](auto const& range) { + bcos::bytes dataTemp; + gatewayNodeInfo->encode(dataTemp); + }); + bcos::bytes data; + gatewayNodeInfo->encode(data); + + auto decodedNodeInfo = std::make_shared(bcos::ref(data)); + BOOST_CHECK(gatewayNodeInfo->nodeSize() == decodedNodeInfo->nodeSize()); + BOOST_CHECK(gatewayNodeInfo->statusSeq() == decodedNodeInfo->statusSeq()); + BOOST_CHECK(gatewayNodeInfo->agency() == decodedNodeInfo->agency()); + BOOST_CHECK(gatewayNodeInfo->p2pNodeID() == decodedNodeInfo->p2pNodeID()); + + auto nodeList = decodedNodeInfo->nodeList(); + auto originNodeList = gatewayNodeInfo->nodeList(); + for (auto const& it : nodeList) + { + auto decodedNodeInfo = it.second; + auto originNodeInfo = originNodeList.at(it.first); + checkNodeInfo(originNodeInfo, decodedNodeInfo); + } +} + +BOOST_AUTO_TEST_CASE(testGatewayNodeInfo) +{ + std::string agency = "agency"; + std::string p2pNode = "p2p23"; + int statusSeq = 123343234234; + auto factory = std::make_shared(p2pNode, agency); + auto gatewayNodeInfo = + std::dynamic_pointer_cast(fakeGatewayNodeInfo(factory, statusSeq)); + registerNode(gatewayNodeInfo, 10); + checkGatewayNodeInfo(gatewayNodeInfo, 10, statusSeq, agency, p2pNode); +} + +BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file diff --git a/cpp/wedpr-transport/ppc-gateway/test/unittests/GatewayTest.cpp b/cpp/wedpr-transport/ppc-gateway/test/unittests/GatewayTest.cpp new file mode 100644 index 00000000..a1ae49b3 --- /dev/null +++ b/cpp/wedpr-transport/ppc-gateway/test/unittests/GatewayTest.cpp @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2022 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 GatewayTest.cpp + * @author: shawnhe + * @date 2022-10-28 + */ + +#if 0 +#include "ppc-gateway/ppc-gateway/Gateway.h" +#include "MockCache.h" +#include "ppc-gateway/ppc-gateway/" +#include "ppc-gateway/ppc-gateway/GatewayConfigContext.h" +#include "ppc-tools/src/config/PPCConfig.h" +#include +#include +#include +#include + +using namespace ppc; +using namespace ppctars; +using namespace ppc::front; +using namespace ppc::gateway; +using namespace ppc::storage; +using namespace ppc::protocol; +using namespace ppc::mock; + +using namespace bcos; +using namespace bcos::test; +using namespace ppc::tools; + + +BOOST_FIXTURE_TEST_SUITE(GatewayTest, TestPromptFixture) + + +BOOST_AUTO_TEST_CASE(test_readConfig) +{ + auto ppcConfig = std::make_shared(); + std::string configPath = "../../../ppc-gateway/test/data/config0.ini"; + ppcConfig->loadGatewayConfig(configPath); + auto config = std::make_shared(ppcConfig); + auto const& gatewayConfig = ppcConfig->gatewayConfig(); + BOOST_CHECK(gatewayConfig.networkConfig.disableSsl == true); + BOOST_CHECK(config->contextConfig() == nullptr); + BOOST_CHECK(gatewayConfig.networkConfig.listenIp == "0.0.0.0"); + BOOST_CHECK(gatewayConfig.networkConfig.listenPort == 34745); + BOOST_CHECK(gatewayConfig.networkConfig.threadPoolSize == 16); + BOOST_CHECK(gatewayConfig.cacheStorageConfig.host == "127.0.0.1"); + BOOST_CHECK(gatewayConfig.cacheStorageConfig.port == 6379); + BOOST_CHECK(gatewayConfig.cacheStorageConfig.password == "123456"); + BOOST_CHECK(gatewayConfig.cacheStorageConfig.pool == 16); + BOOST_CHECK(gatewayConfig.cacheStorageConfig.database == 1); + BOOST_CHECK(gatewayConfig.agencies.at("1001").size() == 2); + BOOST_CHECK(gatewayConfig.agencies.at("1002").size() == 2); +} + +BOOST_AUTO_TEST_CASE(test_taskManager) +{ + auto cache = std::make_shared(); + auto taskManager = std::make_shared(std::make_shared()); + taskManager->registerTaskInfo("1001", "endpoint1001"); + BOOST_CHECK(taskManager->getServiceEndpoint("1001") == "endpoint1001"); + + taskManager->registerTaskInfo("1002", "endpoint1002"); + BOOST_CHECK(taskManager->getServiceEndpoint("1002") == "endpoint1002"); + + BOOST_CHECK(taskManager->getServiceEndpoint("1003").empty()); +} + +BOOST_AUTO_TEST_CASE(test_frontNodeManager) +{ + auto threadPool = std::make_shared("TEST_POOL_MODULE", 4); + auto frontFactory = std::make_shared("1001", threadPool); + + auto frontNodeManager = std::make_shared(); + + auto ioService = std::make_shared(); + frontNodeManager->registerFront("1001", frontFactory->buildFront(ioService)); + auto node1 = frontNodeManager->getFront("1001"); + auto node2 = frontNodeManager->getFront("1001"); + BOOST_CHECK(node1 && node2); +} + +BOOST_AUTO_TEST_SUITE_END() +#endif diff --git a/cpp/wedpr-transport/ppc-gateway/test/unittests/MockCache.h b/cpp/wedpr-transport/ppc-gateway/test/unittests/MockCache.h new file mode 100644 index 00000000..73c7e0f0 --- /dev/null +++ b/cpp/wedpr-transport/ppc-gateway/test/unittests/MockCache.h @@ -0,0 +1,85 @@ +/** + * Copyright (C) 2022 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 MockCache.h + * @author: shawnhe + * @date 2022-10-31 + */ +#pragma once +#include "ppc-framework/storage/CacheStorage.h" +#include + +namespace ppc::mock +{ +class MockCache : public storage::CacheStorage +{ +public: + using Ptr = std::shared_ptr; + MockCache() = default; + ~MockCache() override {} + + /// Note: all these interfaces throws exception when error happened + /** + * @brief: check whether the key exists + * @param _key: key + * @return whether the key exists + */ + bool exists(const std::string& _key) override { return m_kv.find(_key) != m_kv.end(); } + + /** + * @brief: set key value + * @param _expirationTime: timeout of key, seconds + */ + void setValue(const std::string& _key, const std::string& _value, + int32_t _expirationSeconds = -1) override + { + m_kv.emplace(_key, _value); + } + + /** + * @brief: get value by key + * @param _key: key + * @return value + */ + std::optional getValue(const std::string& _key) override + { + auto it = m_kv.find(_key); + if (it == m_kv.end()) + { + return std::nullopt; + } + + return it->second; + } + + /** + * @brief: set a timeout on key + * @param _expirationTime: timeout of key, ms + * @return whether setting is successful + */ + bool expireKey(const std::string& _key, uint32_t _expirationTime) override { return true; } + + /** + * @brief: delete key + * @param _key: key + * @return the number of key deleted + */ + uint64_t deleteKey(const std::string& _key) override { return m_kv.erase(_key); } + +private: + std::unordered_map> m_kv; +}; + +} // namespace ppc::mock \ No newline at end of file diff --git a/cpp/wedpr-transport/ppc-gateway/test/unittests/main.cpp b/cpp/wedpr-transport/ppc-gateway/test/unittests/main.cpp new file mode 100644 index 00000000..2c06f9b5 --- /dev/null +++ b/cpp/wedpr-transport/ppc-gateway/test/unittests/main.cpp @@ -0,0 +1,2 @@ +#define BOOST_TEST_MAIN +#include \ No newline at end of file diff --git a/cpp/wedpr-transport/ppc-http/CMakeLists.txt b/cpp/wedpr-transport/ppc-http/CMakeLists.txt new file mode 100644 index 00000000..5e482dc1 --- /dev/null +++ b/cpp/wedpr-transport/ppc-http/CMakeLists.txt @@ -0,0 +1,5 @@ +add_subdirectory(src) + +if (DEMO) + add_subdirectory(demo) +endif() \ No newline at end of file diff --git a/cpp/wedpr-transport/ppc-http/demo/CMakeLists.txt b/cpp/wedpr-transport/ppc-http/demo/CMakeLists.txt new file mode 100644 index 00000000..56b3c4bd --- /dev/null +++ b/cpp/wedpr-transport/ppc-http/demo/CMakeLists.txt @@ -0,0 +1,16 @@ +file(GLOB_RECURSE SOURCES "*.cpp" "*.h") + +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) +# cmake settings +set(BINARY_NAME http-demo) +set(BINARY_CLIENT_NAME http-client-demo) + +add_executable(${BINARY_NAME} http_demo.cpp) +target_include_directories(${BINARY_NAME} PRIVATE .) +target_link_libraries(${BINARY_NAME} ${HTTP_TARGET} ${HELPER_TARGET} ${PROTOCOL_TARGET}) + +add_executable(${BINARY_CLIENT_NAME} http_client_demo.cpp) +target_include_directories(${BINARY_CLIENT_NAME} PRIVATE .) +target_link_libraries(${BINARY_CLIENT_NAME} ${HTTP_TARGET} ${HELPER_TARGET} ${PROTOCOL_TARGET} ${TOOLS-TARGET}) + +unset(CMAKE_RUNTIME_OUTPUT_DIRECTORY) \ No newline at end of file diff --git a/cpp/wedpr-transport/ppc-http/demo/config.ini b/cpp/wedpr-transport/ppc-http/demo/config.ini new file mode 100644 index 00000000..5d9a0ffb --- /dev/null +++ b/cpp/wedpr-transport/ppc-http/demo/config.ini @@ -0,0 +1,18 @@ +[agency] + id = agency0 + +[gateway] + listen_ip=0.0.0.0 + listen_port=8813 + ;thread_count = 4 + ; ssl or sm ssl + sm_ssl=true + ; the max allowed message size in MBytes, default is 100MBytes + max_allow_msg_size = 100 + ;ssl connection switch, if disable the ssl connection, default: false + disable_ssl = true + ;the time of the gateway holding and waiting to dispatcher the unsynced task, in minutes + holding_msg_minutes = 10 + ;the protocol of gateway : websocket(0)/http(1) + protocol = 1 + url = /api/v1/interconn/invoke \ No newline at end of file diff --git a/cpp/wedpr-transport/ppc-http/demo/http_client_demo.cpp b/cpp/wedpr-transport/ppc-http/demo/http_client_demo.cpp new file mode 100644 index 00000000..106cb10a --- /dev/null +++ b/cpp/wedpr-transport/ppc-http/demo/http_client_demo.cpp @@ -0,0 +1,140 @@ +#include "../src/HttpClient.h" +#include "ppc-tools/src/common/TransTools.h" +#include +#include +#include +#include +#include +#include +#include + +using tcp = boost::asio::ip::tcp; +namespace http = boost::beast::http; +namespace beast = boost::beast; +namespace net = boost::asio; +using namespace ppc::http; +using namespace ppc::tools; + +#define PORT 1234 +#define PATH "/test" + +// Function to handle incoming HTTP requests +void handle_request(http::request& req, http::response& res) +{ + if (req.method() == http::verb::post && req.target() == PATH) + { + res.result(http::status::ok); + res.set(http::field::content_type, "text/plain"); + + // Access the binary data received in the request body + std::string& bodyData = req.body(); + + std::cout << "Server receives body: " << bodyData.data() << std::endl; + + // Save the binary data to a local file + std::ofstream outfile("http_out", std::ios::binary); + if (outfile.is_open()) + { + outfile.write(reinterpret_cast(bodyData.data()), bodyData.size()); + outfile.close(); + res.body() = "Binary data received and saved successfully."; + } + else + { + res.result(http::status::internal_server_error); + res.body() = "Failed to save binary data."; + } + } + else + { + res.result(http::status::not_found); + res.set(http::field::content_type, "text/plain"); + res.body() = "Not Found"; + } +} + +void newServer() +{ + try + { + // Create a Boost ASIO io_context + net::io_context ioc; + + // Create a TCP acceptor to listen on port + tcp::acceptor acceptor(ioc, {tcp::v4(), PORT}); + + while (true) + { + // Wait for an incoming connection + tcp::socket socket(ioc); + acceptor.accept(socket); + + // Read the request + beast::flat_buffer buffer; + http::request request; + http::read(socket, buffer, request); + + // Prepare the response + http::response response; + handle_request(request, response); + + // Send the response + http::write(socket, response); + socket.shutdown(tcp::socket::shutdown_send); + } + } + catch (const std::exception& e) + { + std::cerr << "Server Error: " << e.what() << std::endl; + } +} + +void testClient() +{ + try + { + net::io_context io_context; + std::thread io_thread([&io_context]() { io_context.run(); }); + + HttpClient client(io_context, "127.0.0.1", PORT); + + std::map headers = {{"Content-Type", "application/octet-stream"}}; + + bcos::bytes body = {'a', 'b', 'c', 'd'}; + auto response = client.post(PATH, headers, body); + std::cout << "Client receives body: " << std::string(response.begin(), response.end()) + << std::endl; + + body = {'1', '2', '3', '4'}; + response.clear(); + response = client.post(PATH, headers, body); + std::cout << "Client receives body: " << std::string(response.begin(), response.end()) + << std::endl; + + uint32_t a = 37; + auto body1 = std::make_shared(); + encodeUnsignedNum(body1, a); + response.clear(); + response = client.post(PATH, headers, *body1); + std::cout << "Client receives body: " << std::string(response.begin(), response.end()) + << std::endl; + + io_thread.join(); + } + catch (const std::exception& e) + { + std::cerr << "Client Error: " << e.what() << std::endl; + } +} + +int main(int argc, char const* argv[]) +{ + std::thread myThread(newServer); + std::cout << "Server started!" << std::endl; + + testClient(); + + // Wait for the new thread to finish (optional) + myThread.join(); + return 0; +} diff --git a/cpp/wedpr-transport/ppc-http/demo/http_demo.cpp b/cpp/wedpr-transport/ppc-http/demo/http_demo.cpp new file mode 100644 index 00000000..072c0e7e --- /dev/null +++ b/cpp/wedpr-transport/ppc-http/demo/http_demo.cpp @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2022 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 http_demo.cpp + * @author: zachma + * @date 2023-8-23 + */ + +#include "libhelper/CommandHelper.h" +#include "libhelper/ExitHandler.h" +#include "ppc-framework/protocol/Protocol.h" +#include "ppc-http/src/HttpFactory.h" +#include + +using namespace bcos; +using namespace ppc; +using namespace ppc::http; +using namespace ppc::tools; + +void registerUrlHandler(const std::string& _url, HttpInterface::Ptr _http) +{ + _http->registerUrlHandler( + _url, [](bcos::boostssl::http::HttpRequest const& _httpReq, RespUrlFunc _handler) { + auto reqs = _httpReq.body(); + std::cout << " [Url] ===>>>> " << LOG_KV("url_request", reqs) << std::endl; + _handler(nullptr, std::move(bcos::bytes(reqs.begin(), reqs.end()))); + }); +} + +int main(int argc, char const* argv[]) +{ + ExitHandler exitHandler; + signal(SIGTERM, &ExitHandler::exitHandler); + signal(SIGABRT, &ExitHandler::exitHandler); + signal(SIGINT, &ExitHandler::exitHandler); + + try + { + auto param = initCommandLine("http_demo", argc, argv); + auto ppcConfig = std::make_shared(); + // not specify the certPath in air-mode + ppcConfig->loadGatewayConfig(param.configFilePath); + auto httpFactory = std::make_shared("selfParty"); + auto url = ppcConfig->gatewayConfig().networkConfig.url; + auto http = httpFactory->buildHttp(ppcConfig); + registerUrlHandler(url, http); + // start the http + http->start(); + while (!exitHandler.shouldExit()) + { + std::this_thread::sleep_for(std::chrono::milliseconds(200)); + } + std::cout << "[" << bcos::getCurrentDateTime() << "] "; + std::cout << "http-demo program exit normally." << std::endl; + } + catch (std::exception const& e) + { + ppc::printVersion("http-demo"); + std::cout << "[" << bcos::getCurrentDateTime() << "] "; + std::cout << "start http-demo failed, error:" << boost::diagnostic_information(e) + << std::endl; + return -1; + } + return 0; +} diff --git a/cpp/wedpr-transport/ppc-http/src/CMakeLists.txt b/cpp/wedpr-transport/ppc-http/src/CMakeLists.txt new file mode 100644 index 00000000..672dccd9 --- /dev/null +++ b/cpp/wedpr-transport/ppc-http/src/CMakeLists.txt @@ -0,0 +1,4 @@ +file(GLOB_RECURSE SRCS *.cpp) +add_library(${HTTP_TARGET} ${SRCS}) + +target_link_libraries(${HTTP_TARGET} PUBLIC ${TOOLS_TARGET} ${PROTOCOL_TARGET} ${BCOS_BOOSTSSL_TARGET}) \ No newline at end of file diff --git a/cpp/wedpr-transport/ppc-http/src/Http.cpp b/cpp/wedpr-transport/ppc-http/src/Http.cpp new file mode 100644 index 00000000..5f871d29 --- /dev/null +++ b/cpp/wedpr-transport/ppc-http/src/Http.cpp @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2022 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 Http.cpp + * @author: zachma + * @date 2023-8-23 + */ + +#include "Http.h" +#include "ppc-framework/http/HttpTypeDef.h" +#include "ppc-framework/protocol/Protocol.h" +#include "ppc-tools/src/config/ParamChecker.h" +#include + +using namespace bcos; +using namespace ppc::http; +using namespace ppc::tools; +using namespace ppc::protocol; + +Http::Http(std::shared_ptr _wsService, std::string const& _selfPartyID, + std::string const& _token) + : m_wsService(std::move(_wsService)), m_token(_token) +{ + // register handler for http + auto httpServer = m_wsService->httpServer(); + if (httpServer) + { + httpServer->setHttpReqHandler([this](bcos::boostssl::http::HttpRequest&& _request, + std::function _responseHandler) { + this->onHttpRequest(std::move(_request), _responseHandler); + }); + } + HTTP_LOG(INFO) << LOG_DESC("init http success") << LOG_KV("selfParty", _selfPartyID); +} + +void Http::onHttpRequest( + bcos::boostssl::http::HttpRequest&& _request, std::function _responseHandler) +{ + std::string uri; + std::map params; + std::string url = std::string(_request.target().data(), _request.target().size()); + parseURL(url, uri, params); + auto it = m_urlToHandler.find(uri); + if (it == m_urlToHandler.end()) + { + HTTP_LOG(DEBUG) << LOG_DESC("onHttpRequest: uri not found") << LOG_KV("uri", uri); + BOOST_THROW_EXCEPTION(BCOS_ERROR( + (int64_t)HttpError::UriNotFound, "The uri does not exist/is not available.")); + } + auto const& methodHandler = it->second; + HTTP_LOG(DEBUG) << LOG_DESC("onHttpRequest: handle uri") << LOG_KV("uri", uri); + methodHandler(std::move(_request), [_responseHandler](Error::Ptr _error, + bcos::bytes&& _result) { _responseHandler(_result); }); +} \ No newline at end of file diff --git a/cpp/wedpr-transport/ppc-http/src/Http.h b/cpp/wedpr-transport/ppc-http/src/Http.h new file mode 100644 index 00000000..750f1973 --- /dev/null +++ b/cpp/wedpr-transport/ppc-http/src/Http.h @@ -0,0 +1,132 @@ +/* + * Copyright (C) 2022 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 Http.h + * @author: zachma + * @date 2023-8-23 + */ +#pragma once +#include "ppc-framework/front/FrontInterface.h" +#include "ppc-framework/http/HttpInterface.h" +#include +#include +#include +#include +#include + +namespace ppc::http +{ +class Http : public HttpInterface +{ +public: + using Ptr = std::shared_ptr; + Http(std::shared_ptr _wsService, std::string const& _selfPartyID, + std::string const& _token); + ~Http() override { stop(); } + + void start() override + { + if (m_wsService) + { + m_wsService->start(); + } + HTTP_LOG(INFO) << LOG_DESC("start HTTP"); + } + + void stop() override + { + if (m_wsService) + { + m_wsService->stop(); + } + HTTP_LOG(INFO) << LOG_DESC("stop HTTP"); + } + + void registerUrlHandler(std::string const& _urlName, + std::function _handler) + override + { + bcos::UpgradableGuard l(x_urlToHandler); + if (m_urlToHandler.count(_urlName)) + { + HTTP_LOG(INFO) << LOG_DESC("registerUrlHandler return for url handler already exists") + << LOG_KV("url", _urlName); + return; + } + bcos::UpgradeGuard ul(l); + m_urlToHandler[_urlName] = _handler; + HTTP_LOG(INFO) << LOG_DESC("registerUrlHandler success") << LOG_KV("url", _urlName); + } + +protected: + virtual void onHttpRequest(bcos::boostssl::http::HttpRequest&& _request, + std::function _responseHandler); + + void parseURL( + const std::string& _url, std::string& uri, std::map& params_map) + { + std::string params; + std::string url; + auto paramsStart = _url.find("?"); + if (paramsStart != std::string::npos) + { + params = _url.substr(paramsStart + 1); + uri = _url.substr(0, paramsStart - 1); + } + else + { + uri = _url; + } + + auto pos = 0U; + while (pos < params.size()) + { + auto eqPos = params.find("=", pos); + auto ampPos = params.find("&", pos); + + std::string paramName = params.substr(pos, eqPos - pos); + std::string paramValue; + if (ampPos != std::string::npos) + { + paramValue = params.substr(eqPos + 1, ampPos - eqPos - 1); + } + else + { + paramValue = params.substr(eqPos + 1); + } + + params_map[paramName] = paramValue; + if (ampPos == std::string::npos) + { + break; + } + + pos = ampPos + 1; + } + } + +private: + std::shared_ptr m_wsService; + + // the url_name to function + std::map> + m_urlToHandler; + + bcos::SharedMutex x_urlToHandler; + + std::string m_token; +}; +} // namespace ppc::http diff --git a/cpp/wedpr-transport/ppc-http/src/HttpClient.cpp b/cpp/wedpr-transport/ppc-http/src/HttpClient.cpp new file mode 100644 index 00000000..bdd52b99 --- /dev/null +++ b/cpp/wedpr-transport/ppc-http/src/HttpClient.cpp @@ -0,0 +1,122 @@ +/** + * Copyright (C) 2022 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 HttpClient.cpp + * @author: shawnhe + * @date 2023-07-25 + */ + +#include "HttpClient.h" + +using tcp = boost::asio::ip::tcp; +namespace http = boost::beast::http; +namespace ssl = boost::asio::ssl; +using namespace boost::system; + +bcos::bytes ppc::http::HttpClient::post(const std::string& path, + const std::map& headers, const bcos::bytes& body) +{ + return query(boost::beast::http::verb::post, path, headers, body); +} + +bcos::bytes ppc::http::HttpClient::get(const std::string& path, + const std::map& headers, const bcos::bytes& body) +{ + return query(boost::beast::http::verb::get, path, headers, body); +} + +bcos::bytes ppc::http::HttpClient::query(boost::beast::http::verb method, const std::string& path, + const std::map& headers, const bcos::bytes& body) +{ + boost::system::error_code ec; + // Declare a container to hold the response + boost::beast::http::response response; + + // This buffer is used for reading and must be persisted + boost::beast::flat_buffer buffer; + + // Make the connection on the IP address we get from a lookup + if (m_enableSsl) + { + boost::asio::ssl::stream socket_stream(m_ioContext, m_sslContext); + boost::asio::connect(socket_stream.next_layer(), m_endpoints); + socket_stream.handshake(ssl::stream_base::client); + + // Set up an HTTP GET request message + boost::beast::http::request request{ + boost::beast::http::verb::post, path, m_version}; + request.set(boost::beast::http::field::host, m_serverHost); + request.set(boost::beast::http::field::user_agent, BOOST_BEAST_VERSION_STRING); + request.set(boost::beast::http::field::content_length, std::to_string(body.size())); + + for (const auto& header : headers) + { + request.set(header.first, header.second); + } + + request.body() = std::string(reinterpret_cast(body.data()), body.size()); + + // Send the HTTP request to the remote host + boost::beast::http::write(socket_stream, request); + + + // Receive the HTTP response + boost::beast::http::read(socket_stream, buffer, response); + + // Gracefully close the socket + socket_stream.shutdown(ec); + } + else + { + boost::asio::ip::tcp::socket newSocket(m_ioContext); + boost::asio::connect(newSocket, m_endpoints.begin(), m_endpoints.end()); + + // Set up an HTTP GET request message + boost::beast::http::request request{ + boost::beast::http::verb::post, path, m_version}; + request.set(boost::beast::http::field::host, m_serverHost); + request.set(boost::beast::http::field::user_agent, BOOST_BEAST_VERSION_STRING); + request.set(boost::beast::http::field::content_length, std::to_string(body.size())); + + for (const auto& header : headers) + { + request.set(header.first, header.second); + } + + request.body() = std::string(reinterpret_cast(body.data()), body.size()); + + // Send the HTTP request to the remote host + boost::beast::http::write(newSocket, request); + + // Receive the HTTP response + boost::beast::http::read(newSocket, buffer, response); + + // Gracefully close the socket + newSocket.shutdown(tcp::socket::shutdown_both, ec); + } + + // not_connected happens sometimes + // so don't bother reporting it. + if (ec && ec != boost::system::errc::not_connected) + throw boost::system::system_error{ec}; + + // Copy the response body to a vector + std::vector response_data; + response_data.reserve(boost::asio::buffer_size(response.body().data())); + response_data.assign(boost::asio::buffers_begin(response.body().data()), + boost::asio::buffers_end(response.body().data())); + + return response_data; +} diff --git a/cpp/wedpr-transport/ppc-http/src/HttpClient.h b/cpp/wedpr-transport/ppc-http/src/HttpClient.h new file mode 100644 index 00000000..ee435bc2 --- /dev/null +++ b/cpp/wedpr-transport/ppc-http/src/HttpClient.h @@ -0,0 +1,81 @@ +/** + * Copyright (C) 2022 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 HttpClient.h + * @author: shawnhe + * @date 2023-07-25 + */ + +#pragma once +#include "bcos-utilities/Common.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace ppc::http +{ +class HttpClient +{ +public: + using Ptr = std::shared_ptr; + HttpClient(boost::asio::io_context& ioContext, const std::string& hostOrIp, unsigned short port, + bool enableSsl = false, unsigned short version = 11) + : m_ioContext(ioContext), + m_resolver(ioContext), + m_serverHost(hostOrIp), + m_port(port), + m_enableSsl(enableSsl), + m_version(version) + { + if (enableSsl) + { + m_sslContext.set_verify_mode(boost::asio::ssl::verify_peer); + } + m_endpoints = m_resolver.resolve(m_serverHost, std::to_string(m_port)); + } + + bcos::bytes post(const std::string& path, const std::map& headers, + const bcos::bytes& body); + + bcos::bytes get(const std::string& path, const std::map& headers, + const bcos::bytes& body); + +private: + bcos::bytes query(boost::beast::http::verb method, const std::string& path, + const std::map& headers, const bcos::bytes& body); + +private: + boost::asio::io_context& m_ioContext; + boost::asio::ip::tcp::resolver m_resolver; + boost::asio::ssl::context m_sslContext = + boost::asio::ssl::context(boost::asio::ssl::context::sslv23_client); + + std::string m_serverHost; + unsigned short m_port; + bool m_enableSsl; + unsigned short m_version; + + boost::asio::ip::tcp::resolver::results_type m_endpoints; +}; +} // namespace ppc::http diff --git a/cpp/wedpr-transport/ppc-http/src/HttpFactory.cpp b/cpp/wedpr-transport/ppc-http/src/HttpFactory.cpp new file mode 100644 index 00000000..0826944d --- /dev/null +++ b/cpp/wedpr-transport/ppc-http/src/HttpFactory.cpp @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2022 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 HttpFactory.cpp + * @author: zachma + * @date 2023-8-23 + */ + +#include "HttpFactory.h" +#include "ppc-tools/src/config/PPCConfig.h" +#include +#include + +using namespace bcos; +using namespace ppc::http; +using namespace ppc::tools; + +Http::Ptr HttpFactory::buildHttp(ppc::tools::PPCConfig::ConstPtr _config) +{ + auto wsConfig = initConfig(_config); + // create the wsConfig + auto wsService = std::make_shared(); + wsService->setTimerFactory(std::make_shared()); + auto initializer = std::make_shared(); + + initializer->setConfig(wsConfig); + initializer->initWsService(wsService); + + return std::make_shared( + wsService, m_selfPartyID, _config->gatewayConfig().networkConfig.token); +} + + +std::shared_ptr HttpFactory::initConfig( + ppc::tools::PPCConfig::ConstPtr _config) +{ + // init the wsConfig + auto wsConfig = std::make_shared(); + wsConfig->setModel(boostssl::ws::WsModel::Server); + + wsConfig->setListenIP(_config->gatewayConfig().networkConfig.listenIp); + wsConfig->setListenPort(_config->gatewayConfig().networkConfig.listenPort); + wsConfig->setThreadPoolSize(_config->gatewayConfig().networkConfig.threadPoolSize); + wsConfig->setDisableSsl(_config->gatewayConfig().networkConfig.disableSsl); + if (_config->gatewayConfig().networkConfig.disableSsl) + { + return wsConfig; + } + // non-sm-ssl + auto contextConfig = std::make_shared(); + if (!_config->gatewayConfig().networkConfig.enableSM) + { + boostssl::context::ContextConfig::CertConfig certConfig; + certConfig.caCert = _config->gatewayConfig().networkConfig.caCertPath; + certConfig.nodeCert = _config->gatewayConfig().networkConfig.sslCertPath; + certConfig.nodeKey = _config->gatewayConfig().networkConfig.sslKeyPath; + contextConfig->setCertConfig(certConfig); + contextConfig->setSslType("ssl"); + HTTP_LOG(INFO) << LOG_DESC("initConfig: http work in non-sm-ssl model") + << LOG_KV("caCert", certConfig.caCert) + << LOG_KV("nodeCert", certConfig.nodeCert) + << LOG_KV("nodeKey", certConfig.nodeKey); + wsConfig->setContextConfig(contextConfig); + return wsConfig; + } + // sm-ssl + boostssl::context::ContextConfig::SMCertConfig certConfig; + certConfig.caCert = _config->gatewayConfig().networkConfig.smCaCertPath; + certConfig.nodeCert = _config->gatewayConfig().networkConfig.smSslCertPath; + certConfig.nodeKey = _config->gatewayConfig().networkConfig.smSslKeyPath; + certConfig.enNodeCert = _config->gatewayConfig().networkConfig.smEnSslCertPath; + certConfig.enNodeKey = _config->gatewayConfig().networkConfig.smEnSslKeyPath; + contextConfig->setSmCertConfig(certConfig); + contextConfig->setSslType("sm_ssl"); + + BCOS_LOG(INFO) << LOG_DESC("initConfig") << LOG_DESC("http work in sm ssl model") + << LOG_KV("caCert", certConfig.caCert) << LOG_KV("nodeCert", certConfig.nodeCert) + << LOG_KV("enNodeCert", certConfig.enNodeCert); + + wsConfig->setContextConfig(contextConfig); + return wsConfig; +} diff --git a/cpp/wedpr-transport/ppc-http/src/HttpFactory.h b/cpp/wedpr-transport/ppc-http/src/HttpFactory.h new file mode 100644 index 00000000..f7aa0856 --- /dev/null +++ b/cpp/wedpr-transport/ppc-http/src/HttpFactory.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2022 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 HttpFactory.h + * @author: zachma + * @date 2023-8-23 + */ +#pragma once +#include "Http.h" +#include + +namespace bcos::boostssl::ws +{ +class WsConfig; +} +namespace ppc::tools +{ +class PPCConfig; +} +namespace ppc::http +{ +class HttpFactory +{ +public: + using Ptr = std::shared_ptr; + HttpFactory(std::string const& _selfPartyID) : m_selfPartyID(_selfPartyID) {} + virtual ~HttpFactory() = default; + + Http::Ptr buildHttp(std::shared_ptr _config); + +private: + std::shared_ptr initConfig( + std::shared_ptr _config); + +private: + std::string m_selfPartyID; +}; +} // namespace ppc::http \ No newline at end of file diff --git a/cpp/wedpr-transport/ppc-rpc/CMakeLists.txt b/cpp/wedpr-transport/ppc-rpc/CMakeLists.txt new file mode 100644 index 00000000..6fa01414 --- /dev/null +++ b/cpp/wedpr-transport/ppc-rpc/CMakeLists.txt @@ -0,0 +1,11 @@ +add_subdirectory(src) + +if (TESTS) + enable_testing() + set(CTEST_OUTPUT_ON_FAILURE TRUE) + add_subdirectory(tests) +endif() + +if (DEMO) + add_subdirectory(demo) +endif() \ No newline at end of file diff --git a/cpp/wedpr-transport/ppc-rpc/demo/CMakeLists.txt b/cpp/wedpr-transport/ppc-rpc/demo/CMakeLists.txt new file mode 100644 index 00000000..b3b0bfa1 --- /dev/null +++ b/cpp/wedpr-transport/ppc-rpc/demo/CMakeLists.txt @@ -0,0 +1,11 @@ +file(GLOB_RECURSE SOURCES "*.cpp" "*.h") + +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) +# cmake settings +set(BINARY_NAME rpc-demo) + +add_executable(${BINARY_NAME} ${SOURCES}) +target_include_directories(${BINARY_NAME} PRIVATE .) +target_link_libraries(${BINARY_NAME} ${RPC_TARGET} ${HELPER_TARGET} ${PROTOCOL_TARGET} TBB::tbb) + +unset(CMAKE_RUNTIME_OUTPUT_DIRECTORY) \ No newline at end of file diff --git a/cpp/wedpr-transport/ppc-rpc/demo/config.ini b/cpp/wedpr-transport/ppc-rpc/demo/config.ini new file mode 100644 index 00000000..2357f4e0 --- /dev/null +++ b/cpp/wedpr-transport/ppc-rpc/demo/config.ini @@ -0,0 +1,14 @@ +[agency] + id = agency0 + +[rpc] + listen_ip=0.0.0.0 + listen_port=8550 + thread_count=4 + ; ssl or sm ssl + sm_ssl=false + cert_path=conf + ; ssl connection switch, if disable the ssl connection, default: false + disable_ssl=true + ; GB, reject task if available memory is less than min_needed_memory + ; min_needed_memory = 5 diff --git a/cpp/wedpr-transport/ppc-rpc/demo/rpc_demo.cpp b/cpp/wedpr-transport/ppc-rpc/demo/rpc_demo.cpp new file mode 100644 index 00000000..9fdaf747 --- /dev/null +++ b/cpp/wedpr-transport/ppc-rpc/demo/rpc_demo.cpp @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2022 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 rpc_demo.cpp + * @author: yujiechen + * @date 2022-11-4 + */ +#include "libhelper/CommandHelper.h" +#include "libhelper/ExitHandler.h" +#include "ppc-rpc/src/RpcFactory.h" +#include + +using namespace bcos; +using namespace ppc; +using namespace ppc::rpc; +using namespace ppc::tools; + +void registerEchoHandler(RpcInterface::Ptr _rpc) +{ + _rpc->registerHandler("echo", [](Json::Value const& _request, RespFunc _func) { + Json::Value response; + response["request"] = _request; + response["tag"] = "echo"; + _func(nullptr, std::move(response)); + }); +} + +int main(int argc, const char* argv[]) +{ + ExitHandler exitHandler; + signal(SIGTERM, &ExitHandler::exitHandler); + signal(SIGABRT, &ExitHandler::exitHandler); + signal(SIGINT, &ExitHandler::exitHandler); + try + { + auto param = initCommandLine("rpc_demo", argc, argv); + auto ppcConfig = std::make_shared(); + // not specify the certPath in air-mode + ppcConfig->loadRpcConfig(param.configFilePath); + auto rpcFactory = std::make_shared("selfParty"); + auto rpc = rpcFactory->buildRpc(ppcConfig, nullptr); + registerEchoHandler(rpc); + // start the rpc + rpc->start(); + while (!exitHandler.shouldExit()) + { + std::this_thread::sleep_for(std::chrono::milliseconds(200)); + } + std::cout << "[" << bcos::getCurrentDateTime() << "] "; + std::cout << "rpc-demo program exit normally." << std::endl; + } + catch (std::exception const& e) + { + ppc::printVersion("rpc_demo"); + std::cout << "[" << bcos::getCurrentDateTime() << "] "; + std::cout << "start rpc-demo failed, error:" << boost::diagnostic_information(e) + << std::endl; + return -1; + } +} \ No newline at end of file diff --git a/cpp/wedpr-transport/ppc-rpc/src/CMakeLists.txt b/cpp/wedpr-transport/ppc-rpc/src/CMakeLists.txt new file mode 100644 index 00000000..ecec04a6 --- /dev/null +++ b/cpp/wedpr-transport/ppc-rpc/src/CMakeLists.txt @@ -0,0 +1,4 @@ +file(GLOB_RECURSE SRCS *.cpp) +add_library(${RPC_TARGET} ${SRCS}) + +target_link_libraries(${RPC_TARGET} PUBLIC ${TOOLS_TARGET} ${STORAGE_TARGET} ${PROTOCOL_TARGET} jsoncpp_static ${BCOS_BOOSTSSL_TARGET}) diff --git a/cpp/wedpr-transport/ppc-rpc/src/JsonRequest.h b/cpp/wedpr-transport/ppc-rpc/src/JsonRequest.h new file mode 100644 index 00000000..00bdc0d3 --- /dev/null +++ b/cpp/wedpr-transport/ppc-rpc/src/JsonRequest.h @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2022 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 JsonRequest.h + * @author: yujiechen + * @date 2022-11-3 + */ +#pragma once +#include "ppc-framework/rpc/RpcTypeDef.h" +#include +#include +#include +#include + +namespace ppc::rpc +{ +class JsonRequest +{ +public: + using Ptr = std::shared_ptr; + JsonRequest() = default; + JsonRequest(std::string_view _data) { deserialize(_data); } + + virtual ~JsonRequest() {} + + virtual void setJsonRpc(std::string const& _jsonrpc) { m_jsonrpc = _jsonrpc; } + virtual void setMethod(std::string const& _method) { m_method = _method; } + virtual void setId(int64_t _id) { m_id = _id; } + virtual void setParams(Json::Value const& _params) { m_params = _params; } + + virtual std::string const& jsonRpc() const { return m_jsonrpc; } + virtual std::string const& token() const { return m_token; } + virtual int64_t id() const { return m_id; } + virtual Json::Value const& params() const { return m_params; } + virtual std::string const& method() const { return m_method; } + +protected: + virtual void deserialize(std::string_view _requestBody) + { + Json::Value root; + Json::Reader reader; + if (!reader.parse(_requestBody.begin(), _requestBody.end(), root)) + { + BOOST_THROW_EXCEPTION(BCOS_ERROR((int64_t)RpcError::InvalidRequest, + "invalid request for parse to json object failed")); + } + // parse jsonrpc field + if (!root.isMember("jsonrpc")) + { + BOOST_THROW_EXCEPTION( + BCOS_ERROR((int64_t)RpcError::InvalidRequest, "Must set the jsonrpc field")); + } + m_jsonrpc = root["jsonrpc"].asString(); + // parse jsonrpc field + if (!root.isMember("token")) + { + BOOST_THROW_EXCEPTION( + BCOS_ERROR((int64_t)RpcError::InvalidRequest, "Must set the token field")); + } + m_token = root["token"].asString(); + // parse method field + if (!root.isMember("method")) + { + BOOST_THROW_EXCEPTION( + BCOS_ERROR((int64_t)RpcError::InvalidRequest, "Must define the method field")); + } + m_method = root["method"].asString(); + // parse the id field, optional + if (root.isMember("id")) + { + m_id = root["id"].asInt64(); + } + // parse the params field + if (!root.isMember("params")) + { + BOOST_THROW_EXCEPTION( + BCOS_ERROR((int64_t)RpcError::InvalidRequest, "Must define the params field")); + } + m_params = root["params"]; + } + +private: + std::string m_jsonrpc; + std::string m_token; + std::string m_method; + int64_t m_id; + Json::Value m_params; +}; +} // namespace ppc::rpc \ No newline at end of file diff --git a/cpp/wedpr-transport/ppc-rpc/src/JsonResponse.h b/cpp/wedpr-transport/ppc-rpc/src/JsonResponse.h new file mode 100644 index 00000000..d37cd2c0 --- /dev/null +++ b/cpp/wedpr-transport/ppc-rpc/src/JsonResponse.h @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2022 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 JsonResponse.h + * @author: yujiechen + * @date 2022-11-3 + */ +#pragma once +#include +#include +#include +#include +#include +#include +#include + +namespace ppc::rpc +{ +class JsonSink +{ +public: + typedef char char_type; + typedef boost::iostreams::sink_tag category; + + JsonSink(bcos::bytes& buffer) : m_buffer(buffer) {} + + std::streamsize write(const char* s, std::streamsize n) + { + m_buffer.insert(m_buffer.end(), (bcos::byte*)s, (bcos::byte*)s + n); + return n; + } + + bcos::bytes& m_buffer; +}; +class JsonResponse +{ +public: + using Ptr = std::shared_ptr; + JsonResponse() : m_error(std::make_shared(0, "success")) {} + virtual ~JsonResponse() = default; + + void setJsonRpc(std::string const& _jsonrpc) { m_jsonrpc = _jsonrpc; } + void setId(int64_t _id) { m_id = _id; } + void setError(bcos::Error const& _error) { *m_error = _error; } + void setError(bcos::Error&& _error) { *m_error = std::move(_error); } + void setResult(Json::Value&& _result) { m_result = std::move(_result); } + + bcos::Error::Ptr mutableError() { return m_error; } + + virtual bcos::bytes serialize() + { + Json::Value response; + response["jsonrpc"] = m_jsonrpc; + response["id"] = m_id; + if (m_error && m_error->errorCode()) + { + m_result["code"] = m_error->errorCode(); + m_result["message"] = m_error->errorMessage(); + } + response["result"] = m_result; + bcos::bytes out; + boost::iostreams::stream outputStream(out); + std::unique_ptr writer(Json::StreamWriterBuilder().newStreamWriter()); + writer->write(response, &outputStream); + writer.reset(); + return out; + } + +private: + std::string m_jsonrpc; + int64_t m_id; + bcos::Error::Ptr m_error; + Json::Value m_result; +}; +} // namespace ppc::rpc \ No newline at end of file diff --git a/cpp/wedpr-transport/ppc-rpc/src/Rpc.cpp b/cpp/wedpr-transport/ppc-rpc/src/Rpc.cpp new file mode 100644 index 00000000..ea9dce49 --- /dev/null +++ b/cpp/wedpr-transport/ppc-rpc/src/Rpc.cpp @@ -0,0 +1,418 @@ +/* + * Copyright (C) 2022 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 Rpc.cpp + * @author: yujiechen + * @date 2022-11-3 + */ +#include "Rpc.h" +#include "JsonRequest.h" +#include "JsonResponse.h" +#include "ppc-framework/protocol/Protocol.h" +#include "ppc-framework/rpc/RpcTypeDef.h" +#include "ppc-tools/src/config/ParamChecker.h" +#include + +using namespace bcos; +using namespace ppc::rpc; +using namespace ppc::tools; +using namespace ppc::protocol; + +Rpc::Rpc(std::shared_ptr _wsService, ppc::gateway::IGateway::Ptr gateway, + std::string const& _selfPartyID, std::string const& _token, std::string const& _prePath) + : m_prePath(_prePath), + m_wsService(std::move(_wsService)), + m_gateway(std::move(gateway)), + m_taskFactory(std::make_shared(_selfPartyID, _prePath)), + m_token(_token) +{ + // register handler for wsService + m_wsService->registerMsgHandler((uint16_t)ppc::protocol::MessageType::RpcRequest, + boost::bind(&Rpc::onWsRpcRequest, this, boost::placeholders::_1, boost::placeholders::_2)); + // register handler for httpServer + auto httpServer = m_wsService->httpServer(); + if (httpServer) + { + httpServer->setHttpReqHandler([this](bcos::boostssl::http::HttpRequest&& _request, + std::function _responseHandler) { + this->onRPCRequest(std::move(_request), _responseHandler); + }); + } + // register the handler for RUN_TASK_METHOD + m_methodToHandler[RUN_TASK_METHOD] = + boost::bind(&Rpc::runTask, this, boost::placeholders::_1, boost::placeholders::_2); + // register the handler for ASYNC_RUN_TASK_METHOD + m_methodToHandler[ASYNC_RUN_TASK_METHOD] = + boost::bind(&Rpc::asyncRunTask, this, boost::placeholders::_1, boost::placeholders::_2); + // register the handler for GET_TASK_STATUS + m_methodToHandler[GET_TASK_STATUS] = + boost::bind(&Rpc::getTaskStatus, this, boost::placeholders::_1, boost::placeholders::_2); + // register ecdh bs mode methods + m_methodToHandler[ASYNC_RUN_BS_MODE_TASK] = boost::bind( + &Rpc::asyncRunBsModeTask, this, boost::placeholders::_1, boost::placeholders::_2); + m_methodToHandler[FETCH_CIPHER] = + boost::bind(&Rpc::fetchCipher, this, boost::placeholders::_1, boost::placeholders::_2); + m_methodToHandler[SEND_ECDH_CIPHER] = + boost::bind(&Rpc::sendEcdhCipher, this, boost::placeholders::_1, boost::placeholders::_2); + m_methodToHandler[SEND_PARTNER_CIPHER] = boost::bind( + &Rpc::sendPartnerCipher, this, boost::placeholders::_1, boost::placeholders::_2); + m_methodToHandler[GET_BS_MODE_TASK_STATUS] = boost::bind( + &Rpc::getBsModeTaskStatus, this, boost::placeholders::_1, boost::placeholders::_2); + m_methodToHandler[KILL_BS_MODE_TASK] = + boost::bind(&Rpc::killBsModeTask, this, boost::placeholders::_1, boost::placeholders::_2); + m_methodToHandler[UPDATE_BS_MODE_TASK_STATUS] = boost::bind( + &Rpc::updateBsModeTaskStatus, this, boost::placeholders::_1, boost::placeholders::_2); + m_methodToHandler[GET_PEERS] = + boost::bind(&Rpc::getPeers, this, boost::placeholders::_1, boost::placeholders::_2); + RPC_LOG(INFO) << LOG_DESC("init rpc success") << LOG_KV("selfParty", _selfPartyID); +} + +void Rpc::onRPCRequest( + bcos::boostssl::http::HttpRequest&& _request, std::function _responseHandler) +{ + onRPCRequestImpl(_request.body(), _responseHandler); +} + +void Rpc::onRPCRequestImpl( + std::string_view const& _requestBody, std::function _responseHandler) +{ + auto response = std::make_shared(); + try + { + auto startT = bcos::utcSteadyTime(); + JsonRequest request(_requestBody); + if (request.token() != m_token) + { + RPC_LOG(INFO) << LOG_DESC("onRPCRequest: token not match") + << LOG_KV("interface", request.token()) << LOG_KV("config", m_token); + BOOST_THROW_EXCEPTION( + BCOS_ERROR((int64_t)RpcError::NoPermission, "no permission, please check token")); + } + response->setJsonRpc(request.jsonRpc()); + response->setId(request.id()); + auto it = m_methodToHandler.find(request.method()); + if (it == m_methodToHandler.end()) + { + RPC_LOG(DEBUG) << LOG_DESC("onRPCRequest: method not found") + << LOG_KV("method", request.method()); + BOOST_THROW_EXCEPTION(BCOS_ERROR( + (int64_t)RpcError::MethodNotFound, "The method does not exist/is not available.")); + } + auto const& methodHandler = it->second; + methodHandler( + request.params(), [response, _responseHandler, startT, method = request.method()]( + Error::Ptr _error, Json::Value&& _result) { + auto costs = bcos::utcSteadyTime() - startT; + if (costs >= 300) + { + RPC_LOG(INFO) << LOG_DESC("Slow rpc interface found") + << LOG_KV("method", method) << LOG_KV("costs(ms)", costs); + } + + if (_error && _error->errorCode() != 0) + { + response->setError(std::move(*_error)); + response->setResult(std::move(_result)); + } + else + { + response->setResult(std::move(_result)); + } + _responseHandler(response->serialize()); + }); + } + catch (Error const& e) + { + RPC_LOG(WARNING) << LOG_DESC("onRPCRequest error") << LOG_KV("request", _requestBody) + << LOG_KV("code", e.errorCode()) << LOG_KV("msg", e.errorMessage()); + response->setError(e); + _responseHandler(response->serialize()); + } + catch (std::exception const& e) + { + RPC_LOG(WARNING) << LOG_DESC("onRPCRequest error") << LOG_KV("request", _requestBody) + << LOG_KV("msg", boost::diagnostic_information(e)); + response->mutableError()->setErrorCode(PPCRetCode::EXCEPTION); + response->mutableError()->setErrorMessage(boost::diagnostic_information(e)); + _responseHandler(response->serialize()); + } +} + +void Rpc::onWsRpcRequest(std::shared_ptr _msg, + std::shared_ptr _session) +{ + auto buffer = _msg->payload(); + auto request = std::string_view((const char*)buffer->data(), buffer->size()); + onRPCRequestImpl(request, [m_buffer = std::move(buffer), _msg, _session](bcos::bytes resp) { + if (_session && _session->isConnected()) + { + auto buffer = std::make_shared(std::move(resp)); + _msg->setPayload(buffer); + _session->asyncSendMessage(_msg); + return; + } + RPC_LOG(WARNING) + << LOG_DESC("onWsRpcRequest: unable to send response for session has been inactive") + << LOG_KV("req", std::string_view((const char*)m_buffer->data(), m_buffer->size())) + << LOG_KV("resp", std::string_view((const char*)resp.data(), resp.size())) + << LOG_KV("seq", _msg->seq()) + << LOG_KV("endpoint", _session ? _session->endPoint() : std::string("")); + }); +} + +void Rpc::runTask(Json::Value const& _req, RespFunc _respFunc) +{ + if (!m_rpcStorage) + { + BOOST_THROW_EXCEPTION( + BCOS_ERROR((int64_t)RpcError::StorageNotSet, "storage for rpc not set")); + } + auto task = m_taskFactory->createTask(_req); + auto taskHandler = getTaskHandler(task->type(), task->algorithm()); + // not find the handler + if (!taskHandler) + { + std::stringstream oss; + oss << "The specified task algorithm not been implemented or disabled, type: " + << (ppc::protocol::TaskType)(task->type()) << "(" << std::to_string(task->type()) + << ")"; + oss << ", algorithm: " << (ppc::protocol::TaskAlgorithmType)(task->algorithm()) << "(" + << std::to_string(task->algorithm()) << ")"; + auto errorMsg = oss.str(); + RPC_LOG(WARNING) << errorMsg; + BOOST_THROW_EXCEPTION(BCOS_ERROR((int64_t)RpcError::NotImplemented, errorMsg)); + } + RPC_LOG(DEBUG) << LOG_DESC("runTask") << printTaskInfo(task); + auto startT = utcSteadyTime(); + + // insert task + auto error = m_rpcStorage->insertTask(task); + if (error && error->errorCode()) + { + auto result = std::make_shared(task->id()); + result->setStatus(toString(TaskStatus::RUNNING)); + _respFunc(result->error(), result->serializeToJson()); + return; + } + + taskHandler(task, [&, task, _respFunc, startT](ppc::protocol::TaskResult::Ptr&& _result) { + auto cost = bcos::utcSteadyTime() - startT; + _result->setTimeCost(cost); + RPC_LOG(DEBUG) << LOG_DESC("runTask finish") << LOG_KV("timecost", cost) + << printTaskInfo(task); + + // update status + auto error = m_rpcStorage->updateTaskStatus(_result); + if (error && error->errorCode()) + { + auto result = std::make_shared(task->id()); + result->setError(std::move(error)); + result->setStatus(toString(TaskStatus::FAILED)); + _respFunc(result->error(), result->serializeToJson()); + return; + } + _respFunc(_result->error(), _result->serializeToJson()); + }); +} + +void Rpc::asyncRunTask(Json::Value const& _req, RespFunc _respFunc) +{ + if (!m_rpcStorage) + { + BOOST_THROW_EXCEPTION( + BCOS_ERROR((int64_t)RpcError::StorageNotSet, "storage for rpc not set")); + } + auto task = m_taskFactory->createTask(_req); + auto taskHandler = getTaskHandler(task->type(), task->algorithm()); + // not find the handler + if (!taskHandler) + { + std::stringstream oss; + oss << "The specified task algorithm not been implemented or disabled, type: " + << (ppc::protocol::TaskType)(task->type()) << "(" << std::to_string(task->type()) + << ")"; + oss << ", algorithm: " << (ppc::protocol::TaskAlgorithmType)(task->algorithm()) << "(" + << std::to_string(task->algorithm()) << ")"; + auto errorMsg = oss.str(); + RPC_LOG(WARNING) << errorMsg; + BOOST_THROW_EXCEPTION(BCOS_ERROR((int64_t)RpcError::NotImplemented, errorMsg)); + } + RPC_LOG(DEBUG) << LOG_DESC("asyncRunTask") << printTaskInfo(task); + + // insert task + auto error = m_rpcStorage->insertTask(task); + if (error && error->errorCode()) + { + auto result = std::make_shared(task->id()); + result->setStatus(toString(TaskStatus::RUNNING)); + _respFunc(result->error(), result->serializeToJson()); + return; + } + + // return response immediately + auto result = std::make_shared(task->id()); + result->setStatus(toString(TaskStatus::RUNNING)); + _respFunc(result->error(), result->serializeToJson()); + + auto startT = utcSteadyTime(); + taskHandler(task, [&, task, startT](ppc::protocol::TaskResult::Ptr&& _result) { + auto cost = utcSteadyTime() - startT; + _result->setTimeCost(cost); + RPC_LOG(DEBUG) << LOG_DESC("runTask finish") << LOG_KV("timecost", cost) + << printTaskInfo(task); + // update status + auto error = m_rpcStorage->updateTaskStatus(_result); + if (error && error->errorCode()) + { + RPC_LOG(WARNING) << LOG_DESC("failed to updateTaskStatus") << printTaskInfo(task); + } + }); +} + +void Rpc::getTaskStatus(Json::Value const& _req, RespFunc _respFunc) +{ + if (!m_rpcStorage) + { + BOOST_THROW_EXCEPTION( + BCOS_ERROR((int64_t)RpcError::StorageNotSet, "storage for rpc not set")); + } + + if (!_req.isMember("taskID")) + { + BOOST_THROW_EXCEPTION(InvalidParameter() << errinfo_comment("Must specify the taskID")); + } + auto taskID = _req["taskID"].asString(); + + auto result = m_rpcStorage->getTaskStatus(taskID); + _respFunc(result->error(), result->serializeToJson()); +} + + +void Rpc::asyncRunBsModeTask(Json::Value const& _req, RespFunc _respFunc) +{ + if (!m_bsEcdhPSI) + { + BOOST_THROW_EXCEPTION( + BCOS_ERROR((int64_t)RpcError::BsModePsiNotSet, "bs psi for rpc not set")); + } + auto request = std::make_shared(_req, m_prePath); + m_bsEcdhPSI->asyncRunTask(request, [&](psi::BsEcdhResult::Ptr&& _result) { + _respFunc(_result->error(), _result->serializeToJson()); + }); +} + +void Rpc::fetchCipher(Json::Value const& _req, RespFunc _respFunc) +{ + if (!m_bsEcdhPSI) + { + BOOST_THROW_EXCEPTION( + BCOS_ERROR((int64_t)RpcError::BsModePsiNotSet, "bs psi for rpc not set")); + } + + auto request = std::make_shared(_req); + auto result = m_bsEcdhPSI->fetchCipher(request); + _respFunc(result->error(), result->serializeToJson()); +} + +void Rpc::sendEcdhCipher(Json::Value const& _req, RespFunc _respFunc) +{ + if (!m_bsEcdhPSI) + { + BOOST_THROW_EXCEPTION( + BCOS_ERROR((int64_t)RpcError::BsModePsiNotSet, "bs psi for rpc not set")); + } + + auto request = std::make_shared(_req); + auto result = m_bsEcdhPSI->sendEcdhCipher(request); + _respFunc(result->error(), result->serializeToJson()); +} + +void Rpc::getPeers(Json::Value const& _req, RespFunc _respFunc) +{ + if (m_gateway == nullptr) + { + BOOST_THROW_EXCEPTION(BCOS_ERROR(-1, "the gateway not initialized!")); + } + m_gateway->asyncGetPeers([_respFunc](bcos::Error::Ptr error, std::string peersInfo) { + try + { + Json::Value root; + Json::Reader jsonReader; + + if (!jsonReader.parse(peersInfo, root)) + { + BOOST_THROW_EXCEPTION(BCOS_ERROR(-1, "Invalid json string: " + peersInfo)); + } + _respFunc(error, std::move(root)); + } + catch (std::exception const& e) + { + RPC_LOG(WARNING) << LOG_DESC("getPeers exception") + << LOG_KV("error", boost::diagnostic_information(e)); + } + }); +} + +void Rpc::sendPartnerCipher(Json::Value const& _req, RespFunc _respFunc) +{ + if (!m_bsEcdhPSI) + { + BOOST_THROW_EXCEPTION( + BCOS_ERROR((int64_t)RpcError::BsModePsiNotSet, "bs psi for rpc not set")); + } + + auto request = std::make_shared(_req); + auto result = m_bsEcdhPSI->sendPartnerCipher(request); + _respFunc(result->error(), result->serializeToJson()); +} + +void Rpc::getBsModeTaskStatus(Json::Value const& _req, RespFunc _respFunc) +{ + if (!m_bsEcdhPSI) + { + BOOST_THROW_EXCEPTION( + BCOS_ERROR((int64_t)RpcError::BsModePsiNotSet, "bs psi for rpc not set")); + } + + auto request = std::make_shared(_req); + auto result = m_bsEcdhPSI->getTaskStatus(request); + _respFunc(result->error(), result->serializeToJson()); +} + +void Rpc::killBsModeTask(Json::Value const& _req, RespFunc _respFunc) +{ + if (!m_bsEcdhPSI) + { + BOOST_THROW_EXCEPTION( + BCOS_ERROR((int64_t)RpcError::BsModePsiNotSet, "bs psi for rpc not set")); + } + + auto request = std::make_shared(_req); + auto result = m_bsEcdhPSI->killTask(request); + _respFunc(result->error(), result->serializeToJson()); +} + +void Rpc::updateBsModeTaskStatus(Json::Value const& _req, RespFunc _respFunc) +{ + if (!m_bsEcdhPSI) + { + BOOST_THROW_EXCEPTION( + BCOS_ERROR((int64_t)RpcError::BsModePsiNotSet, "bs psi for rpc not set")); + } + + auto request = std::make_shared(_req); + auto result = m_bsEcdhPSI->updateTaskStatus(request); + _respFunc(result->error(), result->serializeToJson()); +} diff --git a/cpp/wedpr-transport/ppc-rpc/src/Rpc.h b/cpp/wedpr-transport/ppc-rpc/src/Rpc.h new file mode 100644 index 00000000..be1da870 --- /dev/null +++ b/cpp/wedpr-transport/ppc-rpc/src/Rpc.h @@ -0,0 +1,157 @@ +/* + * Copyright (C) 2022 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 Rpc.h + * @author: yujiechen + * @date 2022-11-3 + */ +#pragma once +#include "ppc-framework/front/FrontInterface.h" +#include "ppc-framework/gateway/IGateway.h" +#include "ppc-framework/rpc/RpcInterface.h" +#include "ppc-framework/rpc/RpcStatusInterface.h" +#include "protocol/src/JsonTaskImpl.h" +#include +#include +#include +#include +#include +#include + +namespace ppc::rpc +{ +class Rpc : public RpcInterface +{ +public: + using Ptr = std::shared_ptr; + Rpc(std::shared_ptr _wsService, + ppc::gateway::IGateway::Ptr gateway, std::string const& _selfPartyID, + std::string const& _token, std::string const& _prePath = "data"); + ~Rpc() override { stop(); } + void start() override + { + if (m_wsService) + { + m_wsService->start(); + } + if (m_rpcStorage) + { + m_rpcStorage->start(); + } + RPC_LOG(INFO) << LOG_DESC("start RPC"); + } + void stop() override + { + if (m_wsService) + { + m_wsService->stop(); + } + if (m_rpcStorage) + { + m_rpcStorage->stop(); + } + RPC_LOG(INFO) << LOG_DESC("stop RPC"); + } + + void registerHandler(std::string const& _methodName, + std::function _handler) override + { + bcos::UpgradableGuard l(x_methodToHandler); + if (m_methodToHandler.count(_methodName)) + { + RPC_LOG(INFO) << LOG_DESC("registerHandler return for method handler already exists") + << LOG_KV("method", _methodName); + return; + } + bcos::UpgradeGuard ul(l); + m_methodToHandler[_methodName] = _handler; + RPC_LOG(INFO) << LOG_DESC("registerHandler success") << LOG_KV("method", _methodName); + } + + void registerTaskHandler( + ppc::protocol::TaskType _type, uint8_t _algorithm, TaskHandler _handler) override + { + bcos::UpgradableGuard l(x_taskHandlers); + if (m_taskHandlers.count((uint8_t)_type) && + m_taskHandlers.at((uint8_t)_type).count(_algorithm)) + { + RPC_LOG(INFO) << LOG_DESC("registerTaskHandler return for handler already exists") + << LOG_KV("type", _type) << LOG_KV("algorithm", _algorithm); + return; + } + m_taskHandlers[(uint8_t)_type][_algorithm] = _handler; + RPC_LOG(INFO) << LOG_DESC("registerTaskHandler success") << LOG_KV("type", _type) + << LOG_KV("algorithm", (int)_algorithm); + } + + void setRpcStorage(RpcStatusInterface::Ptr _storage) { m_rpcStorage = std::move(_storage); } + + void setBsEcdhPSI(psi::BsEcdhPSIInterface::Ptr _psi) { m_bsEcdhPSI = std::move(_psi); } + +protected: + virtual void onRPCRequest(bcos::boostssl::http::HttpRequest&& _request, + std::function _responseHandler); + + virtual void onRPCRequestImpl( + std::string_view const& _requestBody, std::function _responseHandler); + virtual void onWsRpcRequest(std::shared_ptr _msg, + std::shared_ptr _session); + + virtual TaskHandler getTaskHandler(uint8_t _type, uint8_t _algorithm) const + { + bcos::ReadGuard l(x_taskHandlers); + if (!m_taskHandlers.count(_type) || !m_taskHandlers.at(_type).count(_algorithm)) + { + return nullptr; + } + return m_taskHandlers.at(_type).at(_algorithm); + } + + virtual void runTask(Json::Value const& _req, RespFunc _respFunc); + virtual void asyncRunTask(Json::Value const& _req, RespFunc _respFunc); + virtual void getTaskStatus(Json::Value const& _req, RespFunc _respFunc); + + virtual void asyncRunBsModeTask(Json::Value const& _req, RespFunc _respFunc); + virtual void fetchCipher(Json::Value const& _req, RespFunc _respFunc); + virtual void sendEcdhCipher(Json::Value const& _req, RespFunc _respFunc); + virtual void sendPartnerCipher(Json::Value const& _req, RespFunc _respFunc); + virtual void getBsModeTaskStatus(Json::Value const& _req, RespFunc _respFunc); + virtual void killBsModeTask(Json::Value const& _req, RespFunc _respFunc); + virtual void updateBsModeTaskStatus(Json::Value const& _req, RespFunc _respFunc); + + virtual void getPeers(Json::Value const& _req, RespFunc _respFunc); + +private: + std::string m_prePath; + std::shared_ptr m_wsService; + ppc::gateway::IGateway::Ptr m_gateway; + RpcStatusInterface::Ptr m_rpcStorage; + + // Note: here use jsonTaskFactory to decrease the overhead to convert json::value to string when + // deserialze the task + ppc::protocol::JsonTaskFactory::Ptr m_taskFactory; + std::string m_token; + + // the method_name to function + std::map> m_methodToHandler; + bcos::SharedMutex x_methodToHandler; + + // the taskHandlers + std::map> m_taskHandlers; + mutable bcos::SharedMutex x_taskHandlers; + + psi::BsEcdhPSIInterface::Ptr m_bsEcdhPSI; +}; +} // namespace ppc::rpc diff --git a/cpp/wedpr-transport/ppc-rpc/src/RpcFactory.cpp b/cpp/wedpr-transport/ppc-rpc/src/RpcFactory.cpp new file mode 100644 index 00000000..95953dd0 --- /dev/null +++ b/cpp/wedpr-transport/ppc-rpc/src/RpcFactory.cpp @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2022 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 RpcFactory.cpp + * @author: yujiechen + * @date 2022-11-4 + */ +#include "RpcFactory.h" +#include "ppc-storage/src/mysql/MySQLStorage.h" +#include "ppc-tools/src/config/PPCConfig.h" +#include +#include + +using namespace bcos; +using namespace ppc::rpc; +using namespace ppc::tools; + +Rpc::Ptr RpcFactory::buildRpc( + ppc::tools::PPCConfig::ConstPtr _config, ppc::gateway::IGateway::Ptr gateway) +{ + auto wsConfig = initConfig(_config); + // create the wsConfig + auto wsService = std::make_shared("WeDPR-RPC"); + wsService->setTimerFactory(std::make_shared()); + auto initializer = std::make_shared(); + + initializer->setConfig(wsConfig); + initializer->initWsService(wsService); + + auto rpc = std::make_shared( + wsService, gateway, m_selfPartyID, _config->rpcConfig().token, _config->dataLocation()); + return rpc; +} + +std::shared_ptr RpcFactory::initConfig( + ppc::tools::PPCConfig::ConstPtr _config) +{ + // init the wsConfig + auto wsConfig = std::make_shared(); + wsConfig->setModel(boostssl::ws::WsModel::Server); + + wsConfig->setListenIP(_config->rpcConfig().listenIp); + wsConfig->setListenPort(_config->rpcConfig().listenPort); + wsConfig->setThreadPoolSize(_config->rpcConfig().threadPoolSize); + wsConfig->setDisableSsl(_config->rpcConfig().disableSsl); + if (_config->rpcConfig().disableSsl) + { + return wsConfig; + } + // non-sm-ssl + auto contextConfig = std::make_shared(); + if (!_config->rpcConfig().enableSM) + { + boostssl::context::ContextConfig::CertConfig certConfig; + certConfig.caCert = _config->rpcConfig().caCertPath; + certConfig.nodeCert = _config->rpcConfig().sslCertPath; + certConfig.nodeKey = _config->rpcConfig().sslKeyPath; + contextConfig->setCertConfig(certConfig); + contextConfig->setSslType("ssl"); + RPC_LOG(INFO) << LOG_DESC("initConfig: rpc work in non-sm-ssl model") + << LOG_KV("caCert", certConfig.caCert) + << LOG_KV("nodeCert", certConfig.nodeCert) + << LOG_KV("nodeKey", certConfig.nodeKey); + wsConfig->setContextConfig(contextConfig); + return wsConfig; + } + // sm-ssl + boostssl::context::ContextConfig::SMCertConfig certConfig; + certConfig.caCert = _config->rpcConfig().smCaCertPath; + certConfig.nodeCert = _config->rpcConfig().smSslCertPath; + certConfig.nodeKey = _config->rpcConfig().smSslKeyPath; + certConfig.enNodeCert = _config->rpcConfig().smEnSslCertPath; + certConfig.enNodeKey = _config->rpcConfig().smEnSslKeyPath; + contextConfig->setSmCertConfig(certConfig); + contextConfig->setSslType("sm_ssl"); + + BCOS_LOG(INFO) << LOG_DESC("initConfig") << LOG_DESC("rpc work in sm ssl model") + << LOG_KV("caCert", certConfig.caCert) << LOG_KV("nodeCert", certConfig.nodeCert) + << LOG_KV("enNodeCert", certConfig.enNodeCert); + + wsConfig->setContextConfig(contextConfig); + return wsConfig; +} \ No newline at end of file diff --git a/cpp/wedpr-transport/ppc-rpc/src/RpcFactory.h b/cpp/wedpr-transport/ppc-rpc/src/RpcFactory.h new file mode 100644 index 00000000..91f94ff1 --- /dev/null +++ b/cpp/wedpr-transport/ppc-rpc/src/RpcFactory.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2022 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 RpcFactory.h + * @author: yujiechen + * @date 2022-11-4 + */ +#pragma once +#include "Rpc.h" +#include "ppc-framework/gateway/IGateway.h" +#include +namespace bcos::boostssl::ws +{ +class WsConfig; +} +namespace ppc::tools +{ +class PPCConfig; +} +namespace ppc::rpc +{ +class RpcFactory +{ +public: + using Ptr = std::shared_ptr; + RpcFactory(std::string const& _selfPartyID) : m_selfPartyID(_selfPartyID) {} + virtual ~RpcFactory() = default; + + Rpc::Ptr buildRpc( + std::shared_ptr _config, ppc::gateway::IGateway::Ptr gateway); + +private: + std::shared_ptr initConfig( + std::shared_ptr _config); + +private: + std::string m_selfPartyID; +}; +} // namespace ppc::rpc \ No newline at end of file diff --git a/cpp/wedpr-transport/ppc-rpc/src/RpcMemory.cpp b/cpp/wedpr-transport/ppc-rpc/src/RpcMemory.cpp new file mode 100644 index 00000000..0cd35e2a --- /dev/null +++ b/cpp/wedpr-transport/ppc-rpc/src/RpcMemory.cpp @@ -0,0 +1,127 @@ +/** + * Copyright (C) 2022 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 RpcMemory.cpp + * @author: shawnhe + * @date 2023-03-28 + */ + +#include "RpcMemory.h" +#include "bcos-utilities/Common.h" + +using namespace bcos; +using namespace ppc::protocol; +using namespace ppc::rpc; +using namespace ppc::storage; + +void RpcMemory::start() +{ + if (m_taskCleaner) + { + m_taskCleaner->registerTimeoutHandler(boost::bind(&RpcMemory::cleanTask, this)); + m_taskCleaner->start(); + } +} + + +void RpcMemory::stop() +{ + if (m_taskCleaner) + { + m_taskCleaner->stop(); + } +} + +void RpcMemory::cleanTask() +{ + try + { + WriteGuard l(x_tasks); + for (auto it = m_tasks.begin(); it != m_tasks.end();) + { + if (it->second.first + VALIDITY_TERM <= utcSteadyTime()) + { + it = m_tasks.erase(it); + } + else + { + ++it; + } + } + } + catch (std::exception const& e) + { + RPC_STATUS_LOG(WARNING) << LOG_DESC("cleanTask exception") + << LOG_KV("exception", boost::diagnostic_information(e)); + } + m_taskCleaner->restart(); +} + +bcos::Error::Ptr RpcMemory::insertTask(protocol::Task::Ptr _task) +{ + WriteGuard l(x_tasks); + auto it = m_tasks.find(_task->id()); + if (it != m_tasks.end()) + { + auto taskResult = it->second.second; + // the task already exists case + if (!taskResult || taskResult->status() == toString(TaskStatus::RUNNING)) + { + return std::make_shared(PPCRetCode::WRITE_RPC_STATUS_ERROR, "task exists"); + } + if (taskResult) + { + RPC_STATUS_LOG(INFO) << LOG_DESC("find the existed not running-task") + << LOG_KV("task", _task->id()) + << LOG_KV("status", taskResult->status()); + if (taskResult->status() != toString(TaskStatus::COMPLETED)) + { + // erase the task_id + m_front->eraseTaskInfo(_task->id()); + } + } + } + auto taskResult = std::make_shared(_task->id()); + taskResult->setStatus(toString(TaskStatus::RUNNING)); + m_tasks[_task->id()] = {utcSteadyTime(), std::move(taskResult)}; + return nullptr; +} + +bcos::Error::Ptr RpcMemory::updateTaskStatus(protocol::TaskResult::Ptr _taskResult) +{ + WriteGuard l(x_tasks); + if (m_tasks.find(_taskResult->taskID()) == m_tasks.end()) + { + return std::make_shared(PPCRetCode::WRITE_RPC_STATUS_ERROR, "task not found"); + } + m_tasks[_taskResult->taskID()].second = std::move(_taskResult); + return nullptr; +} + +TaskResult::Ptr RpcMemory::getTaskStatus(const std::string& _taskID) +{ + ReadGuard l(x_tasks); + if (m_tasks.find(_taskID) == m_tasks.end()) + { + auto error = + std::make_shared(PPCRetCode::READ_RPC_STATUS_ERROR, "task not found"); + auto result = std::make_shared(_taskID); + result->setStatus(toString(TaskStatus::FAILED)); + result->setError(error); + return result; + } + + return m_tasks[_taskID].second; +} \ No newline at end of file diff --git a/cpp/wedpr-transport/ppc-rpc/src/RpcMemory.h b/cpp/wedpr-transport/ppc-rpc/src/RpcMemory.h new file mode 100644 index 00000000..bb2b0a3c --- /dev/null +++ b/cpp/wedpr-transport/ppc-rpc/src/RpcMemory.h @@ -0,0 +1,60 @@ +/** + * Copyright (C) 2022 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 RpcMemory.h + * @author: shawnhe + * @date 2023-03-27 + * @desc: 如果无法启用mysqlx协议,则数据保存到内存中 + */ + +#pragma once +#include "ppc-framework/front/FrontInterface.h" +#include "ppc-framework/rpc/RpcStatusInterface.h" +#include +#include + +namespace ppc::rpc +{ +class RpcMemory : public RpcStatusInterface +{ +public: + using Ptr = std::shared_ptr; + + RpcMemory(ppc::front::FrontInterface::Ptr front) + : m_front(std::move(front)), + m_taskCleaner(std::make_shared(60 * 60 * 1000, "taskCleaner")) + {} + ~RpcMemory() override = default; + + void start() override; + void stop() override; + + bcos::Error::Ptr insertTask(protocol::Task::Ptr _task) override; + bcos::Error::Ptr updateTaskStatus(protocol::TaskResult::Ptr _taskResult) override; + protocol::TaskResult::Ptr getTaskStatus(const std::string& _taskID) override; + +protected: + void cleanTask(); + +private: + ppc::front::FrontInterface::Ptr m_front; + + mutable bcos::SharedMutex x_tasks; + std::unordered_map> m_tasks; + std::shared_ptr m_taskCleaner; + + const uint64_t VALIDITY_TERM = 24 * 60 * 60 * 1000; // ms +}; +} // namespace ppc::rpc \ No newline at end of file diff --git a/cpp/wedpr-transport/ppc-rpc/tests/CMakeLists.txt b/cpp/wedpr-transport/ppc-rpc/tests/CMakeLists.txt new file mode 100644 index 00000000..9654e227 --- /dev/null +++ b/cpp/wedpr-transport/ppc-rpc/tests/CMakeLists.txt @@ -0,0 +1,10 @@ +file(GLOB_RECURSE SOURCES "*.cpp" "*.h") + +# cmake settings +set(TEST_BINARY_NAME test-ppc-rpc) + +add_executable(${TEST_BINARY_NAME} ${SOURCES}) +target_include_directories(${TEST_BINARY_NAME} PRIVATE .) + +target_link_libraries(${TEST_BINARY_NAME} ${RPC_TARGET} ${BOOST_UNIT_TEST}) +add_test(NAME test-rpc WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} COMMAND ${TEST_BINARY_NAME}) \ No newline at end of file diff --git a/cpp/wedpr-transport/ppc-rpc/tests/TestRpcRequestResponse.cpp b/cpp/wedpr-transport/ppc-rpc/tests/TestRpcRequestResponse.cpp new file mode 100644 index 00000000..134f9192 --- /dev/null +++ b/cpp/wedpr-transport/ppc-rpc/tests/TestRpcRequestResponse.cpp @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2022 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 TestRpcRequestResponse.cpp + * @author: yujiechen + * @date 2022-11-4 + */ +#include "ppc-rpc/src/JsonRequest.h" +#include "ppc-rpc/src/JsonResponse.h" +#include +#include +#include + +using namespace ppc::rpc; +using namespace bcos; +using namespace bcos::test; + +namespace ppc::test +{ +BOOST_FIXTURE_TEST_SUITE(rpcRequestResponseTest, TestPromptFixture) +BOOST_AUTO_TEST_CASE(testJsonRequest) +{ + // case1: valid request + std::string requestData = + "{\"jsonrpc\":\"2.0\",\"token\":\"test\",\"method\":\"getBlockNumber\",\"params\":[1]," + "\"id\":1}"; + auto jsonRequest = std::make_shared(requestData); + BOOST_CHECK(jsonRequest->jsonRpc() == "2.0"); + BOOST_CHECK(jsonRequest->method() == "getBlockNumber"); + BOOST_CHECK(jsonRequest->id() == 1); + Json::Value params = jsonRequest->params(); + BOOST_CHECK(params.isArray() == true); + for (auto const& param : params) + { + BOOST_CHECK(param.asInt64() == 1); + } + // case2: invalid request without method + requestData = "{\"jsonrpc\":\"2.0\",\"token\":\"test\",\"params\":[1],\"id\":1}"; + BOOST_CHECK_THROW(std::make_shared(requestData), bcos::Error); + // case3: invalid json request + requestData = "abc"; + BOOST_CHECK_THROW(std::make_shared(requestData), bcos::Error); + + // case4: valid request with taskInfo + requestData = + "{\"jsonrpc\":\"2.0\",\"token\":\"test\",\"method\":\"runTask\",\"params\":{\"algorithm\":" + "45,\"params\":" + "\"taskParam\", " + "\"parties\":[{\"data\":{\"desc\":{\"path\":\"testPath\"},\"id\":\"dataSelf\",\"type\":0}," + "\"desc\":\"selfParty\",\"id\":\"selfParty\",\"partyIndex\":0,\"type\":0}]},\"id\":1}"; + std::make_shared(requestData); + BOOST_CHECK_NO_THROW(std::make_shared(requestData)); +} + +BOOST_AUTO_TEST_CASE(testJsonResponse) +{ + auto jsonResponse = std::make_shared(); + jsonResponse->setJsonRpc("3.0"); + jsonResponse->setId(10); + BOOST_CHECK_NO_THROW(jsonResponse->serialize()); +} +BOOST_AUTO_TEST_SUITE_END() +} // namespace ppc::test \ No newline at end of file diff --git a/cpp/wedpr-transport/ppc-rpc/tests/main.cpp b/cpp/wedpr-transport/ppc-rpc/tests/main.cpp new file mode 100644 index 00000000..2c06f9b5 --- /dev/null +++ b/cpp/wedpr-transport/ppc-rpc/tests/main.cpp @@ -0,0 +1,2 @@ +#define BOOST_TEST_MAIN +#include \ No newline at end of file diff --git a/cpp/wedpr-transport/sdk-wrapper/CMakeLists.txt b/cpp/wedpr-transport/sdk-wrapper/CMakeLists.txt new file mode 100644 index 00000000..b708386a --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/CMakeLists.txt @@ -0,0 +1,17 @@ +project(wedpr-transport-swig VERSION ${VERSION}) + +# Add subdirectories for each language if desired +option(BUILD_PYTHON "Build Python SWIG module" OFF) +if(BUILD_PYTHON) + # 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) + add_subdirectory(python) +endif() + +# Add subdirectories for each language if desired +option(BUILD_JAVA "Build JAVA SWIG module" ON) +if(BUILD_JAVA) + add_subdirectory(java) +endif() diff --git a/cpp/wedpr-transport/sdk-wrapper/java/CMakeLists.txt b/cpp/wedpr-transport/sdk-wrapper/java/CMakeLists.txt new file mode 100644 index 00000000..132634ec --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/CMakeLists.txt @@ -0,0 +1,35 @@ +option(AUTO_GENERATE "Auto generate the targes" OFF) +# Note: use SWIG Version 4.2.1 +if(AUTO_GENERATE) + # only auto-generate should find swig + file(GLOB_RECURSE SRCS wedpr_java_transport.i) + set_source_files_properties(${SRCS} PROPERTIES CPLUSPLUS ON) + + set(WEDPR_TRANSPORT_PACKAGE "com.webank.wedpr.sdk.jni.generated") + + set_property(SOURCE swig/wedpr_java_transport.i PROPERTY COMPILE_OPTIONS + -package ${WEDPR_TRANSPORT_PACKAGE}) + + file(MAKE_DIRECTORY ${WEDPR_JAVA_TRANSPORT_DIR}) + file(MAKE_DIRECTORY ${WEDPR_JAVA_TRANSPORT_LIB_DIR}) + + swig_add_library(${WEDPR_JAVA_TRANSPORT} + TYPE MODULE + LANGUAGE java + OUTPUT_DIR ${WEDPR_JAVA_TRANSPORT_DIR} + SOURCES ${SRCS}) +else() + file(GLOB_RECURSE SRCS src/*.cxx) + add_library(${WEDPR_JAVA_TRANSPORT} SHARED ${SRCS}) +endif() + +SET(LIBRARY_OUTPUT_PATH ${WEDPR_JAVA_TRANSPORT_LIB_DIR}) +message("LIBRARY_OUTPUT_PATH: ${WEDPR_JAVA_TRANSPORT_LIB_DIR}") + +set_target_properties(${WEDPR_JAVA_TRANSPORT} PROPERTIES + SWIG_USE_TARGET_INCLUDE_DIRECTORIES ON + POSITION_INDEPENDENT_CODE ON) + +target_include_directories(${WEDPR_JAVA_TRANSPORT} PRIVATE ${JNI_INCLUDE_DIRS}) + +target_link_libraries(${WEDPR_JAVA_TRANSPORT} PRIVATE ${WEDPR_TRANSPORT_SDK_TARGET} ${JAVA_LIBRARIES}) \ No newline at end of file diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/build.gradle b/cpp/wedpr-transport/sdk-wrapper/java/bindings/build.gradle new file mode 100644 index 00000000..40ccf763 --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/build.gradle @@ -0,0 +1,215 @@ +plugins { + id 'java' + id 'idea' + id 'java-library' + id 'maven-publish' + id 'org.ajoberstar.grgit' version '4.1.1' + id "de.undercouch.download" version "4.1.2" + id 'com.github.sherter.google-java-format' version '0.9' +} +apply plugin: 'maven-publish' +apply plugin: 'java' +apply plugin: 'signing' + +// Additional attribute definition +ext { + if (!project.hasProperty("ossrhUsername")) { + ossrhUsername="xxx" + } + + if (!project.hasProperty("ossrhPassword")) { + ossrhPassword="xxx" + } + jacksonVersion = "2.17.1" + lombokVersion = "1.18.32" + junitVersion = "4.13.2" + log4jVersion = "2.23.0" + jmhVersion = "1.36" + apacheCommonLangVersion = "3.14.0" + println("*ossrhUsername: " + ossrhUsername) +} + +println("Notice: current gradle version is " + gradle.gradleVersion) +sourceCompatibility = 1.8 +targetCompatibility = 1.8 + +[compileJava, compileTestJava, javadoc]*.options*.encoding = 'UTF-8' + +repositories { + maven { url "https://maven.aliyun.com/nexus/content/groups/public/" } + maven { url "https://oss.sonatype.org/service/local/staging/deploy/maven2"} + maven { url "https://oss.sonatype.org/content/repositories/snapshots" } + maven {url "https://plugins.gradle.org/m2/"} + mavenCentral() + mavenLocal() +} + + googleJavaFormat { + toolVersion = '1.7' + options style: 'AOSP' + source = sourceSets*.allJava + include '**/*.java' + exclude '**/*Test.java' + exclude '**/Test*.java' + exclude '**/Mock*.java' + } + +sourceSets { + main { + java { + srcDir 'src/main/java' + } + resources { + srcDir 'src/main/resources' + } + } + + jmh { + java { + srcDir 'src/jmh/java' + } + resources { + srcDir 'src/jmh/resources' + } + + runtimeClasspath += sourceSets.main.runtimeClasspath + compileClasspath += sourceSets.main.compileClasspath + + compileClasspath += main.output + runtimeClasspath += main.output + } +} +dependencies { + api ('org.slf4j:slf4j-api:1.7.36') + + implementation("org.projectlombok:lombok:${lombokVersion}") + implementation("org.apache.commons:commons-lang3:${apacheCommonLangVersion}") + implementation("com.fasterxml.jackson.core:jackson-databind:${jacksonVersion}") + jmhImplementation ("org.openjdk.jmh:jmh-core:${jmhVersion}") + jmhAnnotationProcessor ("org.openjdk.jmh:jmh-generator-annprocess:${jmhVersion}") + + testImplementation ("org.slf4j:slf4j-log4j12:${log4jVersion}") + testImplementation ("junit:junit:${junitVersion}") + + annotationProcessor("org.projectlombok:lombok:${lombokVersion}") +} + +archivesBaseName = 'wedpr-gateway-sdk' +group = 'com.webank.wedpr' +version = '1.0.0-SNAPSHOT' + +jar { + exclude '**/*.xml' + exclude '**/*.properties' + manifest { + try { + def repo = grgit.open(currentDir: project.rootDir) + if (repo != null) { + + def date = new Date().format("yyyy-MM-dd'T'HH:mm:ssZ") + def branch = repo.branch.getCurrent().getName() + def commit = repo.head().getAbbreviatedId(40) + + attributes(["Implementation-Timestamp": date, + "Git-Branch" : branch, + "Git-Commit" : commit]) + } + } catch (Exception e) { + e.printStackTrace() + } + } from sourceSets.main.output + + doLast { + copy { + from destinationDirectory + into 'dist/apps' + } + + copy { + from configurations.runtimeClasspath + into 'dist/lib' + } + } +} + +javadoc { + options.addStringOption('Xdoclint:none', '-quiet') + options.addStringOption('encoding', 'UTF-8') + options.addStringOption('charSet', 'UTF-8') +} + +task sourcesJar(type: Jar) { + from sourceSets.main.allJava + archiveClassifier = 'sources' + duplicatesStrategy 'exclude' +} +tasks.withType(Copy).all { + duplicatesStrategy 'exclude' +} + + +task javadocJar(type: Jar) { + from javadoc + archiveClassifier = 'javadoc' +} + +task jmh(type: JavaExec, dependsOn: jmhClasses) { + main = 'com.webank.wedpr.sdk.jni.jmh.BenchmarkMain' + classpath = sourceSets.jmh.compileClasspath + sourceSets.jmh.runtimeClasspath +} + +publishing { + publications { + mavenJava(MavenPublication) { + + artifactId project.name + groupId project.group + version project.version + + from components.java + artifact sourcesJar + artifact javadocJar + + pom { + name = 'wedpr' + description = 'wedpr java gateway sdk' + url = 'http://www.fisco-bcos.org' + + licenses { + license { + name = 'The Apache License, Version 2.0' + url = 'http://www.apache.org/licenses/LICENSE-2.0.txt' + } + } + scm { + connection = 'http://github.com/WeBankBlockchain/wedpr-components.git' + url = 'http://github.com/WeBankBlockchain/wedpr-components.git' + } + + developers { + developer { + id = 'zhangsan' + name = 'zhangsan' + email = 'zhangsan@example.com' + } + } + } + } + } + repositories { + maven { + def releasesRepoURL = "https://oss.sonatype.org/service/local/staging/deploy/maven2" + def snapshotsRepoURL = "https://oss.sonatype.org/content/repositories/snapshots" + allowInsecureProtocol = true + url = !version.endsWith("SNAPSHOT") ? releasesRepoURL : snapshotsRepoURL + + credentials { + username ossrhUsername + password ossrhPassword + } + } + signing { + sign publishing.publications.mavenJava + } + } +} diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/conf/wedpr_sdk_log_config.ini b/cpp/wedpr-transport/sdk-wrapper/java/bindings/conf/wedpr_sdk_log_config.ini new file mode 100644 index 00000000..6b5595be --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/conf/wedpr_sdk_log_config.ini @@ -0,0 +1,9 @@ +[log] + enable=true + ; print the log to std::cout or not, default print to the log files + enable_console_output = false + log_path=./log + ; info debug trace + level=info + ; MB + max_log_file_size=200 diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/gradle/wrapper/gradle-wrapper.jar b/cpp/wedpr-transport/sdk-wrapper/java/bindings/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 00000000..e708b1c0 Binary files /dev/null and b/cpp/wedpr-transport/sdk-wrapper/java/bindings/gradle/wrapper/gradle-wrapper.jar differ diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/gradle/wrapper/gradle-wrapper.properties b/cpp/wedpr-transport/sdk-wrapper/java/bindings/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 00000000..a33e7343 --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +# distributionUrl=https\://services.gradle.org/distributions/gradle-7.3-bin.zip +distributionUrl=https://mirrors.cloud.tencent.com/gradle/gradle-7.3-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/gradlew b/cpp/wedpr-transport/sdk-wrapper/java/bindings/gradlew new file mode 100644 index 00000000..4f906e0c --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/gradlew @@ -0,0 +1,185 @@ +#!/usr/bin/env sh + +# +# Copyright 2015 the original author or authors. +# +# 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 +# +# https://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. +# + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$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 "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# 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 + ;; + 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" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin or MSYS, switch paths to Windows format before running java +if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=`expr $i + 1` + done + case $i in + 0) set -- ;; + 1) set -- "$args0" ;; + 2) set -- "$args0" "$args1" ;; + 3) set -- "$args0" "$args1" "$args2" ;; + 4) set -- "$args0" "$args1" "$args2" "$args3" ;; + 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=`save "$@"` + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +exec "$JAVACMD" "$@" diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/gradlew.bat b/cpp/wedpr-transport/sdk-wrapper/java/bindings/gradlew.bat new file mode 100644 index 00000000..ac1b06f9 --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/gradlew.bat @@ -0,0 +1,89 @@ +@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%" == "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%"=="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! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/settings.gradle b/cpp/wedpr-transport/sdk-wrapper/java/bindings/settings.gradle new file mode 100644 index 00000000..4a6f5d4e --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/settings.gradle @@ -0,0 +1,2 @@ +rootProject.name = 'wedpr-gateway-sdk' + diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/common/Common.java b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/common/Common.java new file mode 100644 index 00000000..3f121c96 --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/common/Common.java @@ -0,0 +1,43 @@ +/* + * Copyright 2017-2025 [webank-wedpr] + * + * 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. + * + */ + +package com.webank.wedpr.sdk.jni.common; + +import com.webank.wedpr.sdk.jni.generated.*; +import com.webank.wedpr.sdk.jni.generated.Error; + +public class Common { + public static void requireNotNull(String objectName, Object object) throws WeDPRSDKException { + if (object == null) { + throw new WeDPRSDKException("The object " + objectName + " must be not null!"); + } + } + + public static void checkResult(String interfaceName, Error error) throws WeDPRSDKException { + if (error == null || error.errorCode() == 0) { + return; + } + throw new WeDPRSDKException( + error.errorCode(), + "call " + interfaceName + " failed for: " + error.errorMessage()); + } + + public static String getUrl(String url) { + if (url.startsWith("http://")) { + return url; + } + return String.format("http://%s", url); + } +} diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/common/Constant.java b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/common/Constant.java new file mode 100644 index 00000000..4c258d0c --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/common/Constant.java @@ -0,0 +1,25 @@ +/* + * Copyright 2017-2025 [webank-wedpr] + * + * 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. + * + */ + +package com.webank.wedpr.sdk.jni.common; + +public class Constant { + + public static int SUCCESS = 0; + public static int FAILED = -1; + + public static String SUCCESS_MSG = "success"; + public static final String URI_SPLITER = "/"; +} diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/common/JniLibLoader.java b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/common/JniLibLoader.java new file mode 100644 index 00000000..ff34a1de --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/common/JniLibLoader.java @@ -0,0 +1,278 @@ +/** + * Copyright 2023 [wedpr] + * + *

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. + */ +package com.webank.wedpr.sdk.jni.common; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.Field; +import java.nio.file.Files; +import java.nio.file.StandardCopyOption; +import java.util.Objects; +import java.util.Scanner; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Helper class to load wedpr-java-transportjni resources. + * + * @author octopus + */ +public final class JniLibLoader { + private static final Logger logger = LoggerFactory.getLogger(JniLibLoader.class); + + public static final String LINUX = "linux"; + public static final String MAC = "mac"; + public static final String WIN = "win"; + + public static final String NATIVE_RESOURCE_LIB_NAME = "wedpr_java_transport_jni"; + public static final String NATIVE_RESOURCE_HOME = "/META-INF/native"; + public static final String NATIVE_WIN_DEPS_DIR = NATIVE_RESOURCE_HOME + "/win/"; + public static final String WIN_DEPS_FILE_LIST = "file.list"; + + public static final String OS_NAME = getOs(); + public static final String ARCH_NAME = getArch(); + + private static File WORKDIR; + + static { + // 1. initialize workdir + + // -Dcom.webank.wedpr.workdir + String workdir = System.getProperty("com.webank.wedpr.sdk.jni.workdir"); + if (workdir != null) { + try { + File f = new File(workdir); + f.mkdirs(); + WORKDIR = f; + logger.info("initialize workdir, -Dcom.webank.wedpr.sdk.jni.workdir: {}", WORKDIR); + } catch (Exception e) { + logger.debug("initialize workdir, cannot mkdir workdir: {}, e: ", workdir, e); + workdir = null; + } + } + + // default -Djava.io.tmpdir + if (workdir == null) { + workdir = System.getProperty("java.io.tmpdir"); + File f = new File(workdir); + f.mkdirs(); + WORKDIR = f; + + logger.info("initialize workdir, -Djava.io.tmpdirs: {}", WORKDIR); + } + } + + public static String getArch() { + String archName = System.getProperty("os.arch", ""); + if (archName.contains("aarch64") || archName.contains("arm64")) { + return "arm"; + } else { + return ""; + } + } + + public static String getLibName(String baseName) { + String osName = OS_NAME; + String archName = ARCH_NAME; + + logger.debug("osName: {}, archName: {}", osName, archName); + + if (osName.contains(WIN)) { + return baseName + ".dll"; + } else if (osName.contains(LINUX)) { + String arch = getArch(); + if ("arm".equals(arch)) { + return "lib" + baseName + "-aarch64" + ".so"; + } + return "lib" + baseName + ".so"; + } else if (osName.contains(MAC)) { + String arch = getArch(); + if ("arm".equals(arch)) { + return "lib" + baseName + "-aarch64" + ".dylib"; + } + return "lib" + baseName + ".dylib"; + } else { + throw new RuntimeException("unrecognized OS: " + osName); + } + } + + public static String getOs() { + String osName = System.getProperty("os.name").toLowerCase(); + if (osName.contains(WIN)) { + return WIN; + } else if (osName.contains(LINUX)) { + return LINUX; + } else if (osName.contains(MAC)) { + return MAC; + } else { + throw new RuntimeException("unrecognized OS: " + osName); + } + } + + public static void loadJniLibrary() { + String libPath = null; + boolean loadLibFromFsOk = false; + try { + // 1. try to load library from filesystem + // -Dcom.webank.wedpr.jni.library.path + libPath = System.getProperty("com.webank.wedpr.jni.library.path"); + if (libPath != null) { + logger.info( + "try to load library -Dcom.webank.wedpr.jni.library.path, libPath: {}", + libPath); + // try to load library from filesystem first + loadLibraryFromFs( + libPath, NATIVE_RESOURCE_LIB_NAME, new File(libPath).isAbsolute()); + loadLibFromFsOk = true; + } + } catch (Exception e0) { + logger.error("unable to load library from fs, libDir: {}, e: ", libPath, e0); + } + + // 2. try to load library from jar + if (!loadLibFromFsOk) { + try { + logger.info("try to load library from jar"); + if (Objects.equals(getOs(), WIN)) { + loadWinDepsLibraryFromJar(); + } + loadLibraryFromJar(NATIVE_RESOURCE_LIB_NAME); + } catch (Exception e1) { + logger.error("unable to load library from fs, e: ", e1); + throw new UnsatisfiedLinkError(e1.toString()); + } + } + } + + public static void loadLibrary(String lib, boolean absolute) { + if (absolute) { + System.load(lib); + } else { + System.loadLibrary(lib); + } + } + + public static void addLibraryDir(String libraryPath) + throws NoSuchFieldException, IllegalAccessException { + Field userPathsField = ClassLoader.class.getDeclaredField("usr_paths"); + userPathsField.setAccessible(true); + String[] paths = (String[]) userPathsField.get(null); + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < paths.length; i++) { + if (libraryPath.equals(paths[i])) { + continue; + } + sb.append(paths[i]).append(File.pathSeparator); + } + sb.append(libraryPath); + System.setProperty("java.library.path", sb.toString()); + logger.info("modify, java.library.path: " + sb.toString()); + final Field sysPathsField = ClassLoader.class.getDeclaredField("sys_paths"); + sysPathsField.setAccessible(true); + sysPathsField.set(null, null); + } + + public static void loadLibraryFromFs(String dir, String libName, boolean absolute) { + String resource = dir + "/" + getLibName(libName); + loadLibrary(resource, absolute); + } + + public static void loadLibraryFromJar(String baseName) + throws IOException, NoSuchFieldException, IllegalAccessException { + String libName = getLibName(baseName); + File tempDir = new File(WORKDIR, String.valueOf(System.nanoTime())); + // create temp dir + tempDir.mkdirs(); + File tempFile = new File(tempDir, libName); + logger.info("tempDir: {}, tempFile: {}", tempDir, tempFile); + + String resource = NATIVE_RESOURCE_HOME + "/" + libName; + try (InputStream is = JniLibLoader.class.getResourceAsStream(resource)) { + Files.copy(is, tempFile.toPath(), StandardCopyOption.REPLACE_EXISTING); + } catch (IOException e) { + try { + tempFile.delete(); + } catch (Exception e0) { + logger.debug("delete temp file error, e: ", e0); + } + logger.error("copy dynamic lib from jar failed, resource: {}, e: ", resource, e); + throw e; + } catch (NullPointerException e) { + throw new FileNotFoundException("Cannot found " + resource + " inside the JAR."); + } + + try { + loadLibrary(tempFile.getAbsolutePath(), true); + } catch (Exception e) { + logger.error("loadLibrary error, resource: {}, e: ", resource, e); + throw e; + } finally { + try { + tempFile.delete(); + tempDir.delete(); + logger.debug("remove temp dir and temp file, dir: {}, file: {}", tempDir, tempFile); + } catch (Exception ignored) { + } + } + } + + public static void loadWinDepsLibraryFromJar() throws IOException, NoSuchFieldException { + File tempDir = new File(WORKDIR, String.valueOf(System.nanoTime())); + tempDir.mkdirs(); + + try (InputStream is = + JniLibLoader.class.getResourceAsStream(NATIVE_WIN_DEPS_DIR + WIN_DEPS_FILE_LIST)) { + if (is == null) { + throw new FileNotFoundException( + "Cannot found " + WIN_DEPS_FILE_LIST + " inside the JAR."); + } + try (Scanner scanner = new Scanner(is)) { + while (scanner.hasNext()) { + String lib = scanner.next(); + File targetFile = new File(tempDir, lib); + logger.info( + "loadWinDepsLibraryFromJar tempDir: {}, targetFile: {}", + tempDir, + targetFile); + try (InputStream fis = + JniLibLoader.class.getResourceAsStream(NATIVE_WIN_DEPS_DIR + lib)) { + if (fis == null) { + throw new FileNotFoundException( + "Cannot found " + lib + " inside the JAR."); + } + Files.copy(fis, targetFile.toPath(), StandardCopyOption.REPLACE_EXISTING); + loadLibrary(targetFile.getAbsolutePath(), true); + } catch (IOException e) { + targetFile.delete(); + } catch (Exception e) { + logger.error( + "loadLibrary error, resource: {}, e: ", + targetFile.getAbsolutePath(), + e); + throw e; + } finally { + try { + targetFile.delete(); + tempDir.delete(); + logger.debug("remove temp dir and temp file, {}", targetFile); + } catch (Exception ignored) { + } + } + } + } + } + } +} diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/common/ObjectMapperFactory.java b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/common/ObjectMapperFactory.java new file mode 100644 index 00000000..a80145e0 --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/common/ObjectMapperFactory.java @@ -0,0 +1,47 @@ +/* + * Copyright 2017-2025 [webank-wedpr] + * + * 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. + * + */ +package com.webank.wedpr.sdk.jni.common; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.ObjectReader; + +/** Factory for managing our ObjectMapper instances. */ +public class ObjectMapperFactory { + + private static final ObjectMapper DEFAULT_OBJECT_MAPPER = new ObjectMapper(); + + static { + configureObjectMapper(); + } + + private ObjectMapperFactory() {} + + public static ObjectMapper getObjectMapper() { + return DEFAULT_OBJECT_MAPPER; + } + + public static ObjectReader getObjectReader() { + return DEFAULT_OBJECT_MAPPER.reader(); + } + + private static void configureObjectMapper() { + ObjectMapperFactory.DEFAULT_OBJECT_MAPPER.configure( + JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true); + ObjectMapperFactory.DEFAULT_OBJECT_MAPPER.configure( + DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + } +} diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/common/WeDPRSDKException.java b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/common/WeDPRSDKException.java new file mode 100644 index 00000000..29515660 --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/common/WeDPRSDKException.java @@ -0,0 +1,41 @@ +/* + * Copyright 2017-2025 [webank-wedpr] + * + * 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. + * + */ + +package com.webank.wedpr.sdk.jni.common; + +import lombok.Getter; + +@Getter +public class WeDPRSDKException extends Exception { + + private long code; + + public WeDPRSDKException(long code, String message) { + super(message); + this.code = code; + } + + public WeDPRSDKException(String message) { + super(message); + } + + public WeDPRSDKException(Throwable cause) { + super(cause); + } + + public WeDPRSDKException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/demo/TransportDemo.java b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/demo/TransportDemo.java new file mode 100644 index 00000000..0305335e --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/demo/TransportDemo.java @@ -0,0 +1,218 @@ +/* + * Copyright 2017-2025 [webank-wedpr] + * + * 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. + * + */ + +package com.webank.wedpr.sdk.jni.demo; + +import com.webank.wedpr.sdk.jni.generated.*; +import com.webank.wedpr.sdk.jni.generated.Error; +import com.webank.wedpr.sdk.jni.transport.IMessage; +import com.webank.wedpr.sdk.jni.transport.TransportConfig; +import com.webank.wedpr.sdk.jni.transport.WeDPRTransport; +import com.webank.wedpr.sdk.jni.transport.handlers.MessageCallback; +import com.webank.wedpr.sdk.jni.transport.handlers.MessageDispatcherCallback; +import com.webank.wedpr.sdk.jni.transport.handlers.MessageErrorCallback; +import com.webank.wedpr.sdk.jni.transport.impl.RouteType; +import com.webank.wedpr.sdk.jni.transport.impl.TransportImpl; +import com.webank.wedpr.sdk.jni.transport.model.ServiceMeta; +import com.webank.wedpr.sdk.jni.transport.model.TransportEndPoint; +import java.util.List; +import lombok.SneakyThrows; +import org.apache.commons.lang3.StringUtils; + +public class TransportDemo { + public static class MessageDispatcherCallbackImpl extends MessageDispatcherCallback { + private final String nodeID; + private final WeDPRTransport weDPRTransport; + + // java -cp 'conf/:lib/*:apps/*' com.webank.wedpr.sdk.jni.demo.TransportDemo agency0Node + // "127.0.0.1" 9020 "ipv4:127.0.0.1:40600,127.0.0.1:40601" "agency1Node" + // java -cp 'conf/:lib/*:apps/*' com.webank.wedpr.sdk.jni.demo.TransportDemo agency1Node + // "127.0.0.1" 9021 "ipv4:127.0.0.1:40620,127.0.0.1:40621" "agency0Node" + public MessageDispatcherCallbackImpl(String nodeID, WeDPRTransport transport) { + this.nodeID = nodeID; + this.weDPRTransport = transport; + } + + @SneakyThrows(Exception.class) + @Override + public void onMessage(IMessage message) { + System.out.println( + "##### Node: " + + nodeID + + " receiveMessage, detail: " + + message.toString() + + ", payload: " + + new String(message.getPayload()) + + "#######"); + // the case access payload multiple times + String payload = new String(message.getPayload()); + String response = "#### hello, response!"; + System.out.println( + "#### sendResponse: " + + response + + ", traceID: " + + message.getHeader().getTraceID() + + ",srcNode: " + + new String(message.getHeader().getSrcNode())); + this.weDPRTransport.asyncSendResponse( + message.getHeader().getSrcNode(), + message.getHeader().getTraceID(), + response.getBytes(), + 0, + new MessageErrorCallbackImpl(this.nodeID)); + } + } + + public static class MessageCallbackImpl extends MessageCallback { + + @Override + public void onMessage( + Error error, IMessage message, SendResponseHandler sendResponseHandler) { + if (error != null && error.errorCode() != 0) { + System.out.println("#### MessageCallbackImpl error: " + error.errorMessage()); + return; + } + System.out.println( + "#### receive response: " + + message + + ", payload: " + + new String(message.getPayload())); + } + } + + public static class MessageErrorCallbackImpl extends MessageErrorCallback { + private final String nodeID; + + public MessageErrorCallbackImpl(String nodeID) { + this.nodeID = nodeID; + } + + @Override + public void onErrorResult(Error error) { + System.out.println( + "##### Node: " + + nodeID + + " MessageErrorCallback, result: " + + error.errorMessage() + + ", code:" + + error.errorCode() + + "######"); + } + } + + public static void main(String[] args) throws Exception { + String nodeID = "testNode"; + if (args.length > 0) { + nodeID = args[0]; + } + TransportConfig transportConfig = new TransportConfig(2, nodeID); + String hostIp = "127.0.0.1"; + if (args.length > 1) { + hostIp = args[1]; + } + int listenPort = 9020; + if (args.length > 2) { + listenPort = Integer.valueOf(args[2]); + } + String listenIp = "0.0.0.0"; + TransportEndPoint endPoint = new TransportEndPoint(hostIp, listenIp, listenPort); + transportConfig.setSelfEndPoint(endPoint); + String serviceName = "Service_Transport_DEMO"; + String entrypPoint = hostIp + ":" + listenPort; + transportConfig.registerService(serviceName, entrypPoint); + + String grpcTarget = "ipv4:127.0.0.1:40600,127.0.0.1:40601"; + if (args.length > 3) { + grpcTarget = args[3]; + } + transportConfig.setGatewayTargets(grpcTarget); + String dstNode = "agency2Node"; + if (args.length > 4) { + dstNode = args[4]; + } + System.out.println("####### transportConfig: " + transportConfig.toString()); + System.out.println("####### dstNode: " + dstNode); + // build the gatewayTarget + WeDPRTransport transport = TransportImpl.build(transportConfig); + + transport.start(); + String component = "WEDPR_COMPONENT_TEST"; + transport.registerComponent(component); + System.out.println("####### start the transport success"); + // send Message to the gateway + String topic = "testTopic"; + MessageDispatcherCallback messageDispatcherCallback = + new MessageDispatcherCallbackImpl(nodeID, transport); + transport.registerTopicHandler(topic, messageDispatcherCallback); + System.out.println("##### register topic success"); + + byte[] dstNodeBytes = dstNode.getBytes(); + // every 2s send a message + Integer i = 0; + String syncTopic = "sync_" + topic; + // update the service information + String serviceName2 = "Service_Transport_DEMO2"; + transport.registerService(serviceName2, entrypPoint); + while (true) { + try { + // fetch the alive service information + List result = + transport.getAliveEntryPoints(serviceName); + System.out.println( + "#### getAliveEntryPoints1, result: " + StringUtils.join(result)); + + List result2 = + transport.getAliveEntryPoints(serviceName2); + System.out.println( + "#### getAliveEntryPoints2, result2: " + StringUtils.join(result2)); + + String payLoad = "testPayload" + i; + // send Message by nodeID + transport.asyncSendMessageByNodeID( + topic, + dstNodeBytes, + payLoad.getBytes(), + 0, + 10000, + new MessageErrorCallbackImpl(nodeID), + new MessageCallbackImpl()); + + // push + String syncPayload = "sync_" + payLoad; + transport.pushByNodeID(syncTopic, dstNodeBytes, 0, syncPayload.getBytes(), 2000); + // pop + IMessage msg = transport.pop(syncTopic, 2000); + System.out.println( + "##### receive msg from " + + syncTopic + + ", detail: " + + msg.toString() + + ", payload: " + + new String(msg.getPayload()) + + "####"); + // selectNodeListByPolicy + List nodeList = + transport.selectNodeListByPolicy( + RouteType.ROUTE_THROUGH_COMPONENT, null, component, null); + System.out.println( + "###### selectNodeListByPolicy result: " + StringUtils.join(nodeList, ",")); + i++; + } catch (Exception e) { + System.out.println("#### exception: " + e.getMessage()); + } + Thread.sleep(2000); + } + } +} diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/EndPoint.java b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/EndPoint.java new file mode 100644 index 00000000..74228f26 --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/EndPoint.java @@ -0,0 +1,91 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (https://www.swig.org). + * Version 4.2.1 + * + * Do not make changes to this file unless you know what you are doing - modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +package com.webank.wedpr.sdk.jni.generated; + +/** the endpoint */ +public class EndPoint { + private transient long swigCPtr; + protected transient boolean swigCMemOwn; + + protected EndPoint(long cPtr, boolean cMemoryOwn) { + swigCMemOwn = cMemoryOwn; + swigCPtr = cPtr; + } + + protected static long getCPtr(EndPoint obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } + + protected static long swigRelease(EndPoint obj) { + long ptr = 0; + if (obj != null) { + if (!obj.swigCMemOwn) + throw new RuntimeException("Cannot release ownership as memory is not owned"); + ptr = obj.swigCPtr; + obj.swigCMemOwn = false; + obj.delete(); + } + return ptr; + } + + @SuppressWarnings({"deprecation", "removal"}) + protected void finalize() { + delete(); + } + + public synchronized void delete() { + if (swigCPtr != 0) { + if (swigCMemOwn) { + swigCMemOwn = false; + wedpr_java_transportJNI.delete_EndPoint(swigCPtr); + } + swigCPtr = 0; + } + } + + public EndPoint() { + this(wedpr_java_transportJNI.new_EndPoint__SWIG_0(), true); + } + + public EndPoint(String host, int port) { + this(wedpr_java_transportJNI.new_EndPoint__SWIG_1(host, port), true); + } + + public String host() { + return wedpr_java_transportJNI.EndPoint_host(swigCPtr, this); + } + + public int port() { + return wedpr_java_transportJNI.EndPoint_port(swigCPtr, this); + } + + public void setHost(String host) { + wedpr_java_transportJNI.EndPoint_setHost(swigCPtr, this, host); + } + + public void setPort(int port) { + wedpr_java_transportJNI.EndPoint_setPort(swigCPtr, this, port); + } + + public void setListenIp(String listenIp) { + wedpr_java_transportJNI.EndPoint_setListenIp(swigCPtr, this, listenIp); + } + + public String entryPoint() { + return wedpr_java_transportJNI.EndPoint_entryPoint(swigCPtr, this); + } + + public String listenEndPoint() { + return wedpr_java_transportJNI.EndPoint_listenEndPoint(swigCPtr, this); + } + + public String listenIp() { + return wedpr_java_transportJNI.EndPoint_listenIp(swigCPtr, this); + } +} diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/Error.java b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/Error.java new file mode 100644 index 00000000..f37f589e --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/Error.java @@ -0,0 +1,100 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (https://www.swig.org). + * Version 4.2.1 + * + * Do not make changes to this file unless you know what you are doing - modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +package com.webank.wedpr.sdk.jni.generated; + +public class Error { + private transient long swigCPtr; + private transient boolean swigCMemOwn; + + protected Error(long cPtr, boolean cMemoryOwn) { + swigCMemOwn = cMemoryOwn; + swigCPtr = cPtr; + } + + protected static long getCPtr(Error obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } + + protected void swigSetCMemOwn(boolean own) { + swigCMemOwn = own; + } + + @SuppressWarnings({"deprecation", "removal"}) + protected void finalize() { + delete(); + } + + public synchronized void delete() { + if (swigCPtr != 0) { + if (swigCMemOwn) { + swigCMemOwn = false; + wedpr_java_transportJNI.delete_Error(swigCPtr); + } + swigCPtr = 0; + } + } + + public static Error buildError( + byte[] func, byte[] file, int line, int errorCode, String errorMessage) { + return new Error( + wedpr_java_transportJNI.Error_buildError__SWIG_0( + func, file, line, errorCode, errorMessage), + true); + } + + public static Error buildError( + byte[] func, byte[] file, int line, int errorCode, String errorMessage, Error prev) { + return new Error( + wedpr_java_transportJNI.Error_buildError__SWIG_1( + func, file, line, errorCode, errorMessage, Error.getCPtr(prev), prev), + true); + } + + public static Error buildError( + byte[] func, + byte[] file, + int line, + int errorCode, + String errorMessage, + SWIGTYPE_p_std__exception prev) { + return new Error( + wedpr_java_transportJNI.Error_buildError__SWIG_2( + func, + file, + line, + errorCode, + errorMessage, + SWIGTYPE_p_std__exception.getCPtr(prev)), + true); + } + + public Error() { + this(wedpr_java_transportJNI.new_Error__SWIG_0(), true); + } + + public Error(long _errorCode, String _errorMessage) { + this(wedpr_java_transportJNI.new_Error__SWIG_1(_errorCode, _errorMessage), true); + } + + public long errorCode() { + return wedpr_java_transportJNI.Error_errorCode(swigCPtr, this); + } + + public String errorMessage() { + return wedpr_java_transportJNI.Error_errorMessage(swigCPtr, this); + } + + public void setErrorCode(long _errorCode) { + wedpr_java_transportJNI.Error_setErrorCode(swigCPtr, this, _errorCode); + } + + public void setErrorMessage(String _errorMessage) { + wedpr_java_transportJNI.Error_setErrorMessage(swigCPtr, this, _errorMessage); + } +} diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/ErrorCallback.java b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/ErrorCallback.java new file mode 100644 index 00000000..3b58fc66 --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/ErrorCallback.java @@ -0,0 +1,66 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (https://www.swig.org). + * Version 4.2.1 + * + * Do not make changes to this file unless you know what you are doing - modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +package com.webank.wedpr.sdk.jni.generated; + +public class ErrorCallback { + private transient long swigCPtr; + private transient boolean swigCMemOwn; + + protected ErrorCallback(long cPtr, boolean cMemoryOwn) { + swigCMemOwn = cMemoryOwn; + swigCPtr = cPtr; + } + + protected static long getCPtr(ErrorCallback obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } + + protected void swigSetCMemOwn(boolean own) { + swigCMemOwn = own; + } + + @SuppressWarnings({"deprecation", "removal"}) + protected void finalize() { + delete(); + } + + public synchronized void delete() { + if (swigCPtr != 0) { + if (swigCMemOwn) { + swigCMemOwn = false; + wedpr_java_transportJNI.delete_ErrorCallback(swigCPtr); + } + swigCPtr = 0; + } + } + + protected void swigDirectorDisconnect() { + swigSetCMemOwn(false); + delete(); + } + + public void swigReleaseOwnership() { + swigSetCMemOwn(false); + wedpr_java_transportJNI.ErrorCallback_change_ownership(this, swigCPtr, false); + } + + public void swigTakeOwnership() { + swigSetCMemOwn(true); + wedpr_java_transportJNI.ErrorCallback_change_ownership(this, swigCPtr, true); + } + + public ErrorCallback() { + this(wedpr_java_transportJNI.new_ErrorCallback(), true); + wedpr_java_transportJNI.ErrorCallback_director_connect(this, swigCPtr, true, true); + } + + public void onError(Error error) { + wedpr_java_transportJNI.ErrorCallback_onError(swigCPtr, this, Error.getCPtr(error), error); + } +} diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/FrontConfig.java b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/FrontConfig.java new file mode 100644 index 00000000..472a74c0 --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/FrontConfig.java @@ -0,0 +1,127 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (https://www.swig.org). + * Version 4.2.1 + * + * Do not make changes to this file unless you know what you are doing - modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +package com.webank.wedpr.sdk.jni.generated; + +public class FrontConfig { + private transient long swigCPtr; + private transient boolean swigCMemOwn; + + protected FrontConfig(long cPtr, boolean cMemoryOwn) { + swigCMemOwn = cMemoryOwn; + swigCPtr = cPtr; + } + + protected static long getCPtr(FrontConfig obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } + + protected void swigSetCMemOwn(boolean own) { + swigCMemOwn = own; + } + + @SuppressWarnings({"deprecation", "removal"}) + protected void finalize() { + delete(); + } + + public synchronized void delete() { + if (swigCPtr != 0) { + if (swigCMemOwn) { + swigCMemOwn = false; + wedpr_java_transportJNI.delete_FrontConfig(swigCPtr); + } + swigCPtr = 0; + } + } + + public int threadPoolSize() { + return wedpr_java_transportJNI.FrontConfig_threadPoolSize(swigCPtr, this); + } + + public void setThreadPoolSize(int threadPoolSize) { + wedpr_java_transportJNI.FrontConfig_setThreadPoolSize(swigCPtr, this, threadPoolSize); + } + + public String nodeID() { + return wedpr_java_transportJNI.FrontConfig_nodeID(swigCPtr, this); + } + + public void setNodeID(String nodeID) { + wedpr_java_transportJNI.FrontConfig_setNodeID(swigCPtr, this, nodeID); + } + + public EndPoint selfEndPoint() { + return new EndPoint( + wedpr_java_transportJNI.FrontConfig_selfEndPoint(swigCPtr, this), false); + } + + public EndPoint mutableSelfEndPoint() { + return new EndPoint( + wedpr_java_transportJNI.FrontConfig_mutableSelfEndPoint(swigCPtr, this), false); + } + + public void setSelfEndPoint(EndPoint endPoint) { + wedpr_java_transportJNI.FrontConfig_setSelfEndPoint( + swigCPtr, this, EndPoint.getCPtr(endPoint), endPoint); + } + + public void setGatewayGrpcTarget(String gatewayGrpcTarget) { + wedpr_java_transportJNI.FrontConfig_setGatewayGrpcTarget(swigCPtr, this, gatewayGrpcTarget); + } + + public String gatewayGrpcTarget() { + return wedpr_java_transportJNI.FrontConfig_gatewayGrpcTarget(swigCPtr, this); + } + + public void setGrpcConfig(GrpcConfig grpcConfig) { + wedpr_java_transportJNI.FrontConfig_setGrpcConfig( + swigCPtr, this, GrpcConfig.getCPtr(grpcConfig), grpcConfig); + } + + public GrpcConfig grpcConfig() { + long cPtr = wedpr_java_transportJNI.FrontConfig_grpcConfig(swigCPtr, this); + return (cPtr == 0) ? null : new GrpcConfig(cPtr, true); + } + + public INodeInfo generateNodeInfo() { + long cPtr = wedpr_java_transportJNI.FrontConfig_generateNodeInfo(swigCPtr, this); + return (cPtr == 0) ? null : new INodeInfo(cPtr, true); + } + + public StringVec getComponents() { + return new StringVec( + wedpr_java_transportJNI.FrontConfig_getComponents(swigCPtr, this), false); + } + + public void setComponents(StringVec components) { + wedpr_java_transportJNI.FrontConfig_setComponents( + swigCPtr, this, StringVec.getCPtr(components), components); + } + + public void addComponent(String component) { + wedpr_java_transportJNI.FrontConfig_addComponent(swigCPtr, this, component); + } + + public StringVec mutableComponents() { + return new StringVec( + wedpr_java_transportJNI.FrontConfig_mutableComponents(swigCPtr, this), false); + } + + public String meta() { + return wedpr_java_transportJNI.FrontConfig_meta(swigCPtr, this); + } + + public void setMeta(String meta) { + wedpr_java_transportJNI.FrontConfig_setMeta(swigCPtr, this, meta); + } + + public void disOwnMemory() { + swigSetCMemOwn(false); + } +} diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/FrontConfigBuilder.java b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/FrontConfigBuilder.java new file mode 100644 index 00000000..bbdcb1a0 --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/FrontConfigBuilder.java @@ -0,0 +1,62 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (https://www.swig.org). + * Version 4.2.1 + * + * Do not make changes to this file unless you know what you are doing - modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +package com.webank.wedpr.sdk.jni.generated; + +public class FrontConfigBuilder { + private transient long swigCPtr; + protected transient boolean swigCMemOwn; + + protected FrontConfigBuilder(long cPtr, boolean cMemoryOwn) { + swigCMemOwn = cMemoryOwn; + swigCPtr = cPtr; + } + + protected static long getCPtr(FrontConfigBuilder obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } + + protected static long swigRelease(FrontConfigBuilder obj) { + long ptr = 0; + if (obj != null) { + if (!obj.swigCMemOwn) + throw new RuntimeException("Cannot release ownership as memory is not owned"); + ptr = obj.swigCPtr; + obj.swigCMemOwn = false; + obj.delete(); + } + return ptr; + } + + @SuppressWarnings({"deprecation", "removal"}) + protected void finalize() { + delete(); + } + + public synchronized void delete() { + if (swigCPtr != 0) { + if (swigCMemOwn) { + swigCMemOwn = false; + wedpr_java_transportJNI.delete_FrontConfigBuilder(swigCPtr); + } + swigCPtr = 0; + } + } + + public FrontConfig build() { + long cPtr = wedpr_java_transportJNI.FrontConfigBuilder_build__SWIG_0(swigCPtr, this); + return (cPtr == 0) ? null : new FrontConfig(cPtr, true); + } + + public FrontConfig build(int threadPoolSize, String nodeID) { + long cPtr = + wedpr_java_transportJNI.FrontConfigBuilder_build__SWIG_1( + swigCPtr, this, threadPoolSize, nodeID); + return (cPtr == 0) ? null : new FrontConfig(cPtr, true); + } +} diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/FrontMsgExtFlag.java b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/FrontMsgExtFlag.java new file mode 100644 index 00000000..5cdc7443 --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/FrontMsgExtFlag.java @@ -0,0 +1,54 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (https://www.swig.org). + * Version 4.2.1 + * + * Do not make changes to this file unless you know what you are doing - modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +package com.webank.wedpr.sdk.jni.generated; + +public final class FrontMsgExtFlag { + public static final FrontMsgExtFlag Response = + new FrontMsgExtFlag("Response", wedpr_java_transportJNI.FrontMsgExtFlag_Response_get()); + + public final int swigValue() { + return swigValue; + } + + public String toString() { + return swigName; + } + + public static FrontMsgExtFlag swigToEnum(int swigValue) { + if (swigValue < swigValues.length + && swigValue >= 0 + && swigValues[swigValue].swigValue == swigValue) return swigValues[swigValue]; + for (int i = 0; i < swigValues.length; i++) + if (swigValues[i].swigValue == swigValue) return swigValues[i]; + throw new IllegalArgumentException( + "No enum " + FrontMsgExtFlag.class + " with value " + swigValue); + } + + private FrontMsgExtFlag(String swigName) { + this.swigName = swigName; + this.swigValue = swigNext++; + } + + private FrontMsgExtFlag(String swigName, int swigValue) { + this.swigName = swigName; + this.swigValue = swigValue; + swigNext = swigValue + 1; + } + + private FrontMsgExtFlag(String swigName, FrontMsgExtFlag swigEnum) { + this.swigName = swigName; + this.swigValue = swigEnum.swigValue; + swigNext = this.swigValue + 1; + } + + private static FrontMsgExtFlag[] swigValues = {Response}; + private static int swigNext = 0; + private final int swigValue; + private final String swigName; +} diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/GetPeersInfoHandler.java b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/GetPeersInfoHandler.java new file mode 100644 index 00000000..5a73e448 --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/GetPeersInfoHandler.java @@ -0,0 +1,67 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (https://www.swig.org). + * Version 4.2.1 + * + * Do not make changes to this file unless you know what you are doing - modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +package com.webank.wedpr.sdk.jni.generated; + +public class GetPeersInfoHandler { + private transient long swigCPtr; + private transient boolean swigCMemOwn; + + protected GetPeersInfoHandler(long cPtr, boolean cMemoryOwn) { + swigCMemOwn = cMemoryOwn; + swigCPtr = cPtr; + } + + protected static long getCPtr(GetPeersInfoHandler obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } + + protected void swigSetCMemOwn(boolean own) { + swigCMemOwn = own; + } + + @SuppressWarnings({"deprecation", "removal"}) + protected void finalize() { + delete(); + } + + public synchronized void delete() { + if (swigCPtr != 0) { + if (swigCMemOwn) { + swigCMemOwn = false; + wedpr_java_transportJNI.delete_GetPeersInfoHandler(swigCPtr); + } + swigCPtr = 0; + } + } + + protected void swigDirectorDisconnect() { + swigSetCMemOwn(false); + delete(); + } + + public void swigReleaseOwnership() { + swigSetCMemOwn(false); + wedpr_java_transportJNI.GetPeersInfoHandler_change_ownership(this, swigCPtr, false); + } + + public void swigTakeOwnership() { + swigSetCMemOwn(true); + wedpr_java_transportJNI.GetPeersInfoHandler_change_ownership(this, swigCPtr, true); + } + + public GetPeersInfoHandler() { + this(wedpr_java_transportJNI.new_GetPeersInfoHandler(), true); + wedpr_java_transportJNI.GetPeersInfoHandler_director_connect(this, swigCPtr, true, true); + } + + public void onPeersInfo(Error e, String peersInfo) { + wedpr_java_transportJNI.GetPeersInfoHandler_onPeersInfo( + swigCPtr, this, Error.getCPtr(e), e, peersInfo); + } +} diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/GrpcConfig.java b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/GrpcConfig.java new file mode 100644 index 00000000..5860ec62 --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/GrpcConfig.java @@ -0,0 +1,100 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (https://www.swig.org). + * Version 4.2.1 + * + * Do not make changes to this file unless you know what you are doing - modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +package com.webank.wedpr.sdk.jni.generated; + +public class GrpcConfig { + private transient long swigCPtr; + private transient boolean swigCMemOwn; + + protected GrpcConfig(long cPtr, boolean cMemoryOwn) { + swigCMemOwn = cMemoryOwn; + swigCPtr = cPtr; + } + + protected static long getCPtr(GrpcConfig obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } + + protected void swigSetCMemOwn(boolean own) { + swigCMemOwn = own; + } + + public synchronized void delete() { + if (swigCPtr != 0) { + if (swigCMemOwn) { + swigCMemOwn = false; + throw new UnsupportedOperationException( + "C++ destructor does not have public access"); + } + swigCPtr = 0; + } + } + + public GrpcConfig() { + this(wedpr_java_transportJNI.new_GrpcConfig(), true); + } + + public String loadBalancePolicy() { + return wedpr_java_transportJNI.GrpcConfig_loadBalancePolicy(swigCPtr, this); + } + + public void setLoadBalancePolicy(String loadBalancePolicy) { + wedpr_java_transportJNI.GrpcConfig_setLoadBalancePolicy(swigCPtr, this, loadBalancePolicy); + } + + public boolean enableHealthCheck() { + return wedpr_java_transportJNI.GrpcConfig_enableHealthCheck(swigCPtr, this); + } + + public void setEnableHealthCheck(boolean enableHealthCheck) { + wedpr_java_transportJNI.GrpcConfig_setEnableHealthCheck(swigCPtr, this, enableHealthCheck); + } + + public void setEnableDnslookup(boolean enableDnslookup) { + wedpr_java_transportJNI.GrpcConfig_setEnableDnslookup(swigCPtr, this, enableDnslookup); + } + + public boolean enableDnslookup() { + return wedpr_java_transportJNI.GrpcConfig_enableDnslookup(swigCPtr, this); + } + + public java.math.BigInteger maxSendMessageSize() { + return wedpr_java_transportJNI.GrpcConfig_maxSendMessageSize(swigCPtr, this); + } + + public java.math.BigInteger maxReceivedMessageSize() { + return wedpr_java_transportJNI.GrpcConfig_maxReceivedMessageSize(swigCPtr, this); + } + + public void setMaxSendMessageSize(java.math.BigInteger maxSendMessageSize) { + wedpr_java_transportJNI.GrpcConfig_setMaxSendMessageSize( + swigCPtr, this, maxSendMessageSize); + } + + public void setMaxReceivedMessageSize(java.math.BigInteger maxReceivedMessageSize) { + wedpr_java_transportJNI.GrpcConfig_setMaxReceivedMessageSize( + swigCPtr, this, maxReceivedMessageSize); + } + + public int compressAlgorithm() { + return wedpr_java_transportJNI.GrpcConfig_compressAlgorithm(swigCPtr, this); + } + + public void setCompressAlgorithm(int compressAlgorithm) { + wedpr_java_transportJNI.GrpcConfig_setCompressAlgorithm(swigCPtr, this, compressAlgorithm); + } + + public java.math.BigInteger maxMsgSize() { + return wedpr_java_transportJNI.GrpcConfig_maxMsgSize(swigCPtr, this); + } + + public void setMaxMsgSize(java.math.BigInteger maxMsgSize) { + wedpr_java_transportJNI.GrpcConfig_setMaxMsgSize(swigCPtr, this, maxMsgSize); + } +} diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/GrpcServerConfig.java b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/GrpcServerConfig.java new file mode 100644 index 00000000..3f138170 --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/GrpcServerConfig.java @@ -0,0 +1,90 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (https://www.swig.org). + * Version 4.2.1 + * + * Do not make changes to this file unless you know what you are doing - modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +package com.webank.wedpr.sdk.jni.generated; + +public class GrpcServerConfig { + private transient long swigCPtr; + protected transient boolean swigCMemOwn; + + protected GrpcServerConfig(long cPtr, boolean cMemoryOwn) { + swigCMemOwn = cMemoryOwn; + swigCPtr = cPtr; + } + + protected static long getCPtr(GrpcServerConfig obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } + + protected static long swigRelease(GrpcServerConfig obj) { + long ptr = 0; + if (obj != null) { + if (!obj.swigCMemOwn) + throw new RuntimeException("Cannot release ownership as memory is not owned"); + ptr = obj.swigCPtr; + obj.swigCMemOwn = false; + obj.delete(); + } + return ptr; + } + + public synchronized void delete() { + if (swigCPtr != 0) { + if (swigCMemOwn) { + swigCMemOwn = false; + throw new UnsupportedOperationException( + "C++ destructor does not have public access"); + } + swigCPtr = 0; + } + } + + public GrpcServerConfig() { + this(wedpr_java_transportJNI.new_GrpcServerConfig__SWIG_0(), true); + } + + public GrpcServerConfig(EndPoint endPoint, boolean enableHealthCheck) { + this( + wedpr_java_transportJNI.new_GrpcServerConfig__SWIG_1( + EndPoint.getCPtr(endPoint), endPoint, enableHealthCheck), + true); + } + + public String listenEndPoint() { + return wedpr_java_transportJNI.GrpcServerConfig_listenEndPoint(swigCPtr, this); + } + + public void setEndPoint(EndPoint endPoint) { + wedpr_java_transportJNI.GrpcServerConfig_setEndPoint( + swigCPtr, this, EndPoint.getCPtr(endPoint), endPoint); + } + + public void setEnableHealthCheck(boolean enableHealthCheck) { + wedpr_java_transportJNI.GrpcServerConfig_setEnableHealthCheck( + swigCPtr, this, enableHealthCheck); + } + + public EndPoint endPoint() { + return new EndPoint( + wedpr_java_transportJNI.GrpcServerConfig_endPoint(swigCPtr, this), false); + } + + public EndPoint mutableEndPoint() { + return new EndPoint( + wedpr_java_transportJNI.GrpcServerConfig_mutableEndPoint(swigCPtr, this), false); + } + + public boolean enableHealthCheck() { + return wedpr_java_transportJNI.GrpcServerConfig_enableHealthCheck(swigCPtr, this); + } + + public GrpcConfig grpcConfig() { + long cPtr = wedpr_java_transportJNI.GrpcServerConfig_grpcConfig(swigCPtr, this); + return (cPtr == 0) ? null : new GrpcConfig(cPtr, true); + } +} diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/IFront.java b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/IFront.java new file mode 100644 index 00000000..a401a47e --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/IFront.java @@ -0,0 +1,212 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (https://www.swig.org). + * Version 4.2.1 + * + * Do not make changes to this file unless you know what you are doing - modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +package com.webank.wedpr.sdk.jni.generated; + +public class IFront extends IFrontClient { + private transient long swigCPtr; + private transient boolean swigCMemOwnDerived; + + protected IFront(long cPtr, boolean cMemoryOwn) { + super(wedpr_java_transportJNI.IFront_SWIGSmartPtrUpcast(cPtr), true); + swigCMemOwnDerived = cMemoryOwn; + swigCPtr = cPtr; + } + + protected static long getCPtr(IFront obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } + + protected void swigSetCMemOwn(boolean own) { + swigCMemOwnDerived = own; + super.swigSetCMemOwn(own); + } + + @SuppressWarnings({"deprecation", "removal"}) + protected void finalize() { + delete(); + } + + public synchronized void delete() { + if (swigCPtr != 0) { + if (swigCMemOwnDerived) { + swigCMemOwnDerived = false; + wedpr_java_transportJNI.delete_IFront(swigCPtr); + } + swigCPtr = 0; + } + super.delete(); + } + + /** + * start the IFront
+ *
+ */ + public void start() { + wedpr_java_transportJNI.IFront_start(swigCPtr, this); + } + + /** + * stop the IFront
+ *
+ */ + public void stop() { + wedpr_java_transportJNI.IFront_stop(swigCPtr, this); + } + + public void register_topic_handler(String topic, MessageDispatcherHandler callback) { + wedpr_java_transportJNI.IFront_register_topic_handler( + swigCPtr, this, topic, MessageDispatcherHandler.getCPtr(callback), callback); + } + + public void register_msg_handler(String componentType, MessageDispatcherHandler callback) { + wedpr_java_transportJNI.IFront_register_msg_handler( + swigCPtr, + this, + componentType, + MessageDispatcherHandler.getCPtr(callback), + callback); + } + + public void async_send_message( + int routeType, + MessageOptionalHeader routeInfo, + byte[] payload, + java.math.BigInteger payloadSize, + int seq, + int timeout, + ErrorCallback errorCallback, + IMessageHandler msgHandler) { + wedpr_java_transportJNI.IFront_async_send_message( + swigCPtr, + this, + routeType, + MessageOptionalHeader.getCPtr(routeInfo), + routeInfo, + payload, + payloadSize, + seq, + timeout, + ErrorCallback.getCPtr(errorCallback), + errorCallback, + IMessageHandler.getCPtr(msgHandler), + msgHandler); + } + + public void async_send_response( + byte[] dstNode, + java.math.BigInteger dstNodeSize, + String traceID, + byte[] payload, + java.math.BigInteger payloadSize, + int seq, + ErrorCallback errorCallback) { + wedpr_java_transportJNI.IFront_async_send_response( + swigCPtr, + this, + dstNode, + dstNodeSize, + traceID, + payload, + payloadSize, + seq, + ErrorCallback.getCPtr(errorCallback), + errorCallback); + } + + public Error push_msg( + int routeType, + MessageOptionalHeader routeInfo, + byte[] payload, + java.math.BigInteger payloadSize, + int seq, + int timeout) { + long cPtr = + wedpr_java_transportJNI.IFront_push_msg( + swigCPtr, + this, + routeType, + MessageOptionalHeader.getCPtr(routeInfo), + routeInfo, + payload, + payloadSize, + seq, + timeout); + return (cPtr == 0) ? null : new Error(cPtr, true); + } + + public Message pop(String topic, int timeoutMs) { + long cPtr = wedpr_java_transportJNI.IFront_pop(swigCPtr, this, topic, timeoutMs); + return (cPtr == 0) ? null : new Message(cPtr, true); + } + + public Message peek(String topic) { + long cPtr = wedpr_java_transportJNI.IFront_peek(swigCPtr, this, topic); + return (cPtr == 0) ? null : new Message(cPtr, true); + } + + public void asyncGetPeers(GetPeersInfoHandler getPeersCallback) { + wedpr_java_transportJNI.IFront_asyncGetPeers( + swigCPtr, this, GetPeersInfoHandler.getCPtr(getPeersCallback), getPeersCallback); + } + + public INodeInfo nodeInfo() { + long cPtr = wedpr_java_transportJNI.IFront_nodeInfo(swigCPtr, this); + return (cPtr == 0) ? null : new INodeInfo(cPtr, true); + } + + /** + * register the topic
+ *
+ * + * @param topic the topic to register + */ + public Error registerTopic(String topic) { + long cPtr = wedpr_java_transportJNI.IFront_registerTopic(swigCPtr, this, topic); + return (cPtr == 0) ? null : new Error(cPtr, true); + } + + /** + * unRegister the topic
+ *
+ * + * @param topic the topic to unregister + */ + public Error unRegisterTopic(String topic) { + long cPtr = wedpr_java_transportJNI.IFront_unRegisterTopic(swigCPtr, this, topic); + return (cPtr == 0) ? null : new Error(cPtr, true); + } + + public void registerComponent(String component) { + wedpr_java_transportJNI.IFront_registerComponent(swigCPtr, this, component); + } + + public void unRegisterComponent(String component) { + wedpr_java_transportJNI.IFront_unRegisterComponent(swigCPtr, this, component); + } + + public void updateMetaInfo(String meta) { + wedpr_java_transportJNI.IFront_updateMetaInfo(swigCPtr, this, meta); + } + + public StringVec selectNodesByRoutePolicy(short routeType, MessageOptionalHeader routeInfo) { + return new StringVec( + wedpr_java_transportJNI.IFront_selectNodesByRoutePolicy( + swigCPtr, + this, + routeType, + MessageOptionalHeader.getCPtr(routeInfo), + routeInfo), + true); + } + + public INodeDiscovery getNodeDiscovery() { + long cPtr = wedpr_java_transportJNI.IFront_getNodeDiscovery(swigCPtr, this); + return (cPtr == 0) ? null : new INodeDiscovery(cPtr, true); + } +} diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/IFrontBuilder.java b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/IFrontBuilder.java new file mode 100644 index 00000000..23e0fdab --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/IFrontBuilder.java @@ -0,0 +1,64 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (https://www.swig.org). + * Version 4.2.1 + * + * Do not make changes to this file unless you know what you are doing - modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +package com.webank.wedpr.sdk.jni.generated; + +public class IFrontBuilder { + private transient long swigCPtr; + protected transient boolean swigCMemOwn; + + protected IFrontBuilder(long cPtr, boolean cMemoryOwn) { + swigCMemOwn = cMemoryOwn; + swigCPtr = cPtr; + } + + protected static long getCPtr(IFrontBuilder obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } + + protected static long swigRelease(IFrontBuilder obj) { + long ptr = 0; + if (obj != null) { + if (!obj.swigCMemOwn) + throw new RuntimeException("Cannot release ownership as memory is not owned"); + ptr = obj.swigCPtr; + obj.swigCMemOwn = false; + obj.delete(); + } + return ptr; + } + + @SuppressWarnings({"deprecation", "removal"}) + protected void finalize() { + delete(); + } + + public synchronized void delete() { + if (swigCPtr != 0) { + if (swigCMemOwn) { + swigCMemOwn = false; + wedpr_java_transportJNI.delete_IFrontBuilder(swigCPtr); + } + swigCPtr = 0; + } + } + + public IFrontClient buildClient( + String endPoint, + SWIGTYPE_p_std__functionT_void_fF_t onUnHealthHandler, + boolean removeHandlerOnUnhealth) { + long cPtr = + wedpr_java_transportJNI.IFrontBuilder_buildClient( + swigCPtr, + this, + endPoint, + SWIGTYPE_p_std__functionT_void_fF_t.getCPtr(onUnHealthHandler), + removeHandlerOnUnhealth); + return (cPtr == 0) ? null : new IFrontClient(cPtr, true); + } +} diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/IFrontClient.java b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/IFrontClient.java new file mode 100644 index 00000000..ac777ec8 --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/IFrontClient.java @@ -0,0 +1,60 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (https://www.swig.org). + * Version 4.2.1 + * + * Do not make changes to this file unless you know what you are doing - modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +package com.webank.wedpr.sdk.jni.generated; + +public class IFrontClient { + private transient long swigCPtr; + private transient boolean swigCMemOwn; + + protected IFrontClient(long cPtr, boolean cMemoryOwn) { + swigCMemOwn = cMemoryOwn; + swigCPtr = cPtr; + } + + protected static long getCPtr(IFrontClient obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } + + protected void swigSetCMemOwn(boolean own) { + swigCMemOwn = own; + } + + @SuppressWarnings({"deprecation", "removal"}) + protected void finalize() { + delete(); + } + + public synchronized void delete() { + if (swigCPtr != 0) { + if (swigCMemOwn) { + swigCMemOwn = false; + wedpr_java_transportJNI.delete_IFrontClient(swigCPtr); + } + swigCPtr = 0; + } + } + + /** + * : receive message from gateway, call by gateway
+ *
+ * + * @return void + */ + public void onReceiveMessage( + Message _msg, + SWIGTYPE_p_std__functionT_void_fstd__shared_ptrT_bcos__Error_tF_t _callback) { + wedpr_java_transportJNI.IFrontClient_onReceiveMessage( + swigCPtr, + this, + Message.getCPtr(_msg), + _msg, + SWIGTYPE_p_std__functionT_void_fstd__shared_ptrT_bcos__Error_tF_t.getCPtr( + _callback)); + } +} diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/IMessageHandler.java b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/IMessageHandler.java new file mode 100644 index 00000000..260ce3a7 --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/IMessageHandler.java @@ -0,0 +1,74 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (https://www.swig.org). + * Version 4.2.1 + * + * Do not make changes to this file unless you know what you are doing - modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +package com.webank.wedpr.sdk.jni.generated; + +public class IMessageHandler { + private transient long swigCPtr; + private transient boolean swigCMemOwn; + + protected IMessageHandler(long cPtr, boolean cMemoryOwn) { + swigCMemOwn = cMemoryOwn; + swigCPtr = cPtr; + } + + protected static long getCPtr(IMessageHandler obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } + + protected void swigSetCMemOwn(boolean own) { + swigCMemOwn = own; + } + + @SuppressWarnings({"deprecation", "removal"}) + protected void finalize() { + delete(); + } + + public synchronized void delete() { + if (swigCPtr != 0) { + if (swigCMemOwn) { + swigCMemOwn = false; + wedpr_java_transportJNI.delete_IMessageHandler(swigCPtr); + } + swigCPtr = 0; + } + } + + protected void swigDirectorDisconnect() { + swigSetCMemOwn(false); + delete(); + } + + public void swigReleaseOwnership() { + swigSetCMemOwn(false); + wedpr_java_transportJNI.IMessageHandler_change_ownership(this, swigCPtr, false); + } + + public void swigTakeOwnership() { + swigSetCMemOwn(true); + wedpr_java_transportJNI.IMessageHandler_change_ownership(this, swigCPtr, true); + } + + public IMessageHandler() { + this(wedpr_java_transportJNI.new_IMessageHandler(), true); + wedpr_java_transportJNI.IMessageHandler_director_connect(this, swigCPtr, true, true); + } + + public void onMessage(Error e, Message msg, SendResponseHandler sendResponseHandler) { + wedpr_java_transportJNI.IMessageHandler_onMessage( + swigCPtr, + this, + Error.getCPtr(e), + e, + Message.getCPtr(msg), + msg, + SendResponseHandler.getCPtr(sendResponseHandler), + sendResponseHandler); + } +} diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/INodeDiscovery.java b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/INodeDiscovery.java new file mode 100644 index 00000000..2b35ff23 --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/INodeDiscovery.java @@ -0,0 +1,47 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (https://www.swig.org). + * Version 4.2.1 + * + * Do not make changes to this file unless you know what you are doing - modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +package com.webank.wedpr.sdk.jni.generated; + +public class INodeDiscovery { + private transient long swigCPtr; + private transient boolean swigCMemOwn; + + protected INodeDiscovery(long cPtr, boolean cMemoryOwn) { + swigCMemOwn = cMemoryOwn; + swigCPtr = cPtr; + } + + protected static long getCPtr(INodeDiscovery obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } + + protected void swigSetCMemOwn(boolean own) { + swigCMemOwn = own; + } + + @SuppressWarnings({"deprecation", "removal"}) + protected void finalize() { + delete(); + } + + public synchronized void delete() { + if (swigCPtr != 0) { + if (swigCMemOwn) { + swigCMemOwn = false; + wedpr_java_transportJNI.delete_INodeDiscovery(swigCPtr); + } + swigCPtr = 0; + } + } + + public NodeInfoVec getAliveNodeList() { + return new NodeInfoVec( + wedpr_java_transportJNI.INodeDiscovery_getAliveNodeList(swigCPtr, this), true); + } +} diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/INodeInfo.java b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/INodeInfo.java new file mode 100644 index 00000000..f7b791c9 --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/INodeInfo.java @@ -0,0 +1,85 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (https://www.swig.org). + * Version 4.2.1 + * + * Do not make changes to this file unless you know what you are doing - modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +package com.webank.wedpr.sdk.jni.generated; + +public class INodeInfo { + private transient long swigCPtr; + private transient boolean swigCMemOwn; + + protected INodeInfo(long cPtr, boolean cMemoryOwn) { + swigCMemOwn = cMemoryOwn; + swigCPtr = cPtr; + } + + protected static long getCPtr(INodeInfo obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } + + protected void swigSetCMemOwn(boolean own) { + swigCMemOwn = own; + } + + @SuppressWarnings({"deprecation", "removal"}) + protected void finalize() { + delete(); + } + + public synchronized void delete() { + if (swigCPtr != 0) { + if (swigCMemOwn) { + swigCMemOwn = false; + wedpr_java_transportJNI.delete_INodeInfo(swigCPtr); + } + swigCPtr = 0; + } + } + + public String endPoint() { + return wedpr_java_transportJNI.INodeInfo_endPoint(swigCPtr, this); + } + + public SWIGTYPE_p_bcos__bytesConstRef nodeID() { + return new SWIGTYPE_p_bcos__bytesConstRef( + wedpr_java_transportJNI.INodeInfo_nodeID(swigCPtr, this), true); + } + + public void setNodeID(SWIGTYPE_p_bcos__bytesConstRef nodeID) { + wedpr_java_transportJNI.INodeInfo_setNodeID( + swigCPtr, this, SWIGTYPE_p_bcos__bytesConstRef.getCPtr(nodeID)); + } + + public void setEndPoint(String endPoint) { + wedpr_java_transportJNI.INodeInfo_setEndPoint(swigCPtr, this, endPoint); + } + + public boolean addComponent(String component) { + return wedpr_java_transportJNI.INodeInfo_addComponent(swigCPtr, this, component); + } + + public boolean eraseComponent(String component) { + return wedpr_java_transportJNI.INodeInfo_eraseComponent(swigCPtr, this, component); + } + + public boolean componentExist(String component) { + return wedpr_java_transportJNI.INodeInfo_componentExist(swigCPtr, this, component); + } + + public StringVec copiedComponents() { + return new StringVec( + wedpr_java_transportJNI.INodeInfo_copiedComponents(swigCPtr, this), true); + } + + public String meta() { + return wedpr_java_transportJNI.INodeInfo_meta(swigCPtr, this); + } + + public void setMeta(String meta) { + wedpr_java_transportJNI.INodeInfo_setMeta(swigCPtr, this, meta); + } +} diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/InputBuffer.java b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/InputBuffer.java new file mode 100644 index 00000000..d07438aa --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/InputBuffer.java @@ -0,0 +1,72 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (https://www.swig.org). + * Version 4.2.1 + * + * Do not make changes to this file unless you know what you are doing - modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +package com.webank.wedpr.sdk.jni.generated; + +public class InputBuffer { + private transient long swigCPtr; + protected transient boolean swigCMemOwn; + + protected InputBuffer(long cPtr, boolean cMemoryOwn) { + swigCMemOwn = cMemoryOwn; + swigCPtr = cPtr; + } + + protected static long getCPtr(InputBuffer obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } + + protected static long swigRelease(InputBuffer obj) { + long ptr = 0; + if (obj != null) { + if (!obj.swigCMemOwn) + throw new RuntimeException("Cannot release ownership as memory is not owned"); + ptr = obj.swigCPtr; + obj.swigCMemOwn = false; + obj.delete(); + } + return ptr; + } + + @SuppressWarnings({"deprecation", "removal"}) + protected void finalize() { + delete(); + } + + public synchronized void delete() { + if (swigCPtr != 0) { + if (swigCMemOwn) { + swigCMemOwn = false; + wedpr_java_transportJNI.delete_InputBuffer(swigCPtr); + } + swigCPtr = 0; + } + } + + public void setData(SWIGTYPE_p_unsigned_char value) { + wedpr_java_transportJNI.InputBuffer_data_set( + swigCPtr, this, SWIGTYPE_p_unsigned_char.getCPtr(value)); + } + + public SWIGTYPE_p_unsigned_char getData() { + long cPtr = wedpr_java_transportJNI.InputBuffer_data_get(swigCPtr, this); + return (cPtr == 0) ? null : new SWIGTYPE_p_unsigned_char(cPtr, false); + } + + public void setLen(java.math.BigInteger value) { + wedpr_java_transportJNI.InputBuffer_len_set(swigCPtr, this, value); + } + + public java.math.BigInteger getLen() { + return wedpr_java_transportJNI.InputBuffer_len_get(swigCPtr, this); + } + + public InputBuffer() { + this(wedpr_java_transportJNI.new_InputBuffer(), true); + } +} diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/Message.java b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/Message.java new file mode 100644 index 00000000..ab64b268 --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/Message.java @@ -0,0 +1,134 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (https://www.swig.org). + * Version 4.2.1 + * + * Do not make changes to this file unless you know what you are doing - modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +package com.webank.wedpr.sdk.jni.generated; + +public class Message { + private transient long swigCPtr; + private transient boolean swigCMemOwn; + + protected Message(long cPtr, boolean cMemoryOwn) { + swigCMemOwn = cMemoryOwn; + swigCPtr = cPtr; + } + + protected static long getCPtr(Message obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } + + protected void swigSetCMemOwn(boolean own) { + swigCMemOwn = own; + } + + @SuppressWarnings({"deprecation", "removal"}) + protected void finalize() { + delete(); + } + + public synchronized void delete() { + if (swigCPtr != 0) { + if (swigCMemOwn) { + swigCMemOwn = false; + wedpr_java_transportJNI.delete_Message(swigCPtr); + } + swigCPtr = 0; + } + } + + public MessageHeader header() { + long cPtr = wedpr_java_transportJNI.Message_header(swigCPtr, this); + return (cPtr == 0) ? null : new MessageHeader(cPtr, true); + } + + public void setHeader(MessageHeader header) { + wedpr_java_transportJNI.Message_setHeader( + swigCPtr, this, MessageHeader.getCPtr(header), header); + } + + /** the overloaed implementation === */ + public int version() { + return wedpr_java_transportJNI.Message_version(swigCPtr, this); + } + + public void setVersion(int version) { + wedpr_java_transportJNI.Message_setVersion(swigCPtr, this, version); + } + + public int packetType() { + return wedpr_java_transportJNI.Message_packetType(swigCPtr, this); + } + + public void setPacketType(int packetType) { + wedpr_java_transportJNI.Message_setPacketType(swigCPtr, this, packetType); + } + + public String seq() { + return wedpr_java_transportJNI.Message_seq(swigCPtr, this); + } + + public void setSeq(String traceID) { + wedpr_java_transportJNI.Message_setSeq(swigCPtr, this, traceID); + } + + public int ext() { + return wedpr_java_transportJNI.Message_ext(swigCPtr, this); + } + + public void setExt(int ext) { + wedpr_java_transportJNI.Message_setExt(swigCPtr, this, ext); + } + + public boolean isRespPacket() { + return wedpr_java_transportJNI.Message_isRespPacket(swigCPtr, this); + } + + public void setRespPacket() { + wedpr_java_transportJNI.Message_setRespPacket(swigCPtr, this); + } + + public void setPayload(ubytes _payload) { + wedpr_java_transportJNI.Message_setPayload( + swigCPtr, this, ubytes.getCPtr(_payload), _payload); + } + + public byte[] payloadBuffer() { + return wedpr_java_transportJNI.Message_payloadBuffer(swigCPtr, this); + } + + public MessagePayload frontMessage() { + long cPtr = wedpr_java_transportJNI.Message_frontMessage(swigCPtr, this); + return (cPtr == 0) ? null : new MessagePayload(cPtr, true); + } + + public boolean encode(ubytes _buffer) { + return wedpr_java_transportJNI.Message_encode( + swigCPtr, this, ubytes.getCPtr(_buffer), _buffer); + } + + public long decode(SWIGTYPE_p_bcos__bytesConstRef _buffer) { + return wedpr_java_transportJNI.Message_decode( + swigCPtr, this, SWIGTYPE_p_bcos__bytesConstRef.getCPtr(_buffer)); + } + + public long length() { + return wedpr_java_transportJNI.Message_length(swigCPtr, this); + } + + public ubytes payload() { + long cPtr = wedpr_java_transportJNI.Message_payload(swigCPtr, this); + return (cPtr == 0) ? null : new ubytes(cPtr, true); + } + + public void releasePayload() { + wedpr_java_transportJNI.Message_releasePayload(swigCPtr, this); + } + + public void disOwnMemory() { + swigSetCMemOwn(false); + } +} diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/MessageBuilder.java b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/MessageBuilder.java new file mode 100644 index 00000000..d2f7ecaf --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/MessageBuilder.java @@ -0,0 +1,74 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (https://www.swig.org). + * Version 4.2.1 + * + * Do not make changes to this file unless you know what you are doing - modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +package com.webank.wedpr.sdk.jni.generated; + +public class MessageBuilder { + private transient long swigCPtr; + private transient boolean swigCMemOwn; + + protected MessageBuilder(long cPtr, boolean cMemoryOwn) { + swigCMemOwn = cMemoryOwn; + swigCPtr = cPtr; + } + + protected static long getCPtr(MessageBuilder obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } + + protected void swigSetCMemOwn(boolean own) { + swigCMemOwn = own; + } + + @SuppressWarnings({"deprecation", "removal"}) + protected void finalize() { + delete(); + } + + public synchronized void delete() { + if (swigCPtr != 0) { + if (swigCMemOwn) { + swigCMemOwn = false; + wedpr_java_transportJNI.delete_MessageBuilder(swigCPtr); + } + swigCPtr = 0; + } + } + + public Message build() { + long cPtr = wedpr_java_transportJNI.MessageBuilder_build__SWIG_0(swigCPtr, this); + return (cPtr == 0) ? null : new Message(cPtr, true); + } + + public Message build(SWIGTYPE_p_bcos__bytesConstRef buffer) { + long cPtr = + wedpr_java_transportJNI.MessageBuilder_build__SWIG_1( + swigCPtr, this, SWIGTYPE_p_bcos__bytesConstRef.getCPtr(buffer)); + return (cPtr == 0) ? null : new Message(cPtr, true); + } + + public Message build( + SWIGTYPE_p_ppc__protocol__RouteType routeType, + MessageOptionalHeader routeInfo, + ubytes payload) { + long cPtr = + wedpr_java_transportJNI.MessageBuilder_build__SWIG_2( + swigCPtr, + this, + SWIGTYPE_p_ppc__protocol__RouteType.getCPtr(routeType), + MessageOptionalHeader.getCPtr(routeInfo), + routeInfo, + ubytes.swigRelease(payload), + payload); + return (cPtr == 0) ? null : new Message(cPtr, true); + } + + public void disOwnMemory() { + swigSetCMemOwn(false); + } +} diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/MessageDispatcherHandler.java b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/MessageDispatcherHandler.java new file mode 100644 index 00000000..7a0ee807 --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/MessageDispatcherHandler.java @@ -0,0 +1,68 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (https://www.swig.org). + * Version 4.2.1 + * + * Do not make changes to this file unless you know what you are doing - modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +package com.webank.wedpr.sdk.jni.generated; + +public class MessageDispatcherHandler { + private transient long swigCPtr; + private transient boolean swigCMemOwn; + + protected MessageDispatcherHandler(long cPtr, boolean cMemoryOwn) { + swigCMemOwn = cMemoryOwn; + swigCPtr = cPtr; + } + + protected static long getCPtr(MessageDispatcherHandler obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } + + protected void swigSetCMemOwn(boolean own) { + swigCMemOwn = own; + } + + @SuppressWarnings({"deprecation", "removal"}) + protected void finalize() { + delete(); + } + + public synchronized void delete() { + if (swigCPtr != 0) { + if (swigCMemOwn) { + swigCMemOwn = false; + wedpr_java_transportJNI.delete_MessageDispatcherHandler(swigCPtr); + } + swigCPtr = 0; + } + } + + protected void swigDirectorDisconnect() { + swigSetCMemOwn(false); + delete(); + } + + public void swigReleaseOwnership() { + swigSetCMemOwn(false); + wedpr_java_transportJNI.MessageDispatcherHandler_change_ownership(this, swigCPtr, false); + } + + public void swigTakeOwnership() { + swigSetCMemOwn(true); + wedpr_java_transportJNI.MessageDispatcherHandler_change_ownership(this, swigCPtr, true); + } + + public MessageDispatcherHandler() { + this(wedpr_java_transportJNI.new_MessageDispatcherHandler(), true); + wedpr_java_transportJNI.MessageDispatcherHandler_director_connect( + this, swigCPtr, true, true); + } + + public void onMessage(Message msg) { + wedpr_java_transportJNI.MessageDispatcherHandler_onMessage( + swigCPtr, this, Message.getCPtr(msg), msg); + } +} diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/MessageHeader.java b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/MessageHeader.java new file mode 100644 index 00000000..12dbd933 --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/MessageHeader.java @@ -0,0 +1,157 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (https://www.swig.org). + * Version 4.2.1 + * + * Do not make changes to this file unless you know what you are doing - modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +package com.webank.wedpr.sdk.jni.generated; + +public class MessageHeader { + private transient long swigCPtr; + private transient boolean swigCMemOwn; + + protected MessageHeader(long cPtr, boolean cMemoryOwn) { + swigCMemOwn = cMemoryOwn; + swigCPtr = cPtr; + } + + protected static long getCPtr(MessageHeader obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } + + protected void swigSetCMemOwn(boolean own) { + swigCMemOwn = own; + } + + @SuppressWarnings({"deprecation", "removal"}) + protected void finalize() { + delete(); + } + + public synchronized void delete() { + if (swigCPtr != 0) { + if (swigCMemOwn) { + swigCMemOwn = false; + wedpr_java_transportJNI.delete_MessageHeader(swigCPtr); + } + swigCPtr = 0; + } + } + + public void encode(ubytes buffer) { + wedpr_java_transportJNI.MessageHeader_encode( + swigCPtr, this, ubytes.getCPtr(buffer), buffer); + } + + public long decode(SWIGTYPE_p_bcos__bytesConstRef data) { + return wedpr_java_transportJNI.MessageHeader_decode( + swigCPtr, this, SWIGTYPE_p_bcos__bytesConstRef.getCPtr(data)); + } + + public short version() { + return wedpr_java_transportJNI.MessageHeader_version(swigCPtr, this); + } + + public void setVersion(int version) { + wedpr_java_transportJNI.MessageHeader_setVersion(swigCPtr, this, version); + } + + public String traceID() { + return wedpr_java_transportJNI.MessageHeader_traceID(swigCPtr, this); + } + + public void setTraceID(String traceID) { + wedpr_java_transportJNI.MessageHeader_setTraceID(swigCPtr, this, traceID); + } + + public String srcGwNode() { + return wedpr_java_transportJNI.MessageHeader_srcGwNode(swigCPtr, this); + } + + public void setSrcGwNode(String srcGwNode) { + wedpr_java_transportJNI.MessageHeader_setSrcGwNode(swigCPtr, this, srcGwNode); + } + + public String dstGwNode() { + return wedpr_java_transportJNI.MessageHeader_dstGwNode(swigCPtr, this); + } + + public void setDstGwNode(String dstGwNode) { + wedpr_java_transportJNI.MessageHeader_setDstGwNode(swigCPtr, this, dstGwNode); + } + + public int packetType() { + return wedpr_java_transportJNI.MessageHeader_packetType(swigCPtr, this); + } + + public void setPacketType(int packetType) { + wedpr_java_transportJNI.MessageHeader_setPacketType(swigCPtr, this, packetType); + } + + public short ttl() { + return wedpr_java_transportJNI.MessageHeader_ttl(swigCPtr, this); + } + + public void setTTL(int ttl) { + wedpr_java_transportJNI.MessageHeader_setTTL(swigCPtr, this, ttl); + } + + public int ext() { + return wedpr_java_transportJNI.MessageHeader_ext(swigCPtr, this); + } + + public void setExt(int ext) { + wedpr_java_transportJNI.MessageHeader_setExt(swigCPtr, this, ext); + } + + public MessageOptionalHeader optionalField() { + long cPtr = wedpr_java_transportJNI.MessageHeader_optionalField(swigCPtr, this); + return (cPtr == 0) ? null : new MessageOptionalHeader(cPtr, true); + } + + public void setOptionalField(MessageOptionalHeader optionalField) { + wedpr_java_transportJNI.MessageHeader_setOptionalField( + swigCPtr, this, MessageOptionalHeader.getCPtr(optionalField), optionalField); + } + + public int length() { + return wedpr_java_transportJNI.MessageHeader_length(swigCPtr, this); + } + + public boolean isRespPacket() { + return wedpr_java_transportJNI.MessageHeader_isRespPacket(swigCPtr, this); + } + + public void setRespPacket() { + wedpr_java_transportJNI.MessageHeader_setRespPacket(swigCPtr, this); + } + + public SWIGTYPE_p_std__string_view srcP2PNodeIDView() { + return new SWIGTYPE_p_std__string_view( + wedpr_java_transportJNI.MessageHeader_srcP2PNodeIDView(swigCPtr, this), true); + } + + public SWIGTYPE_p_std__string_view dstP2PNodeIDView() { + return new SWIGTYPE_p_std__string_view( + wedpr_java_transportJNI.MessageHeader_dstP2PNodeIDView(swigCPtr, this), true); + } + + public int routeType() { + return wedpr_java_transportJNI.MessageHeader_routeType(swigCPtr, this); + } + + public void setRouteType(SWIGTYPE_p_ppc__protocol__RouteType type) { + wedpr_java_transportJNI.MessageHeader_setRouteType( + swigCPtr, this, SWIGTYPE_p_ppc__protocol__RouteType.getCPtr(type)); + } + + public boolean hasOptionalField() { + return wedpr_java_transportJNI.MessageHeader_hasOptionalField(swigCPtr, this); + } + + public void disOwnMemory() { + swigSetCMemOwn(false); + } +} diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/MessageHeaderBuilder.java b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/MessageHeaderBuilder.java new file mode 100644 index 00000000..71d876b4 --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/MessageHeaderBuilder.java @@ -0,0 +1,68 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (https://www.swig.org). + * Version 4.2.1 + * + * Do not make changes to this file unless you know what you are doing - modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +package com.webank.wedpr.sdk.jni.generated; + +public class MessageHeaderBuilder { + private transient long swigCPtr; + private transient boolean swigCMemOwn; + + protected MessageHeaderBuilder(long cPtr, boolean cMemoryOwn) { + swigCMemOwn = cMemoryOwn; + swigCPtr = cPtr; + } + + protected static long getCPtr(MessageHeaderBuilder obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } + + protected void swigSetCMemOwn(boolean own) { + swigCMemOwn = own; + } + + @SuppressWarnings({"deprecation", "removal"}) + protected void finalize() { + delete(); + } + + public synchronized void delete() { + if (swigCPtr != 0) { + if (swigCMemOwn) { + swigCMemOwn = false; + wedpr_java_transportJNI.delete_MessageHeaderBuilder(swigCPtr); + } + swigCPtr = 0; + } + } + + public MessageHeader build(SWIGTYPE_p_bcos__bytesConstRef _data) { + long cPtr = + wedpr_java_transportJNI.MessageHeaderBuilder_build__SWIG_0( + swigCPtr, this, SWIGTYPE_p_bcos__bytesConstRef.getCPtr(_data)); + return (cPtr == 0) ? null : new MessageHeader(cPtr, true); + } + + public MessageHeader build() { + long cPtr = wedpr_java_transportJNI.MessageHeaderBuilder_build__SWIG_1(swigCPtr, this); + return (cPtr == 0) ? null : new MessageHeader(cPtr, true); + } + + public MessageOptionalHeader build(MessageOptionalHeader optionalHeader) { + long cPtr = + wedpr_java_transportJNI.MessageHeaderBuilder_build__SWIG_2( + swigCPtr, + this, + MessageOptionalHeader.getCPtr(optionalHeader), + optionalHeader); + return (cPtr == 0) ? null : new MessageOptionalHeader(cPtr, true); + } + + public void disOwnMemory() { + swigSetCMemOwn(false); + } +} diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/MessageOptionalHeader.java b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/MessageOptionalHeader.java new file mode 100644 index 00000000..b0a472ed --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/MessageOptionalHeader.java @@ -0,0 +1,113 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (https://www.swig.org). + * Version 4.2.1 + * + * Do not make changes to this file unless you know what you are doing - modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +package com.webank.wedpr.sdk.jni.generated; + +public class MessageOptionalHeader { + private transient long swigCPtr; + private transient boolean swigCMemOwn; + + protected MessageOptionalHeader(long cPtr, boolean cMemoryOwn) { + swigCMemOwn = cMemoryOwn; + swigCPtr = cPtr; + } + + protected static long getCPtr(MessageOptionalHeader obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } + + protected void swigSetCMemOwn(boolean own) { + swigCMemOwn = own; + } + + @SuppressWarnings({"deprecation", "removal"}) + protected void finalize() { + delete(); + } + + public synchronized void delete() { + if (swigCPtr != 0) { + if (swigCMemOwn) { + swigCMemOwn = false; + wedpr_java_transportJNI.delete_MessageOptionalHeader(swigCPtr); + } + swigCPtr = 0; + } + } + + public void encode(ubytes buffer) { + wedpr_java_transportJNI.MessageOptionalHeader_encode( + swigCPtr, this, ubytes.getCPtr(buffer), buffer); + } + + public long decode(SWIGTYPE_p_bcos__bytesConstRef data, java.math.BigInteger _offset) { + return wedpr_java_transportJNI.MessageOptionalHeader_decode( + swigCPtr, this, SWIGTYPE_p_bcos__bytesConstRef.getCPtr(data), _offset); + } + + public String componentType() { + return wedpr_java_transportJNI.MessageOptionalHeader_componentType(swigCPtr, this); + } + + public void setComponentType(String componentType) { + wedpr_java_transportJNI.MessageOptionalHeader_setComponentType( + swigCPtr, this, componentType); + } + + /** for swig-wrapper(pass the binary data) */ + public byte[] srcNodeBuffer() { + return wedpr_java_transportJNI.MessageOptionalHeader_srcNodeBuffer(swigCPtr, this); + } + + public void setSrcNodeBuffer(byte[] data, java.math.BigInteger length) { + wedpr_java_transportJNI.MessageOptionalHeader_setSrcNodeBuffer( + swigCPtr, this, data, length); + } + + public byte[] dstNodeBuffer() { + return wedpr_java_transportJNI.MessageOptionalHeader_dstNodeBuffer(swigCPtr, this); + } + + public void setDstNodeBuffer(byte[] data, java.math.BigInteger length) { + wedpr_java_transportJNI.MessageOptionalHeader_setDstNodeBuffer( + swigCPtr, this, data, length); + } + + public String dstInst() { + return wedpr_java_transportJNI.MessageOptionalHeader_dstInst(swigCPtr, this); + } + + public void setDstInst(String dstInst) { + wedpr_java_transportJNI.MessageOptionalHeader_setDstInst(swigCPtr, this, dstInst); + } + + public String topic() { + return wedpr_java_transportJNI.MessageOptionalHeader_topic(swigCPtr, this); + } + + public void setTopic(SWIGTYPE_p_std__string topic) { + wedpr_java_transportJNI.MessageOptionalHeader_setTopic__SWIG_0( + swigCPtr, this, SWIGTYPE_p_std__string.swigRelease(topic)); + } + + public void setTopic(String topic) { + wedpr_java_transportJNI.MessageOptionalHeader_setTopic__SWIG_1(swigCPtr, this, topic); + } + + public String srcInst() { + return wedpr_java_transportJNI.MessageOptionalHeader_srcInst(swigCPtr, this); + } + + public void setSrcInst(String srcInst) { + wedpr_java_transportJNI.MessageOptionalHeader_setSrcInst(swigCPtr, this, srcInst); + } + + public void disOwnMemory() { + swigSetCMemOwn(false); + } +} diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/MessageOptionalHeaderBuilder.java b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/MessageOptionalHeaderBuilder.java new file mode 100644 index 00000000..0078ee10 --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/MessageOptionalHeaderBuilder.java @@ -0,0 +1,62 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (https://www.swig.org). + * Version 4.2.1 + * + * Do not make changes to this file unless you know what you are doing - modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +package com.webank.wedpr.sdk.jni.generated; + +public class MessageOptionalHeaderBuilder { + private transient long swigCPtr; + private transient boolean swigCMemOwn; + + protected MessageOptionalHeaderBuilder(long cPtr, boolean cMemoryOwn) { + swigCMemOwn = cMemoryOwn; + swigCPtr = cPtr; + } + + protected static long getCPtr(MessageOptionalHeaderBuilder obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } + + protected void swigSetCMemOwn(boolean own) { + swigCMemOwn = own; + } + + @SuppressWarnings({"deprecation", "removal"}) + protected void finalize() { + delete(); + } + + public synchronized void delete() { + if (swigCPtr != 0) { + if (swigCMemOwn) { + swigCMemOwn = false; + wedpr_java_transportJNI.delete_MessageOptionalHeaderBuilder(swigCPtr); + } + swigCPtr = 0; + } + } + + public MessageOptionalHeader build(MessageOptionalHeader optionalHeader) { + long cPtr = + wedpr_java_transportJNI.MessageOptionalHeaderBuilder_build__SWIG_0( + swigCPtr, + this, + MessageOptionalHeader.getCPtr(optionalHeader), + optionalHeader); + return (cPtr == 0) ? null : new MessageOptionalHeader(cPtr, true); + } + + public MessageOptionalHeader build() { + long cPtr = + wedpr_java_transportJNI.MessageOptionalHeaderBuilder_build__SWIG_1(swigCPtr, this); + return (cPtr == 0) ? null : new MessageOptionalHeader(cPtr, true); + } + + public void disOwnMemory() { + swigSetCMemOwn(false); + } +} diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/MessagePayload.java b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/MessagePayload.java new file mode 100644 index 00000000..c83bc33d --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/MessagePayload.java @@ -0,0 +1,108 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (https://www.swig.org). + * Version 4.2.1 + * + * Do not make changes to this file unless you know what you are doing - modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +package com.webank.wedpr.sdk.jni.generated; + +public class MessagePayload { + private transient long swigCPtr; + private transient boolean swigCMemOwn; + + protected MessagePayload(long cPtr, boolean cMemoryOwn) { + swigCMemOwn = cMemoryOwn; + swigCPtr = cPtr; + } + + protected static long getCPtr(MessagePayload obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } + + protected void swigSetCMemOwn(boolean own) { + swigCMemOwn = own; + } + + @SuppressWarnings({"deprecation", "removal"}) + protected void finalize() { + delete(); + } + + public synchronized void delete() { + if (swigCPtr != 0) { + if (swigCMemOwn) { + swigCMemOwn = false; + wedpr_java_transportJNI.delete_MessagePayload(swigCPtr); + } + swigCPtr = 0; + } + } + + public long encode(ubytes buffer) { + return wedpr_java_transportJNI.MessagePayload_encode( + swigCPtr, this, ubytes.getCPtr(buffer), buffer); + } + + public long decode(SWIGTYPE_p_bcos__bytesConstRef data) { + return wedpr_java_transportJNI.MessagePayload_decode( + swigCPtr, this, SWIGTYPE_p_bcos__bytesConstRef.getCPtr(data)); + } + + public short version() { + return wedpr_java_transportJNI.MessagePayload_version(swigCPtr, this); + } + + public void setVersion(short version) { + wedpr_java_transportJNI.MessagePayload_setVersion(swigCPtr, this, version); + } + + public byte[] dataBuffer() { + return wedpr_java_transportJNI.MessagePayload_dataBuffer(swigCPtr, this); + } + + public int seq() { + return wedpr_java_transportJNI.MessagePayload_seq(swigCPtr, this); + } + + public void setSeq(int seq) { + wedpr_java_transportJNI.MessagePayload_setSeq(swigCPtr, this, seq); + } + + public long length() { + return wedpr_java_transportJNI.MessagePayload_length(swigCPtr, this); + } + + public String traceID() { + return wedpr_java_transportJNI.MessagePayload_traceID(swigCPtr, this); + } + + public void setTraceID(String traceID) { + wedpr_java_transportJNI.MessagePayload_setTraceID(swigCPtr, this, traceID); + } + + public int ext() { + return wedpr_java_transportJNI.MessagePayload_ext(swigCPtr, this); + } + + public void setExt(int ext) { + wedpr_java_transportJNI.MessagePayload_setExt(swigCPtr, this, ext); + } + + public void setRespPacket() { + wedpr_java_transportJNI.MessagePayload_setRespPacket(swigCPtr, this); + } + + public boolean isRespPacket() { + return wedpr_java_transportJNI.MessagePayload_isRespPacket(swigCPtr, this); + } + + public void releasePayload() { + wedpr_java_transportJNI.MessagePayload_releasePayload(swigCPtr, this); + } + + public void disOwnMemory() { + swigSetCMemOwn(false); + } +} diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/MessagePayloadBuilder.java b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/MessagePayloadBuilder.java new file mode 100644 index 00000000..064a2c95 --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/MessagePayloadBuilder.java @@ -0,0 +1,58 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (https://www.swig.org). + * Version 4.2.1 + * + * Do not make changes to this file unless you know what you are doing - modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +package com.webank.wedpr.sdk.jni.generated; + +public class MessagePayloadBuilder { + private transient long swigCPtr; + private transient boolean swigCMemOwn; + + protected MessagePayloadBuilder(long cPtr, boolean cMemoryOwn) { + swigCMemOwn = cMemoryOwn; + swigCPtr = cPtr; + } + + protected static long getCPtr(MessagePayloadBuilder obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } + + protected void swigSetCMemOwn(boolean own) { + swigCMemOwn = own; + } + + @SuppressWarnings({"deprecation", "removal"}) + protected void finalize() { + delete(); + } + + public synchronized void delete() { + if (swigCPtr != 0) { + if (swigCMemOwn) { + swigCMemOwn = false; + wedpr_java_transportJNI.delete_MessagePayloadBuilder(swigCPtr); + } + swigCPtr = 0; + } + } + + public MessagePayload build() { + long cPtr = wedpr_java_transportJNI.MessagePayloadBuilder_build__SWIG_0(swigCPtr, this); + return (cPtr == 0) ? null : new MessagePayload(cPtr, true); + } + + public MessagePayload build(SWIGTYPE_p_bcos__bytesConstRef buffer) { + long cPtr = + wedpr_java_transportJNI.MessagePayloadBuilder_build__SWIG_1( + swigCPtr, this, SWIGTYPE_p_bcos__bytesConstRef.getCPtr(buffer)); + return (cPtr == 0) ? null : new MessagePayload(cPtr, true); + } + + public void disOwnMemory() { + swigSetCMemOwn(false); + } +} diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/NodeInfoVec.java b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/NodeInfoVec.java new file mode 100644 index 00000000..c2a45062 --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/NodeInfoVec.java @@ -0,0 +1,175 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (https://www.swig.org). + * Version 4.2.1 + * + * Do not make changes to this file unless you know what you are doing - modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +package com.webank.wedpr.sdk.jni.generated; + +public class NodeInfoVec extends java.util.AbstractList + implements java.util.RandomAccess { + private transient long swigCPtr; + protected transient boolean swigCMemOwn; + + protected NodeInfoVec(long cPtr, boolean cMemoryOwn) { + swigCMemOwn = cMemoryOwn; + swigCPtr = cPtr; + } + + protected static long getCPtr(NodeInfoVec obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } + + protected static long swigRelease(NodeInfoVec obj) { + long ptr = 0; + if (obj != null) { + if (!obj.swigCMemOwn) + throw new RuntimeException("Cannot release ownership as memory is not owned"); + ptr = obj.swigCPtr; + obj.swigCMemOwn = false; + obj.delete(); + } + return ptr; + } + + @SuppressWarnings({"deprecation", "removal"}) + protected void finalize() { + delete(); + } + + public synchronized void delete() { + if (swigCPtr != 0) { + if (swigCMemOwn) { + swigCMemOwn = false; + wedpr_java_transportJNI.delete_NodeInfoVec(swigCPtr); + } + swigCPtr = 0; + } + } + + public NodeInfoVec(INodeInfo[] initialElements) { + this(); + reserve(initialElements.length); + + for (INodeInfo element : initialElements) { + add(element); + } + } + + public NodeInfoVec(Iterable initialElements) { + this(); + for (INodeInfo element : initialElements) { + add(element); + } + } + + public INodeInfo get(int index) { + return doGet(index); + } + + public INodeInfo set(int index, INodeInfo e) { + return doSet(index, e); + } + + public boolean add(INodeInfo e) { + modCount++; + doAdd(e); + return true; + } + + public void add(int index, INodeInfo e) { + modCount++; + doAdd(index, e); + } + + public INodeInfo remove(int index) { + modCount++; + return doRemove(index); + } + + protected void removeRange(int fromIndex, int toIndex) { + modCount++; + doRemoveRange(fromIndex, toIndex); + } + + public int size() { + return doSize(); + } + + public int capacity() { + return doCapacity(); + } + + public void reserve(int n) { + doReserve(n); + } + + public NodeInfoVec() { + this(wedpr_java_transportJNI.new_NodeInfoVec__SWIG_0(), true); + } + + public NodeInfoVec(NodeInfoVec other) { + this( + wedpr_java_transportJNI.new_NodeInfoVec__SWIG_1(NodeInfoVec.getCPtr(other), other), + true); + } + + public boolean isEmpty() { + return wedpr_java_transportJNI.NodeInfoVec_isEmpty(swigCPtr, this); + } + + public void clear() { + wedpr_java_transportJNI.NodeInfoVec_clear(swigCPtr, this); + } + + public NodeInfoVec(int count, INodeInfo value) { + this( + wedpr_java_transportJNI.new_NodeInfoVec__SWIG_2( + count, INodeInfo.getCPtr(value), value), + true); + } + + private int doCapacity() { + return wedpr_java_transportJNI.NodeInfoVec_doCapacity(swigCPtr, this); + } + + private void doReserve(int n) { + wedpr_java_transportJNI.NodeInfoVec_doReserve(swigCPtr, this, n); + } + + private int doSize() { + return wedpr_java_transportJNI.NodeInfoVec_doSize(swigCPtr, this); + } + + private void doAdd(INodeInfo x) { + wedpr_java_transportJNI.NodeInfoVec_doAdd__SWIG_0(swigCPtr, this, INodeInfo.getCPtr(x), x); + } + + private void doAdd(int index, INodeInfo x) { + wedpr_java_transportJNI.NodeInfoVec_doAdd__SWIG_1( + swigCPtr, this, index, INodeInfo.getCPtr(x), x); + } + + private INodeInfo doRemove(int index) { + long cPtr = wedpr_java_transportJNI.NodeInfoVec_doRemove(swigCPtr, this, index); + return (cPtr == 0) ? null : new INodeInfo(cPtr, true); + } + + private INodeInfo doGet(int index) { + long cPtr = wedpr_java_transportJNI.NodeInfoVec_doGet(swigCPtr, this, index); + return (cPtr == 0) ? null : new INodeInfo(cPtr, true); + } + + private INodeInfo doSet(int index, INodeInfo val) { + long cPtr = + wedpr_java_transportJNI.NodeInfoVec_doSet( + swigCPtr, this, index, INodeInfo.getCPtr(val), val); + return (cPtr == 0) ? null : new INodeInfo(cPtr, true); + } + + private void doRemoveRange(int fromIndex, int toIndex) { + wedpr_java_transportJNI.NodeInfoVec_doRemoveRange(swigCPtr, this, fromIndex, toIndex); + } +} diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/OutputBuffer.java b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/OutputBuffer.java new file mode 100644 index 00000000..86eb3187 --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/OutputBuffer.java @@ -0,0 +1,72 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (https://www.swig.org). + * Version 4.2.1 + * + * Do not make changes to this file unless you know what you are doing - modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +package com.webank.wedpr.sdk.jni.generated; + +public class OutputBuffer { + private transient long swigCPtr; + protected transient boolean swigCMemOwn; + + protected OutputBuffer(long cPtr, boolean cMemoryOwn) { + swigCMemOwn = cMemoryOwn; + swigCPtr = cPtr; + } + + protected static long getCPtr(OutputBuffer obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } + + protected static long swigRelease(OutputBuffer obj) { + long ptr = 0; + if (obj != null) { + if (!obj.swigCMemOwn) + throw new RuntimeException("Cannot release ownership as memory is not owned"); + ptr = obj.swigCPtr; + obj.swigCMemOwn = false; + obj.delete(); + } + return ptr; + } + + @SuppressWarnings({"deprecation", "removal"}) + protected void finalize() { + delete(); + } + + public synchronized void delete() { + if (swigCPtr != 0) { + if (swigCMemOwn) { + swigCMemOwn = false; + wedpr_java_transportJNI.delete_OutputBuffer(swigCPtr); + } + swigCPtr = 0; + } + } + + public void setData(SWIGTYPE_p_unsigned_char value) { + wedpr_java_transportJNI.OutputBuffer_data_set( + swigCPtr, this, SWIGTYPE_p_unsigned_char.getCPtr(value)); + } + + public SWIGTYPE_p_unsigned_char getData() { + long cPtr = wedpr_java_transportJNI.OutputBuffer_data_get(swigCPtr, this); + return (cPtr == 0) ? null : new SWIGTYPE_p_unsigned_char(cPtr, false); + } + + public void setLen(java.math.BigInteger value) { + wedpr_java_transportJNI.OutputBuffer_len_set(swigCPtr, this, value); + } + + public java.math.BigInteger getLen() { + return wedpr_java_transportJNI.OutputBuffer_len_get(swigCPtr, this); + } + + public OutputBuffer() { + this(wedpr_java_transportJNI.new_OutputBuffer(), true); + } +} diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SDKMode.java b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SDKMode.java new file mode 100644 index 00000000..c5c9f44f --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SDKMode.java @@ -0,0 +1,53 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (https://www.swig.org). + * Version 4.2.1 + * + * Do not make changes to this file unless you know what you are doing - modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +package com.webank.wedpr.sdk.jni.generated; + +public final class SDKMode { + public static final SDKMode AIR = new SDKMode("AIR", wedpr_java_transportJNI.SDKMode_AIR_get()); + public static final SDKMode PRO = new SDKMode("PRO", wedpr_java_transportJNI.SDKMode_PRO_get()); + + public final int swigValue() { + return swigValue; + } + + public String toString() { + return swigName; + } + + public static SDKMode swigToEnum(int swigValue) { + if (swigValue < swigValues.length + && swigValue >= 0 + && swigValues[swigValue].swigValue == swigValue) return swigValues[swigValue]; + for (int i = 0; i < swigValues.length; i++) + if (swigValues[i].swigValue == swigValue) return swigValues[i]; + throw new IllegalArgumentException("No enum " + SDKMode.class + " with value " + swigValue); + } + + private SDKMode(String swigName) { + this.swigName = swigName; + this.swigValue = swigNext++; + } + + private SDKMode(String swigName, int swigValue) { + this.swigName = swigName; + this.swigValue = swigValue; + swigNext = swigValue + 1; + } + + private SDKMode(String swigName, SDKMode swigEnum) { + this.swigName = swigName; + this.swigValue = swigEnum.swigValue; + swigNext = this.swigValue + 1; + } + + private static SDKMode[] swigValues = {AIR, PRO}; + private static int swigNext = 0; + private final int swigValue; + private final String swigName; +} diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SWIGTYPE_p_bcos__boostssl__EncodedMsg.java b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SWIGTYPE_p_bcos__boostssl__EncodedMsg.java new file mode 100644 index 00000000..bac116db --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SWIGTYPE_p_bcos__boostssl__EncodedMsg.java @@ -0,0 +1,30 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (https://www.swig.org). + * Version 4.2.1 + * + * Do not make changes to this file unless you know what you are doing - modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +package com.webank.wedpr.sdk.jni.generated; + +public class SWIGTYPE_p_bcos__boostssl__EncodedMsg { + private transient long swigCPtr; + + protected SWIGTYPE_p_bcos__boostssl__EncodedMsg( + long cPtr, @SuppressWarnings("unused") boolean futureUse) { + swigCPtr = cPtr; + } + + protected SWIGTYPE_p_bcos__boostssl__EncodedMsg() { + swigCPtr = 0; + } + + protected static long getCPtr(SWIGTYPE_p_bcos__boostssl__EncodedMsg obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } + + protected static long swigRelease(SWIGTYPE_p_bcos__boostssl__EncodedMsg obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } +} diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SWIGTYPE_p_bcos__boostssl__MessageFace__Ptr.java b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SWIGTYPE_p_bcos__boostssl__MessageFace__Ptr.java new file mode 100644 index 00000000..426dd9c4 --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SWIGTYPE_p_bcos__boostssl__MessageFace__Ptr.java @@ -0,0 +1,30 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (https://www.swig.org). + * Version 4.2.1 + * + * Do not make changes to this file unless you know what you are doing - modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +package com.webank.wedpr.sdk.jni.generated; + +public class SWIGTYPE_p_bcos__boostssl__MessageFace__Ptr { + private transient long swigCPtr; + + protected SWIGTYPE_p_bcos__boostssl__MessageFace__Ptr( + long cPtr, @SuppressWarnings("unused") boolean futureUse) { + swigCPtr = cPtr; + } + + protected SWIGTYPE_p_bcos__boostssl__MessageFace__Ptr() { + swigCPtr = 0; + } + + protected static long getCPtr(SWIGTYPE_p_bcos__boostssl__MessageFace__Ptr obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } + + protected static long swigRelease(SWIGTYPE_p_bcos__boostssl__MessageFace__Ptr obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } +} diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SWIGTYPE_p_bcos__bytesConstRef.java b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SWIGTYPE_p_bcos__bytesConstRef.java new file mode 100644 index 00000000..3016ab17 --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SWIGTYPE_p_bcos__bytesConstRef.java @@ -0,0 +1,30 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (https://www.swig.org). + * Version 4.2.1 + * + * Do not make changes to this file unless you know what you are doing - modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +package com.webank.wedpr.sdk.jni.generated; + +public class SWIGTYPE_p_bcos__bytesConstRef { + private transient long swigCPtr; + + protected SWIGTYPE_p_bcos__bytesConstRef( + long cPtr, @SuppressWarnings("unused") boolean futureUse) { + swigCPtr = cPtr; + } + + protected SWIGTYPE_p_bcos__bytesConstRef() { + swigCPtr = 0; + } + + protected static long getCPtr(SWIGTYPE_p_bcos__bytesConstRef obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } + + protected static long swigRelease(SWIGTYPE_p_bcos__bytesConstRef obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } +} diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SWIGTYPE_p_ppc__gateway__IGateway.java b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SWIGTYPE_p_ppc__gateway__IGateway.java new file mode 100644 index 00000000..556ac652 --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SWIGTYPE_p_ppc__gateway__IGateway.java @@ -0,0 +1,30 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (https://www.swig.org). + * Version 4.2.1 + * + * Do not make changes to this file unless you know what you are doing - modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +package com.webank.wedpr.sdk.jni.generated; + +public class SWIGTYPE_p_ppc__gateway__IGateway { + private transient long swigCPtr; + + protected SWIGTYPE_p_ppc__gateway__IGateway( + long cPtr, @SuppressWarnings("unused") boolean futureUse) { + swigCPtr = cPtr; + } + + protected SWIGTYPE_p_ppc__gateway__IGateway() { + swigCPtr = 0; + } + + protected static long getCPtr(SWIGTYPE_p_ppc__gateway__IGateway obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } + + protected static long swigRelease(SWIGTYPE_p_ppc__gateway__IGateway obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } +} diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SWIGTYPE_p_ppc__gateway__IGateway__Ptr.java b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SWIGTYPE_p_ppc__gateway__IGateway__Ptr.java new file mode 100644 index 00000000..73e52ea9 --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SWIGTYPE_p_ppc__gateway__IGateway__Ptr.java @@ -0,0 +1,30 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (https://www.swig.org). + * Version 4.2.1 + * + * Do not make changes to this file unless you know what you are doing - modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +package com.webank.wedpr.sdk.jni.generated; + +public class SWIGTYPE_p_ppc__gateway__IGateway__Ptr { + private transient long swigCPtr; + + protected SWIGTYPE_p_ppc__gateway__IGateway__Ptr( + long cPtr, @SuppressWarnings("unused") boolean futureUse) { + swigCPtr = cPtr; + } + + protected SWIGTYPE_p_ppc__gateway__IGateway__Ptr() { + swigCPtr = 0; + } + + protected static long getCPtr(SWIGTYPE_p_ppc__gateway__IGateway__Ptr obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } + + protected static long swigRelease(SWIGTYPE_p_ppc__gateway__IGateway__Ptr obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } +} diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SWIGTYPE_p_ppc__protocol__INodeInfo__Ptr.java b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SWIGTYPE_p_ppc__protocol__INodeInfo__Ptr.java new file mode 100644 index 00000000..69a74312 --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SWIGTYPE_p_ppc__protocol__INodeInfo__Ptr.java @@ -0,0 +1,30 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (https://www.swig.org). + * Version 4.2.1 + * + * Do not make changes to this file unless you know what you are doing - modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +package com.webank.wedpr.sdk.jni.generated; + +public class SWIGTYPE_p_ppc__protocol__INodeInfo__Ptr { + private transient long swigCPtr; + + protected SWIGTYPE_p_ppc__protocol__INodeInfo__Ptr( + long cPtr, @SuppressWarnings("unused") boolean futureUse) { + swigCPtr = cPtr; + } + + protected SWIGTYPE_p_ppc__protocol__INodeInfo__Ptr() { + swigCPtr = 0; + } + + protected static long getCPtr(SWIGTYPE_p_ppc__protocol__INodeInfo__Ptr obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } + + protected static long swigRelease(SWIGTYPE_p_ppc__protocol__INodeInfo__Ptr obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } +} diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SWIGTYPE_p_ppc__protocol__RouteType.java b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SWIGTYPE_p_ppc__protocol__RouteType.java new file mode 100644 index 00000000..850a8086 --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SWIGTYPE_p_ppc__protocol__RouteType.java @@ -0,0 +1,30 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (https://www.swig.org). + * Version 4.2.1 + * + * Do not make changes to this file unless you know what you are doing - modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +package com.webank.wedpr.sdk.jni.generated; + +public class SWIGTYPE_p_ppc__protocol__RouteType { + private transient long swigCPtr; + + protected SWIGTYPE_p_ppc__protocol__RouteType( + long cPtr, @SuppressWarnings("unused") boolean futureUse) { + swigCPtr = cPtr; + } + + protected SWIGTYPE_p_ppc__protocol__RouteType() { + swigCPtr = 0; + } + + protected static long getCPtr(SWIGTYPE_p_ppc__protocol__RouteType obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } + + protected static long swigRelease(SWIGTYPE_p_ppc__protocol__RouteType obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } +} diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SWIGTYPE_p_std__exception.java b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SWIGTYPE_p_std__exception.java new file mode 100644 index 00000000..e2a77bb3 --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SWIGTYPE_p_std__exception.java @@ -0,0 +1,29 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (https://www.swig.org). + * Version 4.2.1 + * + * Do not make changes to this file unless you know what you are doing - modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +package com.webank.wedpr.sdk.jni.generated; + +public class SWIGTYPE_p_std__exception { + private transient long swigCPtr; + + protected SWIGTYPE_p_std__exception(long cPtr, @SuppressWarnings("unused") boolean futureUse) { + swigCPtr = cPtr; + } + + protected SWIGTYPE_p_std__exception() { + swigCPtr = 0; + } + + protected static long getCPtr(SWIGTYPE_p_std__exception obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } + + protected static long swigRelease(SWIGTYPE_p_std__exception obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } +} diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SWIGTYPE_p_std__functionT_void_fF_t.java b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SWIGTYPE_p_std__functionT_void_fF_t.java new file mode 100644 index 00000000..e3043d71 --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SWIGTYPE_p_std__functionT_void_fF_t.java @@ -0,0 +1,30 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (https://www.swig.org). + * Version 4.2.1 + * + * Do not make changes to this file unless you know what you are doing - modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +package com.webank.wedpr.sdk.jni.generated; + +public class SWIGTYPE_p_std__functionT_void_fF_t { + private transient long swigCPtr; + + protected SWIGTYPE_p_std__functionT_void_fF_t( + long cPtr, @SuppressWarnings("unused") boolean futureUse) { + swigCPtr = cPtr; + } + + protected SWIGTYPE_p_std__functionT_void_fF_t() { + swigCPtr = 0; + } + + protected static long getCPtr(SWIGTYPE_p_std__functionT_void_fF_t obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } + + protected static long swigRelease(SWIGTYPE_p_std__functionT_void_fF_t obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } +} diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SWIGTYPE_p_std__functionT_void_fstd__shared_ptrT_bcos__Error_tF_t.java b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SWIGTYPE_p_std__functionT_void_fstd__shared_ptrT_bcos__Error_tF_t.java new file mode 100644 index 00000000..9d7de5ce --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SWIGTYPE_p_std__functionT_void_fstd__shared_ptrT_bcos__Error_tF_t.java @@ -0,0 +1,32 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (https://www.swig.org). + * Version 4.2.1 + * + * Do not make changes to this file unless you know what you are doing - modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +package com.webank.wedpr.sdk.jni.generated; + +public class SWIGTYPE_p_std__functionT_void_fstd__shared_ptrT_bcos__Error_tF_t { + private transient long swigCPtr; + + protected SWIGTYPE_p_std__functionT_void_fstd__shared_ptrT_bcos__Error_tF_t( + long cPtr, @SuppressWarnings("unused") boolean futureUse) { + swigCPtr = cPtr; + } + + protected SWIGTYPE_p_std__functionT_void_fstd__shared_ptrT_bcos__Error_tF_t() { + swigCPtr = 0; + } + + protected static long getCPtr( + SWIGTYPE_p_std__functionT_void_fstd__shared_ptrT_bcos__Error_tF_t obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } + + protected static long swigRelease( + SWIGTYPE_p_std__functionT_void_fstd__shared_ptrT_bcos__Error_tF_t obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } +} diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SWIGTYPE_p_std__functionT_void_fstd__shared_ptrT_bcos__bytes_t_RRF_t.java b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SWIGTYPE_p_std__functionT_void_fstd__shared_ptrT_bcos__bytes_t_RRF_t.java new file mode 100644 index 00000000..859373ad --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SWIGTYPE_p_std__functionT_void_fstd__shared_ptrT_bcos__bytes_t_RRF_t.java @@ -0,0 +1,32 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (https://www.swig.org). + * Version 4.2.1 + * + * Do not make changes to this file unless you know what you are doing - modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +package com.webank.wedpr.sdk.jni.generated; + +public class SWIGTYPE_p_std__functionT_void_fstd__shared_ptrT_bcos__bytes_t_RRF_t { + private transient long swigCPtr; + + protected SWIGTYPE_p_std__functionT_void_fstd__shared_ptrT_bcos__bytes_t_RRF_t( + long cPtr, @SuppressWarnings("unused") boolean futureUse) { + swigCPtr = cPtr; + } + + protected SWIGTYPE_p_std__functionT_void_fstd__shared_ptrT_bcos__bytes_t_RRF_t() { + swigCPtr = 0; + } + + protected static long getCPtr( + SWIGTYPE_p_std__functionT_void_fstd__shared_ptrT_bcos__bytes_t_RRF_t obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } + + protected static long swigRelease( + SWIGTYPE_p_std__functionT_void_fstd__shared_ptrT_bcos__bytes_t_RRF_t obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } +} diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SWIGTYPE_p_std__shared_ptrT_bcos__bytes_t.java b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SWIGTYPE_p_std__shared_ptrT_bcos__bytes_t.java new file mode 100644 index 00000000..8573008b --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SWIGTYPE_p_std__shared_ptrT_bcos__bytes_t.java @@ -0,0 +1,30 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (https://www.swig.org). + * Version 4.2.1 + * + * Do not make changes to this file unless you know what you are doing - modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +package com.webank.wedpr.sdk.jni.generated; + +public class SWIGTYPE_p_std__shared_ptrT_bcos__bytes_t { + private transient long swigCPtr; + + protected SWIGTYPE_p_std__shared_ptrT_bcos__bytes_t( + long cPtr, @SuppressWarnings("unused") boolean futureUse) { + swigCPtr = cPtr; + } + + protected SWIGTYPE_p_std__shared_ptrT_bcos__bytes_t() { + swigCPtr = 0; + } + + protected static long getCPtr(SWIGTYPE_p_std__shared_ptrT_bcos__bytes_t obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } + + protected static long swigRelease(SWIGTYPE_p_std__shared_ptrT_bcos__bytes_t obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } +} diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SWIGTYPE_p_std__shared_ptrT_ppc__front__FrontConfigBuilder_t.java b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SWIGTYPE_p_std__shared_ptrT_ppc__front__FrontConfigBuilder_t.java new file mode 100644 index 00000000..58d25258 --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SWIGTYPE_p_std__shared_ptrT_ppc__front__FrontConfigBuilder_t.java @@ -0,0 +1,32 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (https://www.swig.org). + * Version 4.2.1 + * + * Do not make changes to this file unless you know what you are doing - modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +package com.webank.wedpr.sdk.jni.generated; + +public class SWIGTYPE_p_std__shared_ptrT_ppc__front__FrontConfigBuilder_t { + private transient long swigCPtr; + + protected SWIGTYPE_p_std__shared_ptrT_ppc__front__FrontConfigBuilder_t( + long cPtr, @SuppressWarnings("unused") boolean futureUse) { + swigCPtr = cPtr; + } + + protected SWIGTYPE_p_std__shared_ptrT_ppc__front__FrontConfigBuilder_t() { + swigCPtr = 0; + } + + protected static long getCPtr( + SWIGTYPE_p_std__shared_ptrT_ppc__front__FrontConfigBuilder_t obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } + + protected static long swigRelease( + SWIGTYPE_p_std__shared_ptrT_ppc__front__FrontConfigBuilder_t obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } +} diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SWIGTYPE_p_std__string.java b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SWIGTYPE_p_std__string.java new file mode 100644 index 00000000..89720225 --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SWIGTYPE_p_std__string.java @@ -0,0 +1,29 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (https://www.swig.org). + * Version 4.2.1 + * + * Do not make changes to this file unless you know what you are doing - modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +package com.webank.wedpr.sdk.jni.generated; + +public class SWIGTYPE_p_std__string { + private transient long swigCPtr; + + protected SWIGTYPE_p_std__string(long cPtr, @SuppressWarnings("unused") boolean futureUse) { + swigCPtr = cPtr; + } + + protected SWIGTYPE_p_std__string() { + swigCPtr = 0; + } + + protected static long getCPtr(SWIGTYPE_p_std__string obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } + + protected static long swigRelease(SWIGTYPE_p_std__string obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } +} diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SWIGTYPE_p_std__string_view.java b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SWIGTYPE_p_std__string_view.java new file mode 100644 index 00000000..d087fcd7 --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SWIGTYPE_p_std__string_view.java @@ -0,0 +1,30 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (https://www.swig.org). + * Version 4.2.1 + * + * Do not make changes to this file unless you know what you are doing - modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +package com.webank.wedpr.sdk.jni.generated; + +public class SWIGTYPE_p_std__string_view { + private transient long swigCPtr; + + protected SWIGTYPE_p_std__string_view( + long cPtr, @SuppressWarnings("unused") boolean futureUse) { + swigCPtr = cPtr; + } + + protected SWIGTYPE_p_std__string_view() { + swigCPtr = 0; + } + + protected static long getCPtr(SWIGTYPE_p_std__string_view obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } + + protected static long swigRelease(SWIGTYPE_p_std__string_view obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } +} diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SWIGTYPE_p_unsigned_char.java b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SWIGTYPE_p_unsigned_char.java new file mode 100644 index 00000000..b7f2ac03 --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SWIGTYPE_p_unsigned_char.java @@ -0,0 +1,29 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (https://www.swig.org). + * Version 4.2.1 + * + * Do not make changes to this file unless you know what you are doing - modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +package com.webank.wedpr.sdk.jni.generated; + +public class SWIGTYPE_p_unsigned_char { + private transient long swigCPtr; + + protected SWIGTYPE_p_unsigned_char(long cPtr, @SuppressWarnings("unused") boolean futureUse) { + swigCPtr = cPtr; + } + + protected SWIGTYPE_p_unsigned_char() { + swigCPtr = 0; + } + + protected static long getCPtr(SWIGTYPE_p_unsigned_char obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } + + protected static long swigRelease(SWIGTYPE_p_unsigned_char obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } +} diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SendResponseHandler.java b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SendResponseHandler.java new file mode 100644 index 00000000..6ab774ab --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SendResponseHandler.java @@ -0,0 +1,64 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (https://www.swig.org). + * Version 4.2.1 + * + * Do not make changes to this file unless you know what you are doing - modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +package com.webank.wedpr.sdk.jni.generated; + +public class SendResponseHandler { + private transient long swigCPtr; + protected transient boolean swigCMemOwn; + + protected SendResponseHandler(long cPtr, boolean cMemoryOwn) { + swigCMemOwn = cMemoryOwn; + swigCPtr = cPtr; + } + + protected static long getCPtr(SendResponseHandler obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } + + protected static long swigRelease(SendResponseHandler obj) { + long ptr = 0; + if (obj != null) { + if (!obj.swigCMemOwn) + throw new RuntimeException("Cannot release ownership as memory is not owned"); + ptr = obj.swigCPtr; + obj.swigCMemOwn = false; + obj.delete(); + } + return ptr; + } + + @SuppressWarnings({"deprecation", "removal"}) + protected void finalize() { + delete(); + } + + public synchronized void delete() { + if (swigCPtr != 0) { + if (swigCMemOwn) { + swigCMemOwn = false; + wedpr_java_transportJNI.delete_SendResponseHandler(swigCPtr); + } + swigCPtr = 0; + } + } + + public SendResponseHandler( + SWIGTYPE_p_std__functionT_void_fstd__shared_ptrT_bcos__bytes_t_RRF_t responseFunc) { + this( + wedpr_java_transportJNI.new_SendResponseHandler( + SWIGTYPE_p_std__functionT_void_fstd__shared_ptrT_bcos__bytes_t_RRF_t + .getCPtr(responseFunc)), + true); + } + + public void sendResponse(SWIGTYPE_p_std__shared_ptrT_bcos__bytes_t payload) { + wedpr_java_transportJNI.SendResponseHandler_sendResponse( + swigCPtr, this, SWIGTYPE_p_std__shared_ptrT_bcos__bytes_t.swigRelease(payload)); + } +} diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SharedBcosError.java b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SharedBcosError.java new file mode 100644 index 00000000..87fff366 --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SharedBcosError.java @@ -0,0 +1,54 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (https://www.swig.org). + * Version 4.2.1 + * + * Do not make changes to this file unless you know what you are doing - modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +package com.webank.wedpr.sdk.jni.generated; + +public class SharedBcosError { + private transient long swigCPtr; + protected transient boolean swigCMemOwn; + + protected SharedBcosError(long cPtr, boolean cMemoryOwn) { + swigCMemOwn = cMemoryOwn; + swigCPtr = cPtr; + } + + protected static long getCPtr(SharedBcosError obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } + + protected static long swigRelease(SharedBcosError obj) { + long ptr = 0; + if (obj != null) { + if (!obj.swigCMemOwn) + throw new RuntimeException("Cannot release ownership as memory is not owned"); + ptr = obj.swigCPtr; + obj.swigCMemOwn = false; + obj.delete(); + } + return ptr; + } + + @SuppressWarnings({"deprecation", "removal"}) + protected void finalize() { + delete(); + } + + public synchronized void delete() { + if (swigCPtr != 0) { + if (swigCMemOwn) { + swigCMemOwn = false; + wedpr_java_transportJNI.delete_SharedBcosError(swigCPtr); + } + swigCPtr = 0; + } + } + + public SharedBcosError() { + this(wedpr_java_transportJNI.new_SharedBcosError(), true); + } +} diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SharedErrorCallback.java b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SharedErrorCallback.java new file mode 100644 index 00000000..4b53ca7f --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SharedErrorCallback.java @@ -0,0 +1,54 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (https://www.swig.org). + * Version 4.2.1 + * + * Do not make changes to this file unless you know what you are doing - modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +package com.webank.wedpr.sdk.jni.generated; + +public class SharedErrorCallback { + private transient long swigCPtr; + protected transient boolean swigCMemOwn; + + protected SharedErrorCallback(long cPtr, boolean cMemoryOwn) { + swigCMemOwn = cMemoryOwn; + swigCPtr = cPtr; + } + + protected static long getCPtr(SharedErrorCallback obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } + + protected static long swigRelease(SharedErrorCallback obj) { + long ptr = 0; + if (obj != null) { + if (!obj.swigCMemOwn) + throw new RuntimeException("Cannot release ownership as memory is not owned"); + ptr = obj.swigCPtr; + obj.swigCMemOwn = false; + obj.delete(); + } + return ptr; + } + + @SuppressWarnings({"deprecation", "removal"}) + protected void finalize() { + delete(); + } + + public synchronized void delete() { + if (swigCPtr != 0) { + if (swigCMemOwn) { + swigCMemOwn = false; + wedpr_java_transportJNI.delete_SharedErrorCallback(swigCPtr); + } + swigCPtr = 0; + } + } + + public SharedErrorCallback() { + this(wedpr_java_transportJNI.new_SharedErrorCallback(), true); + } +} diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SharedFront.java b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SharedFront.java new file mode 100644 index 00000000..26f4d825 --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SharedFront.java @@ -0,0 +1,54 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (https://www.swig.org). + * Version 4.2.1 + * + * Do not make changes to this file unless you know what you are doing - modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +package com.webank.wedpr.sdk.jni.generated; + +public class SharedFront { + private transient long swigCPtr; + protected transient boolean swigCMemOwn; + + protected SharedFront(long cPtr, boolean cMemoryOwn) { + swigCMemOwn = cMemoryOwn; + swigCPtr = cPtr; + } + + protected static long getCPtr(SharedFront obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } + + protected static long swigRelease(SharedFront obj) { + long ptr = 0; + if (obj != null) { + if (!obj.swigCMemOwn) + throw new RuntimeException("Cannot release ownership as memory is not owned"); + ptr = obj.swigCPtr; + obj.swigCMemOwn = false; + obj.delete(); + } + return ptr; + } + + @SuppressWarnings({"deprecation", "removal"}) + protected void finalize() { + delete(); + } + + public synchronized void delete() { + if (swigCPtr != 0) { + if (swigCMemOwn) { + swigCMemOwn = false; + wedpr_java_transportJNI.delete_SharedFront(swigCPtr); + } + swigCPtr = 0; + } + } + + public SharedFront() { + this(wedpr_java_transportJNI.new_SharedFront(), true); + } +} diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SharedFrontClient.java b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SharedFrontClient.java new file mode 100644 index 00000000..0ae0e986 --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SharedFrontClient.java @@ -0,0 +1,54 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (https://www.swig.org). + * Version 4.2.1 + * + * Do not make changes to this file unless you know what you are doing - modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +package com.webank.wedpr.sdk.jni.generated; + +public class SharedFrontClient { + private transient long swigCPtr; + protected transient boolean swigCMemOwn; + + protected SharedFrontClient(long cPtr, boolean cMemoryOwn) { + swigCMemOwn = cMemoryOwn; + swigCPtr = cPtr; + } + + protected static long getCPtr(SharedFrontClient obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } + + protected static long swigRelease(SharedFrontClient obj) { + long ptr = 0; + if (obj != null) { + if (!obj.swigCMemOwn) + throw new RuntimeException("Cannot release ownership as memory is not owned"); + ptr = obj.swigCPtr; + obj.swigCMemOwn = false; + obj.delete(); + } + return ptr; + } + + @SuppressWarnings({"deprecation", "removal"}) + protected void finalize() { + delete(); + } + + public synchronized void delete() { + if (swigCPtr != 0) { + if (swigCMemOwn) { + swigCMemOwn = false; + wedpr_java_transportJNI.delete_SharedFrontClient(swigCPtr); + } + swigCPtr = 0; + } + } + + public SharedFrontClient() { + this(wedpr_java_transportJNI.new_SharedFrontClient(), true); + } +} diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SharedFrontConfig.java b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SharedFrontConfig.java new file mode 100644 index 00000000..a0d898ec --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SharedFrontConfig.java @@ -0,0 +1,54 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (https://www.swig.org). + * Version 4.2.1 + * + * Do not make changes to this file unless you know what you are doing - modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +package com.webank.wedpr.sdk.jni.generated; + +public class SharedFrontConfig { + private transient long swigCPtr; + protected transient boolean swigCMemOwn; + + protected SharedFrontConfig(long cPtr, boolean cMemoryOwn) { + swigCMemOwn = cMemoryOwn; + swigCPtr = cPtr; + } + + protected static long getCPtr(SharedFrontConfig obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } + + protected static long swigRelease(SharedFrontConfig obj) { + long ptr = 0; + if (obj != null) { + if (!obj.swigCMemOwn) + throw new RuntimeException("Cannot release ownership as memory is not owned"); + ptr = obj.swigCPtr; + obj.swigCMemOwn = false; + obj.delete(); + } + return ptr; + } + + @SuppressWarnings({"deprecation", "removal"}) + protected void finalize() { + delete(); + } + + public synchronized void delete() { + if (swigCPtr != 0) { + if (swigCMemOwn) { + swigCMemOwn = false; + wedpr_java_transportJNI.delete_SharedFrontConfig(swigCPtr); + } + swigCPtr = 0; + } + } + + public SharedFrontConfig() { + this(wedpr_java_transportJNI.new_SharedFrontConfig(), true); + } +} diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SharedGateway.java b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SharedGateway.java new file mode 100644 index 00000000..64ef6146 --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SharedGateway.java @@ -0,0 +1,54 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (https://www.swig.org). + * Version 4.2.1 + * + * Do not make changes to this file unless you know what you are doing - modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +package com.webank.wedpr.sdk.jni.generated; + +public class SharedGateway { + private transient long swigCPtr; + protected transient boolean swigCMemOwn; + + protected SharedGateway(long cPtr, boolean cMemoryOwn) { + swigCMemOwn = cMemoryOwn; + swigCPtr = cPtr; + } + + protected static long getCPtr(SharedGateway obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } + + protected static long swigRelease(SharedGateway obj) { + long ptr = 0; + if (obj != null) { + if (!obj.swigCMemOwn) + throw new RuntimeException("Cannot release ownership as memory is not owned"); + ptr = obj.swigCPtr; + obj.swigCMemOwn = false; + obj.delete(); + } + return ptr; + } + + @SuppressWarnings({"deprecation", "removal"}) + protected void finalize() { + delete(); + } + + public synchronized void delete() { + if (swigCPtr != 0) { + if (swigCMemOwn) { + swigCMemOwn = false; + wedpr_java_transportJNI.delete_SharedGateway(swigCPtr); + } + swigCPtr = 0; + } + } + + public SharedGateway() { + this(wedpr_java_transportJNI.new_SharedGateway(), true); + } +} diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SharedGetPeersInfoHandler.java b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SharedGetPeersInfoHandler.java new file mode 100644 index 00000000..a97f2ab9 --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SharedGetPeersInfoHandler.java @@ -0,0 +1,54 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (https://www.swig.org). + * Version 4.2.1 + * + * Do not make changes to this file unless you know what you are doing - modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +package com.webank.wedpr.sdk.jni.generated; + +public class SharedGetPeersInfoHandler { + private transient long swigCPtr; + protected transient boolean swigCMemOwn; + + protected SharedGetPeersInfoHandler(long cPtr, boolean cMemoryOwn) { + swigCMemOwn = cMemoryOwn; + swigCPtr = cPtr; + } + + protected static long getCPtr(SharedGetPeersInfoHandler obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } + + protected static long swigRelease(SharedGetPeersInfoHandler obj) { + long ptr = 0; + if (obj != null) { + if (!obj.swigCMemOwn) + throw new RuntimeException("Cannot release ownership as memory is not owned"); + ptr = obj.swigCPtr; + obj.swigCMemOwn = false; + obj.delete(); + } + return ptr; + } + + @SuppressWarnings({"deprecation", "removal"}) + protected void finalize() { + delete(); + } + + public synchronized void delete() { + if (swigCPtr != 0) { + if (swigCMemOwn) { + swigCMemOwn = false; + wedpr_java_transportJNI.delete_SharedGetPeersInfoHandler(swigCPtr); + } + swigCPtr = 0; + } + } + + public SharedGetPeersInfoHandler() { + this(wedpr_java_transportJNI.new_SharedGetPeersInfoHandler(), true); + } +} diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SharedGrpcConfig.java b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SharedGrpcConfig.java new file mode 100644 index 00000000..4bd5497c --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SharedGrpcConfig.java @@ -0,0 +1,54 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (https://www.swig.org). + * Version 4.2.1 + * + * Do not make changes to this file unless you know what you are doing - modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +package com.webank.wedpr.sdk.jni.generated; + +public class SharedGrpcConfig { + private transient long swigCPtr; + protected transient boolean swigCMemOwn; + + protected SharedGrpcConfig(long cPtr, boolean cMemoryOwn) { + swigCMemOwn = cMemoryOwn; + swigCPtr = cPtr; + } + + protected static long getCPtr(SharedGrpcConfig obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } + + protected static long swigRelease(SharedGrpcConfig obj) { + long ptr = 0; + if (obj != null) { + if (!obj.swigCMemOwn) + throw new RuntimeException("Cannot release ownership as memory is not owned"); + ptr = obj.swigCPtr; + obj.swigCMemOwn = false; + obj.delete(); + } + return ptr; + } + + @SuppressWarnings({"deprecation", "removal"}) + protected void finalize() { + delete(); + } + + public synchronized void delete() { + if (swigCPtr != 0) { + if (swigCMemOwn) { + swigCMemOwn = false; + wedpr_java_transportJNI.delete_SharedGrpcConfig(swigCPtr); + } + swigCPtr = 0; + } + } + + public SharedGrpcConfig() { + this(wedpr_java_transportJNI.new_SharedGrpcConfig(), true); + } +} diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SharedIMessageHandler.java b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SharedIMessageHandler.java new file mode 100644 index 00000000..45703dcd --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SharedIMessageHandler.java @@ -0,0 +1,54 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (https://www.swig.org). + * Version 4.2.1 + * + * Do not make changes to this file unless you know what you are doing - modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +package com.webank.wedpr.sdk.jni.generated; + +public class SharedIMessageHandler { + private transient long swigCPtr; + protected transient boolean swigCMemOwn; + + protected SharedIMessageHandler(long cPtr, boolean cMemoryOwn) { + swigCMemOwn = cMemoryOwn; + swigCPtr = cPtr; + } + + protected static long getCPtr(SharedIMessageHandler obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } + + protected static long swigRelease(SharedIMessageHandler obj) { + long ptr = 0; + if (obj != null) { + if (!obj.swigCMemOwn) + throw new RuntimeException("Cannot release ownership as memory is not owned"); + ptr = obj.swigCPtr; + obj.swigCMemOwn = false; + obj.delete(); + } + return ptr; + } + + @SuppressWarnings({"deprecation", "removal"}) + protected void finalize() { + delete(); + } + + public synchronized void delete() { + if (swigCPtr != 0) { + if (swigCMemOwn) { + swigCMemOwn = false; + wedpr_java_transportJNI.delete_SharedIMessageHandler(swigCPtr); + } + swigCPtr = 0; + } + } + + public SharedIMessageHandler() { + this(wedpr_java_transportJNI.new_SharedIMessageHandler(), true); + } +} diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SharedMessage.java b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SharedMessage.java new file mode 100644 index 00000000..4e30cedb --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SharedMessage.java @@ -0,0 +1,54 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (https://www.swig.org). + * Version 4.2.1 + * + * Do not make changes to this file unless you know what you are doing - modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +package com.webank.wedpr.sdk.jni.generated; + +public class SharedMessage { + private transient long swigCPtr; + protected transient boolean swigCMemOwn; + + protected SharedMessage(long cPtr, boolean cMemoryOwn) { + swigCMemOwn = cMemoryOwn; + swigCPtr = cPtr; + } + + protected static long getCPtr(SharedMessage obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } + + protected static long swigRelease(SharedMessage obj) { + long ptr = 0; + if (obj != null) { + if (!obj.swigCMemOwn) + throw new RuntimeException("Cannot release ownership as memory is not owned"); + ptr = obj.swigCPtr; + obj.swigCMemOwn = false; + obj.delete(); + } + return ptr; + } + + @SuppressWarnings({"deprecation", "removal"}) + protected void finalize() { + delete(); + } + + public synchronized void delete() { + if (swigCPtr != 0) { + if (swigCMemOwn) { + swigCMemOwn = false; + wedpr_java_transportJNI.delete_SharedMessage(swigCPtr); + } + swigCPtr = 0; + } + } + + public SharedMessage() { + this(wedpr_java_transportJNI.new_SharedMessage(), true); + } +} diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SharedMessageBuilder.java b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SharedMessageBuilder.java new file mode 100644 index 00000000..b45e5eff --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SharedMessageBuilder.java @@ -0,0 +1,54 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (https://www.swig.org). + * Version 4.2.1 + * + * Do not make changes to this file unless you know what you are doing - modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +package com.webank.wedpr.sdk.jni.generated; + +public class SharedMessageBuilder { + private transient long swigCPtr; + protected transient boolean swigCMemOwn; + + protected SharedMessageBuilder(long cPtr, boolean cMemoryOwn) { + swigCMemOwn = cMemoryOwn; + swigCPtr = cPtr; + } + + protected static long getCPtr(SharedMessageBuilder obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } + + protected static long swigRelease(SharedMessageBuilder obj) { + long ptr = 0; + if (obj != null) { + if (!obj.swigCMemOwn) + throw new RuntimeException("Cannot release ownership as memory is not owned"); + ptr = obj.swigCPtr; + obj.swigCMemOwn = false; + obj.delete(); + } + return ptr; + } + + @SuppressWarnings({"deprecation", "removal"}) + protected void finalize() { + delete(); + } + + public synchronized void delete() { + if (swigCPtr != 0) { + if (swigCMemOwn) { + swigCMemOwn = false; + wedpr_java_transportJNI.delete_SharedMessageBuilder(swigCPtr); + } + swigCPtr = 0; + } + } + + public SharedMessageBuilder() { + this(wedpr_java_transportJNI.new_SharedMessageBuilder(), true); + } +} diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SharedMessageDispatcherHandler.java b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SharedMessageDispatcherHandler.java new file mode 100644 index 00000000..6b3fd639 --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SharedMessageDispatcherHandler.java @@ -0,0 +1,54 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (https://www.swig.org). + * Version 4.2.1 + * + * Do not make changes to this file unless you know what you are doing - modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +package com.webank.wedpr.sdk.jni.generated; + +public class SharedMessageDispatcherHandler { + private transient long swigCPtr; + protected transient boolean swigCMemOwn; + + protected SharedMessageDispatcherHandler(long cPtr, boolean cMemoryOwn) { + swigCMemOwn = cMemoryOwn; + swigCPtr = cPtr; + } + + protected static long getCPtr(SharedMessageDispatcherHandler obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } + + protected static long swigRelease(SharedMessageDispatcherHandler obj) { + long ptr = 0; + if (obj != null) { + if (!obj.swigCMemOwn) + throw new RuntimeException("Cannot release ownership as memory is not owned"); + ptr = obj.swigCPtr; + obj.swigCMemOwn = false; + obj.delete(); + } + return ptr; + } + + @SuppressWarnings({"deprecation", "removal"}) + protected void finalize() { + delete(); + } + + public synchronized void delete() { + if (swigCPtr != 0) { + if (swigCMemOwn) { + swigCMemOwn = false; + wedpr_java_transportJNI.delete_SharedMessageDispatcherHandler(swigCPtr); + } + swigCPtr = 0; + } + } + + public SharedMessageDispatcherHandler() { + this(wedpr_java_transportJNI.new_SharedMessageDispatcherHandler(), true); + } +} diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SharedMessageHeader.java b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SharedMessageHeader.java new file mode 100644 index 00000000..7040dd6c --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SharedMessageHeader.java @@ -0,0 +1,54 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (https://www.swig.org). + * Version 4.2.1 + * + * Do not make changes to this file unless you know what you are doing - modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +package com.webank.wedpr.sdk.jni.generated; + +public class SharedMessageHeader { + private transient long swigCPtr; + protected transient boolean swigCMemOwn; + + protected SharedMessageHeader(long cPtr, boolean cMemoryOwn) { + swigCMemOwn = cMemoryOwn; + swigCPtr = cPtr; + } + + protected static long getCPtr(SharedMessageHeader obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } + + protected static long swigRelease(SharedMessageHeader obj) { + long ptr = 0; + if (obj != null) { + if (!obj.swigCMemOwn) + throw new RuntimeException("Cannot release ownership as memory is not owned"); + ptr = obj.swigCPtr; + obj.swigCMemOwn = false; + obj.delete(); + } + return ptr; + } + + @SuppressWarnings({"deprecation", "removal"}) + protected void finalize() { + delete(); + } + + public synchronized void delete() { + if (swigCPtr != 0) { + if (swigCMemOwn) { + swigCMemOwn = false; + wedpr_java_transportJNI.delete_SharedMessageHeader(swigCPtr); + } + swigCPtr = 0; + } + } + + public SharedMessageHeader() { + this(wedpr_java_transportJNI.new_SharedMessageHeader(), true); + } +} diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SharedMessageHeaderBuilder.java b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SharedMessageHeaderBuilder.java new file mode 100644 index 00000000..fc0464ed --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SharedMessageHeaderBuilder.java @@ -0,0 +1,54 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (https://www.swig.org). + * Version 4.2.1 + * + * Do not make changes to this file unless you know what you are doing - modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +package com.webank.wedpr.sdk.jni.generated; + +public class SharedMessageHeaderBuilder { + private transient long swigCPtr; + protected transient boolean swigCMemOwn; + + protected SharedMessageHeaderBuilder(long cPtr, boolean cMemoryOwn) { + swigCMemOwn = cMemoryOwn; + swigCPtr = cPtr; + } + + protected static long getCPtr(SharedMessageHeaderBuilder obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } + + protected static long swigRelease(SharedMessageHeaderBuilder obj) { + long ptr = 0; + if (obj != null) { + if (!obj.swigCMemOwn) + throw new RuntimeException("Cannot release ownership as memory is not owned"); + ptr = obj.swigCPtr; + obj.swigCMemOwn = false; + obj.delete(); + } + return ptr; + } + + @SuppressWarnings({"deprecation", "removal"}) + protected void finalize() { + delete(); + } + + public synchronized void delete() { + if (swigCPtr != 0) { + if (swigCMemOwn) { + swigCMemOwn = false; + wedpr_java_transportJNI.delete_SharedMessageHeaderBuilder(swigCPtr); + } + swigCPtr = 0; + } + } + + public SharedMessageHeaderBuilder() { + this(wedpr_java_transportJNI.new_SharedMessageHeaderBuilder(), true); + } +} diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SharedMessagePayload.java b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SharedMessagePayload.java new file mode 100644 index 00000000..6a52b280 --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SharedMessagePayload.java @@ -0,0 +1,54 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (https://www.swig.org). + * Version 4.2.1 + * + * Do not make changes to this file unless you know what you are doing - modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +package com.webank.wedpr.sdk.jni.generated; + +public class SharedMessagePayload { + private transient long swigCPtr; + protected transient boolean swigCMemOwn; + + protected SharedMessagePayload(long cPtr, boolean cMemoryOwn) { + swigCMemOwn = cMemoryOwn; + swigCPtr = cPtr; + } + + protected static long getCPtr(SharedMessagePayload obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } + + protected static long swigRelease(SharedMessagePayload obj) { + long ptr = 0; + if (obj != null) { + if (!obj.swigCMemOwn) + throw new RuntimeException("Cannot release ownership as memory is not owned"); + ptr = obj.swigCPtr; + obj.swigCMemOwn = false; + obj.delete(); + } + return ptr; + } + + @SuppressWarnings({"deprecation", "removal"}) + protected void finalize() { + delete(); + } + + public synchronized void delete() { + if (swigCPtr != 0) { + if (swigCMemOwn) { + swigCMemOwn = false; + wedpr_java_transportJNI.delete_SharedMessagePayload(swigCPtr); + } + swigCPtr = 0; + } + } + + public SharedMessagePayload() { + this(wedpr_java_transportJNI.new_SharedMessagePayload(), true); + } +} diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SharedMessagePayloadBuilder.java b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SharedMessagePayloadBuilder.java new file mode 100644 index 00000000..19b3a20a --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SharedMessagePayloadBuilder.java @@ -0,0 +1,54 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (https://www.swig.org). + * Version 4.2.1 + * + * Do not make changes to this file unless you know what you are doing - modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +package com.webank.wedpr.sdk.jni.generated; + +public class SharedMessagePayloadBuilder { + private transient long swigCPtr; + protected transient boolean swigCMemOwn; + + protected SharedMessagePayloadBuilder(long cPtr, boolean cMemoryOwn) { + swigCMemOwn = cMemoryOwn; + swigCPtr = cPtr; + } + + protected static long getCPtr(SharedMessagePayloadBuilder obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } + + protected static long swigRelease(SharedMessagePayloadBuilder obj) { + long ptr = 0; + if (obj != null) { + if (!obj.swigCMemOwn) + throw new RuntimeException("Cannot release ownership as memory is not owned"); + ptr = obj.swigCPtr; + obj.swigCMemOwn = false; + obj.delete(); + } + return ptr; + } + + @SuppressWarnings({"deprecation", "removal"}) + protected void finalize() { + delete(); + } + + public synchronized void delete() { + if (swigCPtr != 0) { + if (swigCMemOwn) { + swigCMemOwn = false; + wedpr_java_transportJNI.delete_SharedMessagePayloadBuilder(swigCPtr); + } + swigCPtr = 0; + } + } + + public SharedMessagePayloadBuilder() { + this(wedpr_java_transportJNI.new_SharedMessagePayloadBuilder(), true); + } +} diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SharedNodeDiscovery.java b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SharedNodeDiscovery.java new file mode 100644 index 00000000..4b6e0677 --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SharedNodeDiscovery.java @@ -0,0 +1,54 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (https://www.swig.org). + * Version 4.2.1 + * + * Do not make changes to this file unless you know what you are doing - modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +package com.webank.wedpr.sdk.jni.generated; + +public class SharedNodeDiscovery { + private transient long swigCPtr; + protected transient boolean swigCMemOwn; + + protected SharedNodeDiscovery(long cPtr, boolean cMemoryOwn) { + swigCMemOwn = cMemoryOwn; + swigCPtr = cPtr; + } + + protected static long getCPtr(SharedNodeDiscovery obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } + + protected static long swigRelease(SharedNodeDiscovery obj) { + long ptr = 0; + if (obj != null) { + if (!obj.swigCMemOwn) + throw new RuntimeException("Cannot release ownership as memory is not owned"); + ptr = obj.swigCPtr; + obj.swigCMemOwn = false; + obj.delete(); + } + return ptr; + } + + @SuppressWarnings({"deprecation", "removal"}) + protected void finalize() { + delete(); + } + + public synchronized void delete() { + if (swigCPtr != 0) { + if (swigCMemOwn) { + swigCMemOwn = false; + wedpr_java_transportJNI.delete_SharedNodeDiscovery(swigCPtr); + } + swigCPtr = 0; + } + } + + public SharedNodeDiscovery() { + this(wedpr_java_transportJNI.new_SharedNodeDiscovery(), true); + } +} diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SharedNodeInfo.java b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SharedNodeInfo.java new file mode 100644 index 00000000..09fb7ce3 --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SharedNodeInfo.java @@ -0,0 +1,54 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (https://www.swig.org). + * Version 4.2.1 + * + * Do not make changes to this file unless you know what you are doing - modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +package com.webank.wedpr.sdk.jni.generated; + +public class SharedNodeInfo { + private transient long swigCPtr; + protected transient boolean swigCMemOwn; + + protected SharedNodeInfo(long cPtr, boolean cMemoryOwn) { + swigCMemOwn = cMemoryOwn; + swigCPtr = cPtr; + } + + protected static long getCPtr(SharedNodeInfo obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } + + protected static long swigRelease(SharedNodeInfo obj) { + long ptr = 0; + if (obj != null) { + if (!obj.swigCMemOwn) + throw new RuntimeException("Cannot release ownership as memory is not owned"); + ptr = obj.swigCPtr; + obj.swigCMemOwn = false; + obj.delete(); + } + return ptr; + } + + @SuppressWarnings({"deprecation", "removal"}) + protected void finalize() { + delete(); + } + + public synchronized void delete() { + if (swigCPtr != 0) { + if (swigCMemOwn) { + swigCMemOwn = false; + wedpr_java_transportJNI.delete_SharedNodeInfo(swigCPtr); + } + swigCPtr = 0; + } + } + + public SharedNodeInfo() { + this(wedpr_java_transportJNI.new_SharedNodeInfo(), true); + } +} diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SharedRouteInfo.java b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SharedRouteInfo.java new file mode 100644 index 00000000..d3ae668b --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SharedRouteInfo.java @@ -0,0 +1,54 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (https://www.swig.org). + * Version 4.2.1 + * + * Do not make changes to this file unless you know what you are doing - modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +package com.webank.wedpr.sdk.jni.generated; + +public class SharedRouteInfo { + private transient long swigCPtr; + protected transient boolean swigCMemOwn; + + protected SharedRouteInfo(long cPtr, boolean cMemoryOwn) { + swigCMemOwn = cMemoryOwn; + swigCPtr = cPtr; + } + + protected static long getCPtr(SharedRouteInfo obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } + + protected static long swigRelease(SharedRouteInfo obj) { + long ptr = 0; + if (obj != null) { + if (!obj.swigCMemOwn) + throw new RuntimeException("Cannot release ownership as memory is not owned"); + ptr = obj.swigCPtr; + obj.swigCMemOwn = false; + obj.delete(); + } + return ptr; + } + + @SuppressWarnings({"deprecation", "removal"}) + protected void finalize() { + delete(); + } + + public synchronized void delete() { + if (swigCPtr != 0) { + if (swigCMemOwn) { + swigCMemOwn = false; + wedpr_java_transportJNI.delete_SharedRouteInfo(swigCPtr); + } + swigCPtr = 0; + } + } + + public SharedRouteInfo() { + this(wedpr_java_transportJNI.new_SharedRouteInfo(), true); + } +} diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SharedRouteInfoBuilder.java b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SharedRouteInfoBuilder.java new file mode 100644 index 00000000..7cec4144 --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/SharedRouteInfoBuilder.java @@ -0,0 +1,54 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (https://www.swig.org). + * Version 4.2.1 + * + * Do not make changes to this file unless you know what you are doing - modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +package com.webank.wedpr.sdk.jni.generated; + +public class SharedRouteInfoBuilder { + private transient long swigCPtr; + protected transient boolean swigCMemOwn; + + protected SharedRouteInfoBuilder(long cPtr, boolean cMemoryOwn) { + swigCMemOwn = cMemoryOwn; + swigCPtr = cPtr; + } + + protected static long getCPtr(SharedRouteInfoBuilder obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } + + protected static long swigRelease(SharedRouteInfoBuilder obj) { + long ptr = 0; + if (obj != null) { + if (!obj.swigCMemOwn) + throw new RuntimeException("Cannot release ownership as memory is not owned"); + ptr = obj.swigCPtr; + obj.swigCMemOwn = false; + obj.delete(); + } + return ptr; + } + + @SuppressWarnings({"deprecation", "removal"}) + protected void finalize() { + delete(); + } + + public synchronized void delete() { + if (swigCPtr != 0) { + if (swigCMemOwn) { + swigCMemOwn = false; + wedpr_java_transportJNI.delete_SharedRouteInfoBuilder(swigCPtr); + } + swigCPtr = 0; + } + } + + public SharedRouteInfoBuilder() { + this(wedpr_java_transportJNI.new_SharedRouteInfoBuilder(), true); + } +} diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/StringVec.java b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/StringVec.java new file mode 100644 index 00000000..1138ae64 --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/StringVec.java @@ -0,0 +1,163 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (https://www.swig.org). + * Version 4.2.1 + * + * Do not make changes to this file unless you know what you are doing - modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +package com.webank.wedpr.sdk.jni.generated; + +public class StringVec extends java.util.AbstractList implements java.util.RandomAccess { + private transient long swigCPtr; + protected transient boolean swigCMemOwn; + + protected StringVec(long cPtr, boolean cMemoryOwn) { + swigCMemOwn = cMemoryOwn; + swigCPtr = cPtr; + } + + protected static long getCPtr(StringVec obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } + + protected static long swigRelease(StringVec obj) { + long ptr = 0; + if (obj != null) { + if (!obj.swigCMemOwn) + throw new RuntimeException("Cannot release ownership as memory is not owned"); + ptr = obj.swigCPtr; + obj.swigCMemOwn = false; + obj.delete(); + } + return ptr; + } + + @SuppressWarnings({"deprecation", "removal"}) + protected void finalize() { + delete(); + } + + public synchronized void delete() { + if (swigCPtr != 0) { + if (swigCMemOwn) { + swigCMemOwn = false; + wedpr_java_transportJNI.delete_StringVec(swigCPtr); + } + swigCPtr = 0; + } + } + + public StringVec(String[] initialElements) { + this(); + reserve(initialElements.length); + + for (String element : initialElements) { + add(element); + } + } + + public StringVec(Iterable initialElements) { + this(); + for (String element : initialElements) { + add(element); + } + } + + public String get(int index) { + return doGet(index); + } + + public String set(int index, String e) { + return doSet(index, e); + } + + public boolean add(String e) { + modCount++; + doAdd(e); + return true; + } + + public void add(int index, String e) { + modCount++; + doAdd(index, e); + } + + public String remove(int index) { + modCount++; + return doRemove(index); + } + + protected void removeRange(int fromIndex, int toIndex) { + modCount++; + doRemoveRange(fromIndex, toIndex); + } + + public int size() { + return doSize(); + } + + public int capacity() { + return doCapacity(); + } + + public void reserve(int n) { + doReserve(n); + } + + public StringVec() { + this(wedpr_java_transportJNI.new_StringVec__SWIG_0(), true); + } + + public StringVec(StringVec other) { + this(wedpr_java_transportJNI.new_StringVec__SWIG_1(StringVec.getCPtr(other), other), true); + } + + public boolean isEmpty() { + return wedpr_java_transportJNI.StringVec_isEmpty(swigCPtr, this); + } + + public void clear() { + wedpr_java_transportJNI.StringVec_clear(swigCPtr, this); + } + + public StringVec(int count, String value) { + this(wedpr_java_transportJNI.new_StringVec__SWIG_2(count, value), true); + } + + private int doCapacity() { + return wedpr_java_transportJNI.StringVec_doCapacity(swigCPtr, this); + } + + private void doReserve(int n) { + wedpr_java_transportJNI.StringVec_doReserve(swigCPtr, this, n); + } + + private int doSize() { + return wedpr_java_transportJNI.StringVec_doSize(swigCPtr, this); + } + + private void doAdd(String x) { + wedpr_java_transportJNI.StringVec_doAdd__SWIG_0(swigCPtr, this, x); + } + + private void doAdd(int index, String x) { + wedpr_java_transportJNI.StringVec_doAdd__SWIG_1(swigCPtr, this, index, x); + } + + private String doRemove(int index) { + return wedpr_java_transportJNI.StringVec_doRemove(swigCPtr, this, index); + } + + private String doGet(int index) { + return wedpr_java_transportJNI.StringVec_doGet(swigCPtr, this, index); + } + + private String doSet(int index, String val) { + return wedpr_java_transportJNI.StringVec_doSet(swigCPtr, this, index, val); + } + + private void doRemoveRange(int fromIndex, int toIndex) { + wedpr_java_transportJNI.StringVec_doRemoveRange(swigCPtr, this, fromIndex, toIndex); + } +} diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/Transport.java b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/Transport.java new file mode 100644 index 00000000..170e3992 --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/Transport.java @@ -0,0 +1,93 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (https://www.swig.org). + * Version 4.2.1 + * + * Do not make changes to this file unless you know what you are doing - modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +package com.webank.wedpr.sdk.jni.generated; + +public class Transport { + private transient long swigCPtr; + private transient boolean swigCMemOwn; + + protected Transport(long cPtr, boolean cMemoryOwn) { + swigCMemOwn = cMemoryOwn; + swigCPtr = cPtr; + } + + protected static long getCPtr(Transport obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } + + protected void swigSetCMemOwn(boolean own) { + swigCMemOwn = own; + } + + @SuppressWarnings({"deprecation", "removal"}) + protected void finalize() { + delete(); + } + + public synchronized void delete() { + if (swigCPtr != 0) { + if (swigCMemOwn) { + swigCMemOwn = false; + wedpr_java_transportJNI.delete_Transport(swigCPtr); + } + swigCPtr = 0; + } + } + + public Transport(FrontConfig config) { + this(wedpr_java_transportJNI.new_Transport(FrontConfig.getCPtr(config), config), true); + } + + public void start() { + wedpr_java_transportJNI.Transport_start(swigCPtr, this); + } + + public void stop() { + wedpr_java_transportJNI.Transport_stop(swigCPtr, this); + } + + public IFront getFront() { + long cPtr = wedpr_java_transportJNI.Transport_getFront(swigCPtr, this); + return (cPtr == 0) ? null : new IFront(cPtr, true); + } + + public SWIGTYPE_p_ppc__gateway__IGateway__Ptr gateway() { + return new SWIGTYPE_p_ppc__gateway__IGateway__Ptr( + wedpr_java_transportJNI.Transport_gateway(swigCPtr, this), false); + } + + public MessagePayloadBuilder msgPayloadBuilder() { + long cPtr = wedpr_java_transportJNI.Transport_msgPayloadBuilder(swigCPtr, this); + return (cPtr == 0) ? null : new MessagePayloadBuilder(cPtr, true); + } + + public MessageBuilder msgBuilder() { + long cPtr = wedpr_java_transportJNI.Transport_msgBuilder(swigCPtr, this); + return (cPtr == 0) ? null : new MessageBuilder(cPtr, true); + } + + public MessageHeaderBuilder msgHeaderBuilder() { + long cPtr = wedpr_java_transportJNI.Transport_msgHeaderBuilder(swigCPtr, this); + return (cPtr == 0) ? null : new MessageHeaderBuilder(cPtr, true); + } + + public MessageOptionalHeaderBuilder routeInfoBuilder() { + long cPtr = wedpr_java_transportJNI.Transport_routeInfoBuilder(swigCPtr, this); + return (cPtr == 0) ? null : new MessageOptionalHeaderBuilder(cPtr, true); + } + + public FrontConfig getConfig() { + long cPtr = wedpr_java_transportJNI.Transport_getConfig(swigCPtr, this); + return (cPtr == 0) ? null : new FrontConfig(cPtr, true); + } + + public void disOwnMemory() { + swigSetCMemOwn(false); + } +} diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/TransportBuilder.java b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/TransportBuilder.java new file mode 100644 index 00000000..6ca4be2c --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/TransportBuilder.java @@ -0,0 +1,77 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (https://www.swig.org). + * Version 4.2.1 + * + * Do not make changes to this file unless you know what you are doing - modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +package com.webank.wedpr.sdk.jni.generated; + +public class TransportBuilder { + private transient long swigCPtr; + protected transient boolean swigCMemOwn; + + protected TransportBuilder(long cPtr, boolean cMemoryOwn) { + swigCMemOwn = cMemoryOwn; + swigCPtr = cPtr; + } + + protected static long getCPtr(TransportBuilder obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } + + protected static long swigRelease(TransportBuilder obj) { + long ptr = 0; + if (obj != null) { + if (!obj.swigCMemOwn) + throw new RuntimeException("Cannot release ownership as memory is not owned"); + ptr = obj.swigCPtr; + obj.swigCMemOwn = false; + obj.delete(); + } + return ptr; + } + + @SuppressWarnings({"deprecation", "removal"}) + protected void finalize() { + delete(); + } + + public synchronized void delete() { + if (swigCPtr != 0) { + if (swigCMemOwn) { + swigCMemOwn = false; + wedpr_java_transportJNI.delete_TransportBuilder(swigCPtr); + } + swigCPtr = 0; + } + } + + public TransportBuilder() { + this(wedpr_java_transportJNI.new_TransportBuilder(), true); + } + + public Transport buildProTransport(FrontConfig config) { + long cPtr = + wedpr_java_transportJNI.TransportBuilder_buildProTransport( + swigCPtr, this, FrontConfig.getCPtr(config), config); + return (cPtr == 0) ? null : new Transport(cPtr, true); + } + + public FrontConfig buildConfig(int threadPoolSize, String nodeID) { + long cPtr = + wedpr_java_transportJNI.TransportBuilder_buildConfig( + swigCPtr, this, threadPoolSize, nodeID); + return (cPtr == 0) ? null : new FrontConfig(cPtr, true); + } + + public SWIGTYPE_p_std__shared_ptrT_ppc__front__FrontConfigBuilder_t frontConfigBuilder() { + return new SWIGTYPE_p_std__shared_ptrT_ppc__front__FrontConfigBuilder_t( + wedpr_java_transportJNI.TransportBuilder_frontConfigBuilder(swigCPtr, this), false); + } + + public void initLog(String configPath) { + wedpr_java_transportJNI.TransportBuilder_initLog(swigCPtr, this, configPath); + } +} diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/ibytes.java b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/ibytes.java new file mode 100644 index 00000000..8b48eaf1 --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/ibytes.java @@ -0,0 +1,163 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (https://www.swig.org). + * Version 4.2.1 + * + * Do not make changes to this file unless you know what you are doing - modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +package com.webank.wedpr.sdk.jni.generated; + +public class ibytes extends java.util.AbstractList implements java.util.RandomAccess { + private transient long swigCPtr; + protected transient boolean swigCMemOwn; + + protected ibytes(long cPtr, boolean cMemoryOwn) { + swigCMemOwn = cMemoryOwn; + swigCPtr = cPtr; + } + + protected static long getCPtr(ibytes obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } + + protected static long swigRelease(ibytes obj) { + long ptr = 0; + if (obj != null) { + if (!obj.swigCMemOwn) + throw new RuntimeException("Cannot release ownership as memory is not owned"); + ptr = obj.swigCPtr; + obj.swigCMemOwn = false; + obj.delete(); + } + return ptr; + } + + @SuppressWarnings({"deprecation", "removal"}) + protected void finalize() { + delete(); + } + + public synchronized void delete() { + if (swigCPtr != 0) { + if (swigCMemOwn) { + swigCMemOwn = false; + wedpr_java_transportJNI.delete_ibytes(swigCPtr); + } + swigCPtr = 0; + } + } + + public ibytes(byte[] initialElements) { + this(); + reserve(initialElements.length); + + for (byte element : initialElements) { + add(element); + } + } + + public ibytes(Iterable initialElements) { + this(); + for (byte element : initialElements) { + add(element); + } + } + + public Byte get(int index) { + return doGet(index); + } + + public Byte set(int index, Byte e) { + return doSet(index, e); + } + + public boolean add(Byte e) { + modCount++; + doAdd(e); + return true; + } + + public void add(int index, Byte e) { + modCount++; + doAdd(index, e); + } + + public Byte remove(int index) { + modCount++; + return doRemove(index); + } + + protected void removeRange(int fromIndex, int toIndex) { + modCount++; + doRemoveRange(fromIndex, toIndex); + } + + public int size() { + return doSize(); + } + + public int capacity() { + return doCapacity(); + } + + public void reserve(int n) { + doReserve(n); + } + + public ibytes() { + this(wedpr_java_transportJNI.new_ibytes__SWIG_0(), true); + } + + public ibytes(ibytes other) { + this(wedpr_java_transportJNI.new_ibytes__SWIG_1(ibytes.getCPtr(other), other), true); + } + + public boolean isEmpty() { + return wedpr_java_transportJNI.ibytes_isEmpty(swigCPtr, this); + } + + public void clear() { + wedpr_java_transportJNI.ibytes_clear(swigCPtr, this); + } + + public ibytes(int count, byte value) { + this(wedpr_java_transportJNI.new_ibytes__SWIG_2(count, value), true); + } + + private int doCapacity() { + return wedpr_java_transportJNI.ibytes_doCapacity(swigCPtr, this); + } + + private void doReserve(int n) { + wedpr_java_transportJNI.ibytes_doReserve(swigCPtr, this, n); + } + + private int doSize() { + return wedpr_java_transportJNI.ibytes_doSize(swigCPtr, this); + } + + private void doAdd(byte x) { + wedpr_java_transportJNI.ibytes_doAdd__SWIG_0(swigCPtr, this, x); + } + + private void doAdd(int index, byte x) { + wedpr_java_transportJNI.ibytes_doAdd__SWIG_1(swigCPtr, this, index, x); + } + + private byte doRemove(int index) { + return wedpr_java_transportJNI.ibytes_doRemove(swigCPtr, this, index); + } + + private byte doGet(int index) { + return wedpr_java_transportJNI.ibytes_doGet(swigCPtr, this, index); + } + + private byte doSet(int index, byte val) { + return wedpr_java_transportJNI.ibytes_doSet(swigCPtr, this, index, val); + } + + private void doRemoveRange(int fromIndex, int toIndex) { + wedpr_java_transportJNI.ibytes_doRemoveRange(swigCPtr, this, fromIndex, toIndex); + } +} diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/ubytes.java b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/ubytes.java new file mode 100644 index 00000000..38c274e0 --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/ubytes.java @@ -0,0 +1,163 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (https://www.swig.org). + * Version 4.2.1 + * + * Do not make changes to this file unless you know what you are doing - modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +package com.webank.wedpr.sdk.jni.generated; + +public class ubytes extends java.util.AbstractList implements java.util.RandomAccess { + private transient long swigCPtr; + protected transient boolean swigCMemOwn; + + protected ubytes(long cPtr, boolean cMemoryOwn) { + swigCMemOwn = cMemoryOwn; + swigCPtr = cPtr; + } + + protected static long getCPtr(ubytes obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } + + protected static long swigRelease(ubytes obj) { + long ptr = 0; + if (obj != null) { + if (!obj.swigCMemOwn) + throw new RuntimeException("Cannot release ownership as memory is not owned"); + ptr = obj.swigCPtr; + obj.swigCMemOwn = false; + obj.delete(); + } + return ptr; + } + + @SuppressWarnings({"deprecation", "removal"}) + protected void finalize() { + delete(); + } + + public synchronized void delete() { + if (swigCPtr != 0) { + if (swigCMemOwn) { + swigCMemOwn = false; + wedpr_java_transportJNI.delete_ubytes(swigCPtr); + } + swigCPtr = 0; + } + } + + public ubytes(short[] initialElements) { + this(); + reserve(initialElements.length); + + for (short element : initialElements) { + add(element); + } + } + + public ubytes(Iterable initialElements) { + this(); + for (short element : initialElements) { + add(element); + } + } + + public Short get(int index) { + return doGet(index); + } + + public Short set(int index, Short e) { + return doSet(index, e); + } + + public boolean add(Short e) { + modCount++; + doAdd(e); + return true; + } + + public void add(int index, Short e) { + modCount++; + doAdd(index, e); + } + + public Short remove(int index) { + modCount++; + return doRemove(index); + } + + protected void removeRange(int fromIndex, int toIndex) { + modCount++; + doRemoveRange(fromIndex, toIndex); + } + + public int size() { + return doSize(); + } + + public int capacity() { + return doCapacity(); + } + + public void reserve(int n) { + doReserve(n); + } + + public ubytes() { + this(wedpr_java_transportJNI.new_ubytes__SWIG_0(), true); + } + + public ubytes(ubytes other) { + this(wedpr_java_transportJNI.new_ubytes__SWIG_1(ubytes.getCPtr(other), other), true); + } + + public boolean isEmpty() { + return wedpr_java_transportJNI.ubytes_isEmpty(swigCPtr, this); + } + + public void clear() { + wedpr_java_transportJNI.ubytes_clear(swigCPtr, this); + } + + public ubytes(int count, short value) { + this(wedpr_java_transportJNI.new_ubytes__SWIG_2(count, value), true); + } + + private int doCapacity() { + return wedpr_java_transportJNI.ubytes_doCapacity(swigCPtr, this); + } + + private void doReserve(int n) { + wedpr_java_transportJNI.ubytes_doReserve(swigCPtr, this, n); + } + + private int doSize() { + return wedpr_java_transportJNI.ubytes_doSize(swigCPtr, this); + } + + private void doAdd(short x) { + wedpr_java_transportJNI.ubytes_doAdd__SWIG_0(swigCPtr, this, x); + } + + private void doAdd(int index, short x) { + wedpr_java_transportJNI.ubytes_doAdd__SWIG_1(swigCPtr, this, index, x); + } + + private short doRemove(int index) { + return wedpr_java_transportJNI.ubytes_doRemove(swigCPtr, this, index); + } + + private short doGet(int index) { + return wedpr_java_transportJNI.ubytes_doGet(swigCPtr, this, index); + } + + private short doSet(int index, short val) { + return wedpr_java_transportJNI.ubytes_doSet(swigCPtr, this, index, val); + } + + private void doRemoveRange(int fromIndex, int toIndex) { + wedpr_java_transportJNI.ubytes_doRemoveRange(swigCPtr, this, fromIndex, toIndex); + } +} diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/wedpr_java_transport.java b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/wedpr_java_transport.java new file mode 100644 index 00000000..5143b6ce --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/wedpr_java_transport.java @@ -0,0 +1,32 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (https://www.swig.org). + * Version 4.2.1 + * + * Do not make changes to this file unless you know what you are doing - modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +package com.webank.wedpr.sdk.jni.generated; + +public class wedpr_java_transport { + public static String printFrontDesc(FrontConfig config) { + return wedpr_java_transportJNI.printFrontDesc(FrontConfig.getCPtr(config), config); + } + + public static String printGrpcConfig(GrpcConfig grpcConfig) { + return wedpr_java_transportJNI.printGrpcConfig(GrpcConfig.getCPtr(grpcConfig), grpcConfig); + } + + public static String printOptionalField(MessageOptionalHeader optionalHeader) { + return wedpr_java_transportJNI.printOptionalField( + MessageOptionalHeader.getCPtr(optionalHeader), optionalHeader); + } + + public static String printMessage(Message _msg) { + return wedpr_java_transportJNI.printMessage(Message.getCPtr(_msg), _msg); + } + + public static String printNodeInfo(INodeInfo nodeInfo) { + return wedpr_java_transportJNI.printNodeInfo(INodeInfo.getCPtr(nodeInfo), nodeInfo); + } +} diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/wedpr_java_transportJNI.java b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/wedpr_java_transportJNI.java new file mode 100644 index 00000000..6899432c --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/generated/wedpr_java_transportJNI.java @@ -0,0 +1,939 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (https://www.swig.org). + * Version 4.2.1 + * + * Do not make changes to this file unless you know what you are doing - modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +package com.webank.wedpr.sdk.jni.generated; + +public class wedpr_java_transportJNI { + public static final native long new_SharedBcosError(); + + public static final native void delete_SharedBcosError(long jarg1); + + public static final native long new_SharedFrontConfig(); + + public static final native void delete_SharedFrontConfig(long jarg1); + + public static final native long new_SharedGrpcConfig(); + + public static final native void delete_SharedGrpcConfig(long jarg1); + + public static final native long new_SharedFront(); + + public static final native void delete_SharedFront(long jarg1); + + public static final native long new_SharedNodeDiscovery(); + + public static final native void delete_SharedNodeDiscovery(long jarg1); + + public static final native long new_SharedFrontClient(); + + public static final native void delete_SharedFrontClient(long jarg1); + + public static final native long new_SharedErrorCallback(); + + public static final native void delete_SharedErrorCallback(long jarg1); + + public static final native long new_SharedMessageDispatcherHandler(); + + public static final native void delete_SharedMessageDispatcherHandler(long jarg1); + + public static final native long new_SharedIMessageHandler(); + + public static final native void delete_SharedIMessageHandler(long jarg1); + + public static final native long new_SharedGetPeersInfoHandler(); + + public static final native void delete_SharedGetPeersInfoHandler(long jarg1); + + public static final native long new_SharedGateway(); + + public static final native void delete_SharedGateway(long jarg1); + + public static final native long new_SharedMessage(); + + public static final native void delete_SharedMessage(long jarg1); + + public static final native long new_SharedMessageHeader(); + + public static final native void delete_SharedMessageHeader(long jarg1); + + public static final native long new_SharedMessagePayload(); + + public static final native void delete_SharedMessagePayload(long jarg1); + + public static final native long new_SharedRouteInfo(); + + public static final native void delete_SharedRouteInfo(long jarg1); + + public static final native long new_SharedMessageBuilder(); + + public static final native void delete_SharedMessageBuilder(long jarg1); + + public static final native long new_SharedMessageHeaderBuilder(); + + public static final native void delete_SharedMessageHeaderBuilder(long jarg1); + + public static final native long new_SharedMessagePayloadBuilder(); + + public static final native void delete_SharedMessagePayloadBuilder(long jarg1); + + public static final native long new_SharedRouteInfoBuilder(); + + public static final native void delete_SharedRouteInfoBuilder(long jarg1); + + public static final native long new_SharedNodeInfo(); + + public static final native void delete_SharedNodeInfo(long jarg1); + + public static final native long new_ubytes__SWIG_0(); + + public static final native long new_ubytes__SWIG_1(long jarg1, ubytes jarg1_); + + public static final native boolean ubytes_isEmpty(long jarg1, ubytes jarg1_); + + public static final native void ubytes_clear(long jarg1, ubytes jarg1_); + + public static final native long new_ubytes__SWIG_2(int jarg1, short jarg2); + + public static final native int ubytes_doCapacity(long jarg1, ubytes jarg1_); + + public static final native void ubytes_doReserve(long jarg1, ubytes jarg1_, int jarg2); + + public static final native int ubytes_doSize(long jarg1, ubytes jarg1_); + + public static final native void ubytes_doAdd__SWIG_0(long jarg1, ubytes jarg1_, short jarg2); + + public static final native void ubytes_doAdd__SWIG_1( + long jarg1, ubytes jarg1_, int jarg2, short jarg3); + + public static final native short ubytes_doRemove(long jarg1, ubytes jarg1_, int jarg2); + + public static final native short ubytes_doGet(long jarg1, ubytes jarg1_, int jarg2); + + public static final native short ubytes_doSet( + long jarg1, ubytes jarg1_, int jarg2, short jarg3); + + public static final native void ubytes_doRemoveRange( + long jarg1, ubytes jarg1_, int jarg2, int jarg3); + + public static final native void delete_ubytes(long jarg1); + + public static final native long new_ibytes__SWIG_0(); + + public static final native long new_ibytes__SWIG_1(long jarg1, ibytes jarg1_); + + public static final native boolean ibytes_isEmpty(long jarg1, ibytes jarg1_); + + public static final native void ibytes_clear(long jarg1, ibytes jarg1_); + + public static final native long new_ibytes__SWIG_2(int jarg1, byte jarg2); + + public static final native int ibytes_doCapacity(long jarg1, ibytes jarg1_); + + public static final native void ibytes_doReserve(long jarg1, ibytes jarg1_, int jarg2); + + public static final native int ibytes_doSize(long jarg1, ibytes jarg1_); + + public static final native void ibytes_doAdd__SWIG_0(long jarg1, ibytes jarg1_, byte jarg2); + + public static final native void ibytes_doAdd__SWIG_1( + long jarg1, ibytes jarg1_, int jarg2, byte jarg3); + + public static final native byte ibytes_doRemove(long jarg1, ibytes jarg1_, int jarg2); + + public static final native byte ibytes_doGet(long jarg1, ibytes jarg1_, int jarg2); + + public static final native byte ibytes_doSet(long jarg1, ibytes jarg1_, int jarg2, byte jarg3); + + public static final native void ibytes_doRemoveRange( + long jarg1, ibytes jarg1_, int jarg2, int jarg3); + + public static final native void delete_ibytes(long jarg1); + + public static final native long new_StringVec__SWIG_0(); + + public static final native long new_StringVec__SWIG_1(long jarg1, StringVec jarg1_); + + public static final native boolean StringVec_isEmpty(long jarg1, StringVec jarg1_); + + public static final native void StringVec_clear(long jarg1, StringVec jarg1_); + + public static final native long new_StringVec__SWIG_2(int jarg1, String jarg2); + + public static final native int StringVec_doCapacity(long jarg1, StringVec jarg1_); + + public static final native void StringVec_doReserve(long jarg1, StringVec jarg1_, int jarg2); + + public static final native int StringVec_doSize(long jarg1, StringVec jarg1_); + + public static final native void StringVec_doAdd__SWIG_0( + long jarg1, StringVec jarg1_, String jarg2); + + public static final native void StringVec_doAdd__SWIG_1( + long jarg1, StringVec jarg1_, int jarg2, String jarg3); + + public static final native String StringVec_doRemove(long jarg1, StringVec jarg1_, int jarg2); + + public static final native String StringVec_doGet(long jarg1, StringVec jarg1_, int jarg2); + + public static final native String StringVec_doSet( + long jarg1, StringVec jarg1_, int jarg2, String jarg3); + + public static final native void StringVec_doRemoveRange( + long jarg1, StringVec jarg1_, int jarg2, int jarg3); + + public static final native void delete_StringVec(long jarg1); + + public static final native long new_NodeInfoVec__SWIG_0(); + + public static final native long new_NodeInfoVec__SWIG_1(long jarg1, NodeInfoVec jarg1_); + + public static final native boolean NodeInfoVec_isEmpty(long jarg1, NodeInfoVec jarg1_); + + public static final native void NodeInfoVec_clear(long jarg1, NodeInfoVec jarg1_); + + public static final native long new_NodeInfoVec__SWIG_2( + int jarg1, long jarg2, INodeInfo jarg2_); + + public static final native int NodeInfoVec_doCapacity(long jarg1, NodeInfoVec jarg1_); + + public static final native void NodeInfoVec_doReserve( + long jarg1, NodeInfoVec jarg1_, int jarg2); + + public static final native int NodeInfoVec_doSize(long jarg1, NodeInfoVec jarg1_); + + public static final native void NodeInfoVec_doAdd__SWIG_0( + long jarg1, NodeInfoVec jarg1_, long jarg2, INodeInfo jarg2_); + + public static final native void NodeInfoVec_doAdd__SWIG_1( + long jarg1, NodeInfoVec jarg1_, int jarg2, long jarg3, INodeInfo jarg3_); + + public static final native long NodeInfoVec_doRemove(long jarg1, NodeInfoVec jarg1_, int jarg2); + + public static final native long NodeInfoVec_doGet(long jarg1, NodeInfoVec jarg1_, int jarg2); + + public static final native long NodeInfoVec_doSet( + long jarg1, NodeInfoVec jarg1_, int jarg2, long jarg3, INodeInfo jarg3_); + + public static final native void NodeInfoVec_doRemoveRange( + long jarg1, NodeInfoVec jarg1_, int jarg2, int jarg3); + + public static final native void delete_NodeInfoVec(long jarg1); + + public static final native long Error_buildError__SWIG_0( + byte[] jarg1, byte[] jarg2, int jarg3, int jarg4, String jarg5); + + public static final native long Error_buildError__SWIG_1( + byte[] jarg1, + byte[] jarg2, + int jarg3, + int jarg4, + String jarg5, + long jarg6, + Error jarg6_); + + public static final native long Error_buildError__SWIG_2( + byte[] jarg1, byte[] jarg2, int jarg3, int jarg4, String jarg5, long jarg6); + + public static final native long new_Error__SWIG_0(); + + public static final native long new_Error__SWIG_1(long jarg1, String jarg2); + + public static final native void delete_Error(long jarg1); + + public static final native long Error_errorCode(long jarg1, Error jarg1_); + + public static final native String Error_errorMessage(long jarg1, Error jarg1_); + + public static final native void Error_setErrorCode(long jarg1, Error jarg1_, long jarg2); + + public static final native void Error_setErrorMessage(long jarg1, Error jarg1_, String jarg2); + + public static final native void InputBuffer_data_set( + long jarg1, InputBuffer jarg1_, long jarg2); + + public static final native long InputBuffer_data_get(long jarg1, InputBuffer jarg1_); + + public static final native void InputBuffer_len_set( + long jarg1, InputBuffer jarg1_, java.math.BigInteger jarg2); + + public static final native java.math.BigInteger InputBuffer_len_get( + long jarg1, InputBuffer jarg1_); + + public static final native long new_InputBuffer(); + + public static final native void delete_InputBuffer(long jarg1); + + public static final native void OutputBuffer_data_set( + long jarg1, OutputBuffer jarg1_, long jarg2); + + public static final native long OutputBuffer_data_get(long jarg1, OutputBuffer jarg1_); + + public static final native void OutputBuffer_len_set( + long jarg1, OutputBuffer jarg1_, java.math.BigInteger jarg2); + + public static final native java.math.BigInteger OutputBuffer_len_get( + long jarg1, OutputBuffer jarg1_); + + public static final native long new_OutputBuffer(); + + public static final native void delete_OutputBuffer(long jarg1); + + public static final native void delete_FrontConfig(long jarg1); + + public static final native int FrontConfig_threadPoolSize(long jarg1, FrontConfig jarg1_); + + public static final native void FrontConfig_setThreadPoolSize( + long jarg1, FrontConfig jarg1_, int jarg2); + + public static final native String FrontConfig_nodeID(long jarg1, FrontConfig jarg1_); + + public static final native void FrontConfig_setNodeID( + long jarg1, FrontConfig jarg1_, String jarg2); + + public static final native long FrontConfig_selfEndPoint(long jarg1, FrontConfig jarg1_); + + public static final native long FrontConfig_mutableSelfEndPoint(long jarg1, FrontConfig jarg1_); + + public static final native void FrontConfig_setSelfEndPoint( + long jarg1, FrontConfig jarg1_, long jarg2, EndPoint jarg2_); + + public static final native void FrontConfig_setGatewayGrpcTarget( + long jarg1, FrontConfig jarg1_, String jarg2); + + public static final native String FrontConfig_gatewayGrpcTarget(long jarg1, FrontConfig jarg1_); + + public static final native void FrontConfig_setGrpcConfig( + long jarg1, FrontConfig jarg1_, long jarg2, GrpcConfig jarg2_); + + public static final native long FrontConfig_grpcConfig(long jarg1, FrontConfig jarg1_); + + public static final native long FrontConfig_generateNodeInfo(long jarg1, FrontConfig jarg1_); + + public static final native long FrontConfig_getComponents(long jarg1, FrontConfig jarg1_); + + public static final native void FrontConfig_setComponents( + long jarg1, FrontConfig jarg1_, long jarg2, StringVec jarg2_); + + public static final native void FrontConfig_addComponent( + long jarg1, FrontConfig jarg1_, String jarg2); + + public static final native long FrontConfig_mutableComponents(long jarg1, FrontConfig jarg1_); + + public static final native String FrontConfig_meta(long jarg1, FrontConfig jarg1_); + + public static final native void FrontConfig_setMeta( + long jarg1, FrontConfig jarg1_, String jarg2); + + public static final native void delete_FrontConfigBuilder(long jarg1); + + public static final native long FrontConfigBuilder_build__SWIG_0( + long jarg1, FrontConfigBuilder jarg1_); + + public static final native long FrontConfigBuilder_build__SWIG_1( + long jarg1, FrontConfigBuilder jarg1_, int jarg2, String jarg3); + + public static final native String printFrontDesc(long jarg1, FrontConfig jarg1_); + + public static final native long new_EndPoint__SWIG_0(); + + public static final native long new_EndPoint__SWIG_1(String jarg1, int jarg2); + + public static final native void delete_EndPoint(long jarg1); + + public static final native String EndPoint_host(long jarg1, EndPoint jarg1_); + + public static final native int EndPoint_port(long jarg1, EndPoint jarg1_); + + public static final native void EndPoint_setHost(long jarg1, EndPoint jarg1_, String jarg2); + + public static final native void EndPoint_setPort(long jarg1, EndPoint jarg1_, int jarg2); + + public static final native void EndPoint_setListenIp(long jarg1, EndPoint jarg1_, String jarg2); + + public static final native String EndPoint_entryPoint(long jarg1, EndPoint jarg1_); + + public static final native String EndPoint_listenEndPoint(long jarg1, EndPoint jarg1_); + + public static final native String EndPoint_listenIp(long jarg1, EndPoint jarg1_); + + public static final native long new_GrpcConfig(); + + public static final native String GrpcConfig_loadBalancePolicy(long jarg1, GrpcConfig jarg1_); + + public static final native void GrpcConfig_setLoadBalancePolicy( + long jarg1, GrpcConfig jarg1_, String jarg2); + + public static final native boolean GrpcConfig_enableHealthCheck(long jarg1, GrpcConfig jarg1_); + + public static final native void GrpcConfig_setEnableHealthCheck( + long jarg1, GrpcConfig jarg1_, boolean jarg2); + + public static final native void GrpcConfig_setEnableDnslookup( + long jarg1, GrpcConfig jarg1_, boolean jarg2); + + public static final native boolean GrpcConfig_enableDnslookup(long jarg1, GrpcConfig jarg1_); + + public static final native java.math.BigInteger GrpcConfig_maxSendMessageSize( + long jarg1, GrpcConfig jarg1_); + + public static final native java.math.BigInteger GrpcConfig_maxReceivedMessageSize( + long jarg1, GrpcConfig jarg1_); + + public static final native void GrpcConfig_setMaxSendMessageSize( + long jarg1, GrpcConfig jarg1_, java.math.BigInteger jarg2); + + public static final native void GrpcConfig_setMaxReceivedMessageSize( + long jarg1, GrpcConfig jarg1_, java.math.BigInteger jarg2); + + public static final native int GrpcConfig_compressAlgorithm(long jarg1, GrpcConfig jarg1_); + + public static final native void GrpcConfig_setCompressAlgorithm( + long jarg1, GrpcConfig jarg1_, int jarg2); + + public static final native java.math.BigInteger GrpcConfig_maxMsgSize( + long jarg1, GrpcConfig jarg1_); + + public static final native void GrpcConfig_setMaxMsgSize( + long jarg1, GrpcConfig jarg1_, java.math.BigInteger jarg2); + + public static final native long new_GrpcServerConfig__SWIG_0(); + + public static final native long new_GrpcServerConfig__SWIG_1( + long jarg1, EndPoint jarg1_, boolean jarg2); + + public static final native String GrpcServerConfig_listenEndPoint( + long jarg1, GrpcServerConfig jarg1_); + + public static final native void GrpcServerConfig_setEndPoint( + long jarg1, GrpcServerConfig jarg1_, long jarg2, EndPoint jarg2_); + + public static final native void GrpcServerConfig_setEnableHealthCheck( + long jarg1, GrpcServerConfig jarg1_, boolean jarg2); + + public static final native long GrpcServerConfig_endPoint(long jarg1, GrpcServerConfig jarg1_); + + public static final native long GrpcServerConfig_mutableEndPoint( + long jarg1, GrpcServerConfig jarg1_); + + public static final native boolean GrpcServerConfig_enableHealthCheck( + long jarg1, GrpcServerConfig jarg1_); + + public static final native long GrpcServerConfig_grpcConfig( + long jarg1, GrpcServerConfig jarg1_); + + public static final native String printGrpcConfig(long jarg1, GrpcConfig jarg1_); + + public static final native void delete_MessageOptionalHeader(long jarg1); + + public static final native void MessageOptionalHeader_encode( + long jarg1, MessageOptionalHeader jarg1_, long jarg2, ubytes jarg2_); + + public static final native long MessageOptionalHeader_decode( + long jarg1, MessageOptionalHeader jarg1_, long jarg2, java.math.BigInteger jarg3); + + public static final native String MessageOptionalHeader_componentType( + long jarg1, MessageOptionalHeader jarg1_); + + public static final native void MessageOptionalHeader_setComponentType( + long jarg1, MessageOptionalHeader jarg1_, String jarg2); + + public static final native byte[] MessageOptionalHeader_srcNodeBuffer( + long jarg1, MessageOptionalHeader jarg1_); + + public static final native void MessageOptionalHeader_setSrcNodeBuffer( + long jarg1, MessageOptionalHeader jarg1_, byte[] jarg2, java.math.BigInteger jarg3); + + public static final native byte[] MessageOptionalHeader_dstNodeBuffer( + long jarg1, MessageOptionalHeader jarg1_); + + public static final native void MessageOptionalHeader_setDstNodeBuffer( + long jarg1, MessageOptionalHeader jarg1_, byte[] jarg2, java.math.BigInteger jarg3); + + public static final native String MessageOptionalHeader_dstInst( + long jarg1, MessageOptionalHeader jarg1_); + + public static final native void MessageOptionalHeader_setDstInst( + long jarg1, MessageOptionalHeader jarg1_, String jarg2); + + public static final native String MessageOptionalHeader_topic( + long jarg1, MessageOptionalHeader jarg1_); + + public static final native void MessageOptionalHeader_setTopic__SWIG_0( + long jarg1, MessageOptionalHeader jarg1_, long jarg2); + + public static final native void MessageOptionalHeader_setTopic__SWIG_1( + long jarg1, MessageOptionalHeader jarg1_, String jarg2); + + public static final native String MessageOptionalHeader_srcInst( + long jarg1, MessageOptionalHeader jarg1_); + + public static final native void MessageOptionalHeader_setSrcInst( + long jarg1, MessageOptionalHeader jarg1_, String jarg2); + + public static final native void delete_MessageHeader(long jarg1); + + public static final native void MessageHeader_encode( + long jarg1, MessageHeader jarg1_, long jarg2, ubytes jarg2_); + + public static final native long MessageHeader_decode( + long jarg1, MessageHeader jarg1_, long jarg2); + + public static final native short MessageHeader_version(long jarg1, MessageHeader jarg1_); + + public static final native void MessageHeader_setVersion( + long jarg1, MessageHeader jarg1_, int jarg2); + + public static final native String MessageHeader_traceID(long jarg1, MessageHeader jarg1_); + + public static final native void MessageHeader_setTraceID( + long jarg1, MessageHeader jarg1_, String jarg2); + + public static final native String MessageHeader_srcGwNode(long jarg1, MessageHeader jarg1_); + + public static final native void MessageHeader_setSrcGwNode( + long jarg1, MessageHeader jarg1_, String jarg2); + + public static final native String MessageHeader_dstGwNode(long jarg1, MessageHeader jarg1_); + + public static final native void MessageHeader_setDstGwNode( + long jarg1, MessageHeader jarg1_, String jarg2); + + public static final native int MessageHeader_packetType(long jarg1, MessageHeader jarg1_); + + public static final native void MessageHeader_setPacketType( + long jarg1, MessageHeader jarg1_, int jarg2); + + public static final native short MessageHeader_ttl(long jarg1, MessageHeader jarg1_); + + public static final native void MessageHeader_setTTL( + long jarg1, MessageHeader jarg1_, int jarg2); + + public static final native int MessageHeader_ext(long jarg1, MessageHeader jarg1_); + + public static final native void MessageHeader_setExt( + long jarg1, MessageHeader jarg1_, int jarg2); + + public static final native long MessageHeader_optionalField(long jarg1, MessageHeader jarg1_); + + public static final native void MessageHeader_setOptionalField( + long jarg1, MessageHeader jarg1_, long jarg2, MessageOptionalHeader jarg2_); + + public static final native int MessageHeader_length(long jarg1, MessageHeader jarg1_); + + public static final native boolean MessageHeader_isRespPacket(long jarg1, MessageHeader jarg1_); + + public static final native void MessageHeader_setRespPacket(long jarg1, MessageHeader jarg1_); + + public static final native long MessageHeader_srcP2PNodeIDView( + long jarg1, MessageHeader jarg1_); + + public static final native long MessageHeader_dstP2PNodeIDView( + long jarg1, MessageHeader jarg1_); + + public static final native int MessageHeader_routeType(long jarg1, MessageHeader jarg1_); + + public static final native void MessageHeader_setRouteType( + long jarg1, MessageHeader jarg1_, long jarg2); + + public static final native boolean MessageHeader_hasOptionalField( + long jarg1, MessageHeader jarg1_); + + public static final native void delete_Message(long jarg1); + + public static final native long Message_header(long jarg1, Message jarg1_); + + public static final native void Message_setHeader( + long jarg1, Message jarg1_, long jarg2, MessageHeader jarg2_); + + public static final native int Message_version(long jarg1, Message jarg1_); + + public static final native void Message_setVersion(long jarg1, Message jarg1_, int jarg2); + + public static final native int Message_packetType(long jarg1, Message jarg1_); + + public static final native void Message_setPacketType(long jarg1, Message jarg1_, int jarg2); + + public static final native String Message_seq(long jarg1, Message jarg1_); + + public static final native void Message_setSeq(long jarg1, Message jarg1_, String jarg2); + + public static final native int Message_ext(long jarg1, Message jarg1_); + + public static final native void Message_setExt(long jarg1, Message jarg1_, int jarg2); + + public static final native boolean Message_isRespPacket(long jarg1, Message jarg1_); + + public static final native void Message_setRespPacket(long jarg1, Message jarg1_); + + public static final native void Message_setPayload( + long jarg1, Message jarg1_, long jarg2, ubytes jarg2_); + + public static final native byte[] Message_payloadBuffer(long jarg1, Message jarg1_); + + public static final native long Message_frontMessage(long jarg1, Message jarg1_); + + public static final native boolean Message_encode( + long jarg1, Message jarg1_, long jarg2, ubytes jarg2_); + + public static final native long Message_decode(long jarg1, Message jarg1_, long jarg2); + + public static final native long Message_length(long jarg1, Message jarg1_); + + public static final native long Message_payload(long jarg1, Message jarg1_); + + public static final native void Message_releasePayload(long jarg1, Message jarg1_); + + public static final native void delete_MessageHeaderBuilder(long jarg1); + + public static final native long MessageHeaderBuilder_build__SWIG_0( + long jarg1, MessageHeaderBuilder jarg1_, long jarg2); + + public static final native long MessageHeaderBuilder_build__SWIG_1( + long jarg1, MessageHeaderBuilder jarg1_); + + public static final native long MessageHeaderBuilder_build__SWIG_2( + long jarg1, MessageHeaderBuilder jarg1_, long jarg2, MessageOptionalHeader jarg2_); + + public static final native void delete_MessageBuilder(long jarg1); + + public static final native long MessageBuilder_build__SWIG_0(long jarg1, MessageBuilder jarg1_); + + public static final native long MessageBuilder_build__SWIG_1( + long jarg1, MessageBuilder jarg1_, long jarg2); + + public static final native long MessageBuilder_build__SWIG_2( + long jarg1, + MessageBuilder jarg1_, + long jarg2, + long jarg3, + MessageOptionalHeader jarg3_, + long jarg4, + ubytes jarg4_); + + public static final native void delete_MessageOptionalHeaderBuilder(long jarg1); + + public static final native long MessageOptionalHeaderBuilder_build__SWIG_0( + long jarg1, + MessageOptionalHeaderBuilder jarg1_, + long jarg2, + MessageOptionalHeader jarg2_); + + public static final native long MessageOptionalHeaderBuilder_build__SWIG_1( + long jarg1, MessageOptionalHeaderBuilder jarg1_); + + public static final native String printOptionalField(long jarg1, MessageOptionalHeader jarg1_); + + public static final native String printMessage(long jarg1, Message jarg1_); + + public static final native int FrontMsgExtFlag_Response_get(); + + public static final native void delete_MessagePayload(long jarg1); + + public static final native long MessagePayload_encode( + long jarg1, MessagePayload jarg1_, long jarg2, ubytes jarg2_); + + public static final native long MessagePayload_decode( + long jarg1, MessagePayload jarg1_, long jarg2); + + public static final native short MessagePayload_version(long jarg1, MessagePayload jarg1_); + + public static final native void MessagePayload_setVersion( + long jarg1, MessagePayload jarg1_, short jarg2); + + public static final native byte[] MessagePayload_dataBuffer(long jarg1, MessagePayload jarg1_); + + public static final native int MessagePayload_seq(long jarg1, MessagePayload jarg1_); + + public static final native void MessagePayload_setSeq( + long jarg1, MessagePayload jarg1_, int jarg2); + + public static final native long MessagePayload_length(long jarg1, MessagePayload jarg1_); + + public static final native String MessagePayload_traceID(long jarg1, MessagePayload jarg1_); + + public static final native void MessagePayload_setTraceID( + long jarg1, MessagePayload jarg1_, String jarg2); + + public static final native int MessagePayload_ext(long jarg1, MessagePayload jarg1_); + + public static final native void MessagePayload_setExt( + long jarg1, MessagePayload jarg1_, int jarg2); + + public static final native void MessagePayload_setRespPacket(long jarg1, MessagePayload jarg1_); + + public static final native boolean MessagePayload_isRespPacket( + long jarg1, MessagePayload jarg1_); + + public static final native void MessagePayload_releasePayload( + long jarg1, MessagePayload jarg1_); + + public static final native void delete_MessagePayloadBuilder(long jarg1); + + public static final native long MessagePayloadBuilder_build__SWIG_0( + long jarg1, MessagePayloadBuilder jarg1_); + + public static final native long MessagePayloadBuilder_build__SWIG_1( + long jarg1, MessagePayloadBuilder jarg1_, long jarg2); + + public static final native void delete_INodeInfo(long jarg1); + + public static final native String INodeInfo_endPoint(long jarg1, INodeInfo jarg1_); + + public static final native long INodeInfo_nodeID(long jarg1, INodeInfo jarg1_); + + public static final native void INodeInfo_setNodeID(long jarg1, INodeInfo jarg1_, long jarg2); + + public static final native void INodeInfo_setEndPoint( + long jarg1, INodeInfo jarg1_, String jarg2); + + public static final native boolean INodeInfo_addComponent( + long jarg1, INodeInfo jarg1_, String jarg2); + + public static final native boolean INodeInfo_eraseComponent( + long jarg1, INodeInfo jarg1_, String jarg2); + + public static final native boolean INodeInfo_componentExist( + long jarg1, INodeInfo jarg1_, String jarg2); + + public static final native long INodeInfo_copiedComponents(long jarg1, INodeInfo jarg1_); + + public static final native String INodeInfo_meta(long jarg1, INodeInfo jarg1_); + + public static final native void INodeInfo_setMeta(long jarg1, INodeInfo jarg1_, String jarg2); + + public static final native String printNodeInfo(long jarg1, INodeInfo jarg1_); + + public static final native void delete_IFrontClient(long jarg1); + + public static final native void IFrontClient_onReceiveMessage( + long jarg1, IFrontClient jarg1_, long jarg2, Message jarg2_, long jarg3); + + public static final native long new_ErrorCallback(); + + public static final native void delete_ErrorCallback(long jarg1); + + public static final native void ErrorCallback_onError( + long jarg1, ErrorCallback jarg1_, long jarg2, Error jarg2_); + + public static final native void ErrorCallback_director_connect( + ErrorCallback obj, long cptr, boolean mem_own, boolean weak_global); + + public static final native void ErrorCallback_change_ownership( + ErrorCallback obj, long cptr, boolean take_or_release); + + public static final native long new_MessageDispatcherHandler(); + + public static final native void delete_MessageDispatcherHandler(long jarg1); + + public static final native void MessageDispatcherHandler_onMessage( + long jarg1, MessageDispatcherHandler jarg1_, long jarg2, Message jarg2_); + + public static final native void MessageDispatcherHandler_director_connect( + MessageDispatcherHandler obj, long cptr, boolean mem_own, boolean weak_global); + + public static final native void MessageDispatcherHandler_change_ownership( + MessageDispatcherHandler obj, long cptr, boolean take_or_release); + + public static final native long new_SendResponseHandler(long jarg1); + + public static final native void delete_SendResponseHandler(long jarg1); + + public static final native void SendResponseHandler_sendResponse( + long jarg1, SendResponseHandler jarg1_, long jarg2); + + public static final native long new_IMessageHandler(); + + public static final native void delete_IMessageHandler(long jarg1); + + public static final native void IMessageHandler_onMessage( + long jarg1, + IMessageHandler jarg1_, + long jarg2, + Error jarg2_, + long jarg3, + Message jarg3_, + long jarg4, + SendResponseHandler jarg4_); + + public static final native void IMessageHandler_director_connect( + IMessageHandler obj, long cptr, boolean mem_own, boolean weak_global); + + public static final native void IMessageHandler_change_ownership( + IMessageHandler obj, long cptr, boolean take_or_release); + + public static final native long new_GetPeersInfoHandler(); + + public static final native void delete_GetPeersInfoHandler(long jarg1); + + public static final native void GetPeersInfoHandler_onPeersInfo( + long jarg1, GetPeersInfoHandler jarg1_, long jarg2, Error jarg2_, String jarg3); + + public static final native void GetPeersInfoHandler_director_connect( + GetPeersInfoHandler obj, long cptr, boolean mem_own, boolean weak_global); + + public static final native void GetPeersInfoHandler_change_ownership( + GetPeersInfoHandler obj, long cptr, boolean take_or_release); + + public static final native void delete_IFront(long jarg1); + + public static final native void IFront_start(long jarg1, IFront jarg1_); + + public static final native void IFront_stop(long jarg1, IFront jarg1_); + + public static final native void IFront_register_topic_handler( + long jarg1, IFront jarg1_, String jarg2, long jarg3, MessageDispatcherHandler jarg3_); + + public static final native void IFront_register_msg_handler( + long jarg1, IFront jarg1_, String jarg2, long jarg3, MessageDispatcherHandler jarg3_); + + public static final native void IFront_async_send_message( + long jarg1, + IFront jarg1_, + int jarg2, + long jarg3, + MessageOptionalHeader jarg3_, + byte[] jarg4, + java.math.BigInteger jarg5, + int jarg6, + int jarg7, + long jarg8, + ErrorCallback jarg8_, + long jarg9, + IMessageHandler jarg9_); + + public static final native void IFront_async_send_response( + long jarg1, + IFront jarg1_, + byte[] jarg2, + java.math.BigInteger jarg3, + String jarg4, + byte[] jarg5, + java.math.BigInteger jarg6, + int jarg7, + long jarg8, + ErrorCallback jarg8_); + + public static final native long IFront_push_msg( + long jarg1, + IFront jarg1_, + int jarg2, + long jarg3, + MessageOptionalHeader jarg3_, + byte[] jarg4, + java.math.BigInteger jarg5, + int jarg6, + int jarg7); + + public static final native long IFront_pop(long jarg1, IFront jarg1_, String jarg2, int jarg3); + + public static final native long IFront_peek(long jarg1, IFront jarg1_, String jarg2); + + public static final native void IFront_asyncGetPeers( + long jarg1, IFront jarg1_, long jarg2, GetPeersInfoHandler jarg2_); + + public static final native long IFront_nodeInfo(long jarg1, IFront jarg1_); + + public static final native long IFront_registerTopic(long jarg1, IFront jarg1_, String jarg2); + + public static final native long IFront_unRegisterTopic(long jarg1, IFront jarg1_, String jarg2); + + public static final native void IFront_registerComponent( + long jarg1, IFront jarg1_, String jarg2); + + public static final native void IFront_unRegisterComponent( + long jarg1, IFront jarg1_, String jarg2); + + public static final native void IFront_updateMetaInfo(long jarg1, IFront jarg1_, String jarg2); + + public static final native long IFront_selectNodesByRoutePolicy( + long jarg1, IFront jarg1_, short jarg2, long jarg3, MessageOptionalHeader jarg3_); + + public static final native long IFront_getNodeDiscovery(long jarg1, IFront jarg1_); + + public static final native void delete_IFrontBuilder(long jarg1); + + public static final native long IFrontBuilder_buildClient( + long jarg1, IFrontBuilder jarg1_, String jarg2, long jarg3, boolean jarg4); + + public static final native void delete_INodeDiscovery(long jarg1); + + public static final native long INodeDiscovery_getAliveNodeList( + long jarg1, INodeDiscovery jarg1_); + + public static final native int SDKMode_AIR_get(); + + public static final native int SDKMode_PRO_get(); + + public static final native long new_TransportBuilder(); + + public static final native void delete_TransportBuilder(long jarg1); + + public static final native long TransportBuilder_buildProTransport( + long jarg1, TransportBuilder jarg1_, long jarg2, FrontConfig jarg2_); + + public static final native long TransportBuilder_buildConfig( + long jarg1, TransportBuilder jarg1_, int jarg2, String jarg3); + + public static final native long TransportBuilder_frontConfigBuilder( + long jarg1, TransportBuilder jarg1_); + + public static final native void TransportBuilder_initLog( + long jarg1, TransportBuilder jarg1_, String jarg2); + + public static final native long new_Transport(long jarg1, FrontConfig jarg1_); + + public static final native void delete_Transport(long jarg1); + + public static final native void Transport_start(long jarg1, Transport jarg1_); + + public static final native void Transport_stop(long jarg1, Transport jarg1_); + + public static final native long Transport_getFront(long jarg1, Transport jarg1_); + + public static final native long Transport_gateway(long jarg1, Transport jarg1_); + + public static final native long Transport_msgPayloadBuilder(long jarg1, Transport jarg1_); + + public static final native long Transport_msgBuilder(long jarg1, Transport jarg1_); + + public static final native long Transport_msgHeaderBuilder(long jarg1, Transport jarg1_); + + public static final native long Transport_routeInfoBuilder(long jarg1, Transport jarg1_); + + public static final native long Transport_getConfig(long jarg1, Transport jarg1_); + + public static final native long IFront_SWIGSmartPtrUpcast(long jarg1); + + public static void SwigDirector_ErrorCallback_onError(ErrorCallback jself, long error) { + jself.onError((error == 0) ? null : new Error(error, true)); + } + + public static void SwigDirector_MessageDispatcherHandler_onMessage( + MessageDispatcherHandler jself, long msg) { + jself.onMessage((msg == 0) ? null : new Message(msg, true)); + } + + public static void SwigDirector_IMessageHandler_onMessage( + IMessageHandler jself, long e, long msg, long sendResponseHandler) { + jself.onMessage( + (e == 0) ? null : new Error(e, true), + (msg == 0) ? null : new Message(msg, true), + new SendResponseHandler(sendResponseHandler, true)); + } + + public static void SwigDirector_GetPeersInfoHandler_onPeersInfo( + GetPeersInfoHandler jself, long e, String peersInfo) { + jself.onPeersInfo((e == 0) ? null : new Error(e, true), peersInfo); + } + + private static final native void swig_module_init(); + + static { + swig_module_init(); + } +} diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/transport/IMessage.java b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/transport/IMessage.java new file mode 100644 index 00000000..36e04600 --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/transport/IMessage.java @@ -0,0 +1,58 @@ +/* + * Copyright 2017-2025 [webank-wedpr] + * + * 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. + * + */ + +package com.webank.wedpr.sdk.jni.transport; + +public interface IMessage { + public interface IMessageHeader { + int getVersion(); + + String getTraceID(); + + String getSrcGwNode(); + + String getDstGwNode(); + + int getPacketType(); + + int getTTL(); + + int getExt(); + + boolean isRespPacket(); + + int getRouteType(); + + String getComponentType(); + + byte[] getSrcNode(); + + byte[] getDstNode(); + + String getDstInst(); + + String getSrcInst(); + + String getTopic(); + } + + IMessageHeader getHeader(); + + Integer getSeq(); + + boolean isResponsePacket(); + + byte[] getPayload(); +} diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/transport/IMessageBuilder.java b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/transport/IMessageBuilder.java new file mode 100644 index 00000000..1618c84c --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/transport/IMessageBuilder.java @@ -0,0 +1,55 @@ +/* + * Copyright 2017-2025 [webank-wedpr] + * + * 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. + * + */ + +package com.webank.wedpr.sdk.jni.transport; + +import com.webank.wedpr.sdk.jni.common.WeDPRSDKException; +import com.webank.wedpr.sdk.jni.generated.Message; +import com.webank.wedpr.sdk.jni.generated.MessageOptionalHeader; +import com.webank.wedpr.sdk.jni.generated.MessageOptionalHeaderBuilder; +import com.webank.wedpr.sdk.jni.transport.impl.MessageImpl; +import lombok.SneakyThrows; +import org.apache.commons.lang3.StringUtils; + +public class IMessageBuilder { + public static IMessage build(Message msg) { + if (msg == null) { + return null; + } + return new MessageImpl(msg); + } + + @SneakyThrows(Exception.class) + public static MessageOptionalHeader buildRouteInfo( + MessageOptionalHeaderBuilder routeInfoBuilder, String topic) { + if (StringUtils.isBlank(topic)) { + throw new WeDPRSDKException("buildRouteInfo for invalid empty topic!"); + } + // return the ownership to cpp, since it is created by cpp + MessageOptionalHeader routeInfo = routeInfoBuilder.build(); + routeInfo.setTopic(topic); + routeInfo.disOwnMemory(); + return routeInfo; + } + + @SneakyThrows(Exception.class) + public static MessageOptionalHeader buildRouteInfo( + MessageOptionalHeaderBuilder routeInfoBuilder) { + // return the ownership to cpp, since it is created by cpp + MessageOptionalHeader routeInfo = routeInfoBuilder.build(); + routeInfo.disOwnMemory(); + return routeInfo; + } +} diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/transport/TransportConfig.java b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/transport/TransportConfig.java new file mode 100644 index 00000000..8449e465 --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/transport/TransportConfig.java @@ -0,0 +1,153 @@ +/* + * Copyright 2017-2025 [webank-wedpr] + * + * 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. + * + */ + +package com.webank.wedpr.sdk.jni.transport; + +import com.webank.wedpr.sdk.jni.common.JniLibLoader; +import com.webank.wedpr.sdk.jni.common.ObjectMapperFactory; +import com.webank.wedpr.sdk.jni.generated.FrontConfig; +import com.webank.wedpr.sdk.jni.generated.TransportBuilder; +import com.webank.wedpr.sdk.jni.transport.model.ServiceMeta; +import com.webank.wedpr.sdk.jni.transport.model.TransportEndPoint; +import com.webank.wedpr.sdk.jni.transport.model.TransportGrpcConfig; +import java.util.List; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** the transport config used to build the transport */ +public class TransportConfig { + private static final Logger logger = LoggerFactory.getLogger(TransportConfig.class); + private static TransportBuilder transportBuilder; + + static { + // load the jni + JniLibLoader.loadJniLibrary(); + logger.info("loadJniLibrary success"); + createTransportBuilder(); + logger.info("createTransportBuilder success"); + } + + private static synchronized void createTransportBuilder() { + if (transportBuilder != null) { + logger.info("transportBuilder has already been created"); + return; + } + logger.info("init transportBuilder"); + transportBuilder = new TransportBuilder(); + transportBuilder.initLog("conf/wedpr_sdk_log_config.ini"); + logger.info("init transportBuilder success"); + } + + public static TransportBuilder getTransportBuilder() { + return transportBuilder; + } + + private final FrontConfig frontConfig; + private List components; + private TransportEndPoint selfEndPoint; + private ServiceMeta serviceMeta = new ServiceMeta(); + + public TransportConfig(Integer threadPoolSize, String nodeID) { + this.frontConfig = transportBuilder.buildConfig(threadPoolSize, nodeID); + this.frontConfig.disOwnMemory(); + // set default grpcConfig + setGrpcConfig(new TransportGrpcConfig()); + } + + public void setSelfEndPoint(TransportEndPoint endPoint) { + if (endPoint == null) { + return; + } + this.selfEndPoint = endPoint; + this.frontConfig.setSelfEndPoint(endPoint.getEndPoint()); + } + + public void setGatewayTargets(String gatewayTargets) { + this.frontConfig.setGatewayGrpcTarget(gatewayTargets); + } + + public void setGrpcConfig(TransportGrpcConfig grpcConfig) { + this.frontConfig.setGrpcConfig(grpcConfig.getGrpcConfig()); + } + + public void setComponents(List components) { + if (components == null || components.isEmpty()) { + return; + } + this.components = components; + for (String component : components) { + this.frontConfig.addComponent(component); + } + } + + public void registerService(ServiceMeta serviceMeta) { + if (serviceMeta != null) { + this.serviceMeta = serviceMeta; + } + } + + public void registerService(String serviceName, String entryPoint) throws Exception { + serviceMeta.addEntryPoint(new ServiceMeta.EntryPointMeta(serviceName, entryPoint)); + // update the meta + this.frontConfig.setMeta( + ObjectMapperFactory.getObjectMapper().writeValueAsString(serviceMeta)); + } + + public ServiceMeta getServiceMeta() { + return this.serviceMeta; + } + + public FrontConfig getFrontConfig() { + return frontConfig; + } + + public List getComponents() { + return components; + } + + public TransportEndPoint getSelfEndPoint() { + return selfEndPoint; + } + + public Integer getThreadPoolSize() { + return frontConfig.threadPoolSize(); + } + + public String getNodeID() { + return frontConfig.nodeID(); + } + + public String getGatewayTargets() { + return frontConfig.gatewayGrpcTarget(); + } + + @Override + public String toString() { + return "TransportConfig{" + + "components=" + + components + + ", selfEndPoint=" + + selfEndPoint + + ", threadPoolSize=" + + getThreadPoolSize() + + ", nodeID='" + + getNodeID() + + '\'' + + ", gatewayTargets='" + + getGatewayTargets() + + '\'' + + '}'; + } +} diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/transport/WeDPRTransport.java b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/transport/WeDPRTransport.java new file mode 100644 index 00000000..93dc1fa9 --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/transport/WeDPRTransport.java @@ -0,0 +1,197 @@ +/* + * Copyright 2017-2025 [webank-wedpr] + * + * 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. + * + */ + +package com.webank.wedpr.sdk.jni.transport; + +import com.webank.wedpr.sdk.jni.common.WeDPRSDKException; +import com.webank.wedpr.sdk.jni.transport.handlers.GetPeersCallback; +import com.webank.wedpr.sdk.jni.transport.handlers.MessageCallback; +import com.webank.wedpr.sdk.jni.transport.handlers.MessageDispatcherCallback; +import com.webank.wedpr.sdk.jni.transport.handlers.MessageErrorCallback; +import com.webank.wedpr.sdk.jni.transport.impl.RouteType; +import com.webank.wedpr.sdk.jni.transport.model.ServiceMeta; +import java.util.List; + +public interface WeDPRTransport { + // start the transport + void start(); + // stop the transport + void stop(); + /** + * register the component + * + * @param component the component used to router + * @throws Exception failed case + */ + void registerComponent(String component) throws Exception; + + /** + * unregister the component + * + * @param component the component used to route + * @throws Exception failed case + */ + void unRegisterComponent(String component) throws Exception; + + /** + * register the topic + * + * @param topic the topic used to route + * @throws Exception failed case + */ + void registerTopic(String topic) throws Exception; + + /** + * unRegister the topic + * + * @param topic the topic used to route + * @throws Exception failed case + */ + void unRegisterTopic(String topic) throws Exception; + + /** + * register handlers according to component + * + * @param component the component of the message should handled by the given callback + * @param messageDispatcherCallback the message callback + */ + void registerComponentHandler( + String component, MessageDispatcherCallback messageDispatcherCallback); + + /** + * async get peers information + * + * @param handler the handler that handle the peersInfo + */ + void asyncGetPeers(GetPeersCallback handler); + + //// the async interfaces + /** + * register the message handler + * + * @param topic the topic + * @param messageHandler the message handler + */ + void registerTopicHandler(String topic, MessageDispatcherCallback messageHandler); + + /** + * async send message by the nodeID + * + * @param topic the topic + * @param dstNode the dstNode + * @param payload the payload + * @param seq the seq of the payload + * @param timeout the timeout setting + * @param errorCallback the handler called after receive the message related to the topic + */ + void asyncSendMessageByNodeID( + String topic, + byte[] dstNode, + byte[] payload, + int seq, + int timeout, + MessageErrorCallback errorCallback, + MessageCallback msgCallback); + + /** + * send message by the agency + * + * @param topic the topic + * @param agency the agency + * @param payload the payload + * @param seq the seq + * @param timeout the timeout + * @param errorCallback the handler called after receive the message related to the topic + */ + void asyncSendMessageByAgency( + String topic, + String agency, + byte[] payload, + int seq, + int timeout, + MessageErrorCallback errorCallback, + MessageCallback msgCallback); + + void asyncSendMessageByComponent( + String topic, + String dstInst, + String component, + byte[] payload, + int seq, + int timeout, + MessageErrorCallback errorCallback, + MessageCallback msgCallback); + + /** + * send message by the topic(will register firstly) + * + * @param topic the topic(used to route too + * @param payload the payload(the payload) + * @param seq the seq(the seq) + * @param timeout the timeout + * @param errorCallback the handler + */ + void asyncSendMessageByTopic( + String topic, + String dstInst, + byte[] payload, + int seq, + int timeout, + MessageErrorCallback errorCallback, + MessageCallback msgCallback); + + /** + * send response to given node + * + * @param dstNode the node that should receive the response + * @param traceID the traceID of the response + * @param payload the payload + * @param seq the seq + * @param errorCallback the error callback + */ + void asyncSendResponse( + byte[] dstNode, + String traceID, + byte[] payload, + int seq, + MessageErrorCallback errorCallback); + + /** @param topic the topic to remove */ + void removeTopic(String topic) throws WeDPRSDKException; + + //// the sync interfaces + void pushByNodeID(String topic, byte[] dstNodeID, int seq, byte[] payload, int timeout) + throws WeDPRSDKException; + + void pushByComponent( + String topic, String dstInst, String component, int seq, byte[] payload, int timeout) + throws WeDPRSDKException; + + void pushByInst(String topic, String dstInst, int seq, byte[] payload, int timeout) + throws WeDPRSDKException; + + IMessage pop(String topic, int timeout) throws WeDPRSDKException; + + IMessage peek(String topic); + + List selectNodeListByPolicy( + RouteType routeType, String dstInst, String dstComponent, String dstNode); + + List getAliveEntryPoints(String serviceName); + + void registerService(String serviceName, String entryPoint) throws Exception; + + public TransportConfig getTransportConfig(); +} diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/transport/handlers/GetPeersCallback.java b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/transport/handlers/GetPeersCallback.java new file mode 100644 index 00000000..3f02e7f1 --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/transport/handlers/GetPeersCallback.java @@ -0,0 +1,46 @@ +/* + * Copyright 2017-2025 [webank-wedpr] + * + * 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. + * + */ + +package com.webank.wedpr.sdk.jni.transport.handlers; + +import com.webank.wedpr.sdk.jni.generated.Error; +import com.webank.wedpr.sdk.jni.generated.GetPeersInfoHandler; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public abstract class GetPeersCallback extends GetPeersInfoHandler { + private static final Logger logger = LoggerFactory.getLogger(GetPeersCallback.class); + + public abstract void onPeers(Error e, String peersInfo); + + public void onPeersInfo(Error e, String peersInfo) { + try { + onPeers(e, peersInfo); + } catch (Exception exception) { + logger.warn( + "onPeersInfo exception, result: {}, peersInfo: {}, e: ", + e.toString(), + peersInfo, + exception); + } + } + + // release the ownership to c++, in case of it's released by the jvm + @Override + protected void finalize() { + swigReleaseOwnership(); + delete(); + } +} diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/transport/handlers/MessageCallback.java b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/transport/handlers/MessageCallback.java new file mode 100644 index 00000000..8e12f8e5 --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/transport/handlers/MessageCallback.java @@ -0,0 +1,47 @@ +/* + * Copyright 2017-2025 [webank-wedpr] + * + * 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. + * + */ + +package com.webank.wedpr.sdk.jni.transport.handlers; + +import com.webank.wedpr.sdk.jni.generated.Error; +import com.webank.wedpr.sdk.jni.generated.IMessageHandler; +import com.webank.wedpr.sdk.jni.generated.Message; +import com.webank.wedpr.sdk.jni.generated.SendResponseHandler; +import com.webank.wedpr.sdk.jni.transport.IMessage; +import com.webank.wedpr.sdk.jni.transport.IMessageBuilder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public abstract class MessageCallback extends IMessageHandler { + private static final Logger logger = LoggerFactory.getLogger(MessageCallback.class); + + public abstract void onMessage( + Error error, IMessage message, SendResponseHandler sendResponseHandler); + + // release the ownership to c++, in case of it's released by the jvm + protected void finalize() { + swigReleaseOwnership(); + delete(); + } + + @Override + public void onMessage(Error e, Message msg, SendResponseHandler sendResponseHandler) { + try { + onMessage(e, IMessageBuilder.build(msg), sendResponseHandler); + } catch (Exception exception) { + logger.warn("onMessage exception, msg: {}, e:", msg.toString(), exception); + } + } +} diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/transport/handlers/MessageDispatcherCallback.java b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/transport/handlers/MessageDispatcherCallback.java new file mode 100644 index 00000000..7eb0eec5 --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/transport/handlers/MessageDispatcherCallback.java @@ -0,0 +1,45 @@ +/* + * Copyright 2017-2025 [webank-wedpr] + * + * 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. + * + */ + +package com.webank.wedpr.sdk.jni.transport.handlers; + +import com.webank.wedpr.sdk.jni.generated.Message; +import com.webank.wedpr.sdk.jni.generated.MessageDispatcherHandler; +import com.webank.wedpr.sdk.jni.transport.IMessage; +import com.webank.wedpr.sdk.jni.transport.IMessageBuilder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public abstract class MessageDispatcherCallback extends MessageDispatcherHandler { + private static final Logger logger = LoggerFactory.getLogger(MessageDispatcherCallback.class); + + public abstract void onMessage(IMessage message); + + // TODO: check this will cause memory leak or not + // release the ownership to c++, in case of it's released by the jvm + protected void finalize() { + swigReleaseOwnership(); + delete(); + } + + @Override + public void onMessage(Message msg) { + try { + onMessage(IMessageBuilder.build(msg)); + } catch (Exception e) { + logger.warn("onMessage exception, msg: {}, e:", msg.toString(), e); + } + } +} diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/transport/handlers/MessageErrorCallback.java b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/transport/handlers/MessageErrorCallback.java new file mode 100644 index 00000000..0eb22a13 --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/transport/handlers/MessageErrorCallback.java @@ -0,0 +1,41 @@ +/* + * Copyright 2017-2025 [webank-wedpr] + * + * 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. + * + */ + +package com.webank.wedpr.sdk.jni.transport.handlers; + +import com.webank.wedpr.sdk.jni.generated.Error; +import com.webank.wedpr.sdk.jni.generated.ErrorCallback; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public abstract class MessageErrorCallback extends ErrorCallback { + private static final Logger logger = LoggerFactory.getLogger(MessageErrorCallback.class); + + public abstract void onErrorResult(Error error); + + public void onError(Error error) { + try { + onErrorResult(error); + } catch (Exception e) { + logger.warn("onError exception, error: {}, e:", error.toString(), e); + } + } + // release the ownership to c++, in case of it's released by the jvm + @Override + protected void finalize() { + swigReleaseOwnership(); + delete(); + } +} diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/transport/impl/MessageImpl.java b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/transport/impl/MessageImpl.java new file mode 100644 index 00000000..8edcc1b6 --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/transport/impl/MessageImpl.java @@ -0,0 +1,157 @@ +/* + * Copyright 2017-2025 [webank-wedpr] + * + * 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. + * + */ + +package com.webank.wedpr.sdk.jni.transport.impl; + +import com.webank.wedpr.sdk.jni.generated.Message; +import com.webank.wedpr.sdk.jni.generated.MessageHeader; +import com.webank.wedpr.sdk.jni.transport.IMessage; + +public class MessageImpl implements IMessage { + public class MessageHeaderImpl implements IMessageHeader { + private final MessageHeader messageHeader; + + protected MessageHeaderImpl(MessageHeader messageHeader) { + this.messageHeader = messageHeader; + this.messageHeader.optionalField().disOwnMemory(); + this.messageHeader.disOwnMemory(); + } + + @Override + public int getVersion() { + return this.messageHeader.version(); + } + + @Override + public String getTraceID() { + return this.messageHeader.traceID(); + } + + @Override + public String getSrcGwNode() { + return this.messageHeader.srcGwNode(); + } + + @Override + public String getDstGwNode() { + return this.messageHeader.dstGwNode(); + } + + @Override + public int getPacketType() { + return this.messageHeader.packetType(); + } + + @Override + public int getTTL() { + return this.messageHeader.ttl(); + } + + @Override + public int getExt() { + return this.messageHeader.ext(); + } + + @Override + public boolean isRespPacket() { + return this.messageHeader.isRespPacket(); + } + + @Override + public int getRouteType() { + return this.messageHeader.routeType(); + } + + @Override + public String getComponentType() { + return this.messageHeader.optionalField().componentType(); + } + + @Override + public byte[] getSrcNode() { + return this.messageHeader.optionalField().srcNodeBuffer(); + } + + @Override + public byte[] getDstNode() { + return this.messageHeader.optionalField().dstNodeBuffer(); + } + + @Override + public String getDstInst() { + return this.messageHeader.optionalField().dstInst(); + } + + @Override + public String getSrcInst() { + return this.messageHeader.optionalField().srcInst(); + } + + @Override + public String getTopic() { + return this.messageHeader.optionalField().topic(); + } + + @Override + public String toString() { + return "MessageHeaderImpl{" + + "traceID=" + + getTraceID() + + ", srcInst=" + + getSrcInst() + + ", dstInst=" + + getDstInst() + + ", topic=" + + getTopic() + + ", response=" + + isResponsePacket() + + '}'; + } + } + + private final MessageHeaderImpl messageHeader; + private final Message rawMessage; + // v1, v2 + public MessageImpl(Message rawMessage) { + this.rawMessage = rawMessage; + this.rawMessage.disOwnMemory(); + this.messageHeader = new MessageHeaderImpl(rawMessage.header()); + } + + @Override + public IMessageHeader getHeader() { + return this.messageHeader; + } + + @Override + public Integer getSeq() { + return this.rawMessage.frontMessage().seq(); + } + + @Override + public byte[] getPayload() { + return this.rawMessage.frontMessage().dataBuffer(); + } + + @Override + public boolean isResponsePacket() { + return this.rawMessage.frontMessage().isRespPacket(); + } + + @Override + public String toString() { + return "MessageImpl{" + "messageHeader=" + messageHeader + '}'; + } +} diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/transport/impl/RouteType.java b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/transport/impl/RouteType.java new file mode 100644 index 00000000..ab6ccb94 --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/transport/impl/RouteType.java @@ -0,0 +1,23 @@ +/* + * Copyright 2017-2025 [webank-wedpr] + * + * 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. + * + */ + +package com.webank.wedpr.sdk.jni.transport.impl; + +public enum RouteType { + ROUTE_THROUGH_NODEID, + ROUTE_THROUGH_COMPONENT, + ROUTE_THROUGH_AGENCY, + ROUTE_THROUGH_TOPIC; +} diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/transport/impl/TransportImpl.java b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/transport/impl/TransportImpl.java new file mode 100644 index 00000000..a3986303 --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/transport/impl/TransportImpl.java @@ -0,0 +1,532 @@ +/* + * Copyright 2017-2025 [webank-wedpr] + * + * 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. + * + */ + +package com.webank.wedpr.sdk.jni.transport.impl; + +import com.webank.wedpr.sdk.jni.common.Common; +import com.webank.wedpr.sdk.jni.common.Constant; +import com.webank.wedpr.sdk.jni.common.ObjectMapperFactory; +import com.webank.wedpr.sdk.jni.common.WeDPRSDKException; +import com.webank.wedpr.sdk.jni.generated.*; +import com.webank.wedpr.sdk.jni.generated.Error; +import com.webank.wedpr.sdk.jni.transport.IMessage; +import com.webank.wedpr.sdk.jni.transport.IMessageBuilder; +import com.webank.wedpr.sdk.jni.transport.TransportConfig; +import com.webank.wedpr.sdk.jni.transport.WeDPRTransport; +import com.webank.wedpr.sdk.jni.transport.handlers.GetPeersCallback; +import com.webank.wedpr.sdk.jni.transport.handlers.MessageCallback; +import com.webank.wedpr.sdk.jni.transport.handlers.MessageDispatcherCallback; +import com.webank.wedpr.sdk.jni.transport.handlers.MessageErrorCallback; +import com.webank.wedpr.sdk.jni.transport.model.ServiceMeta; +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.List; +import lombok.SneakyThrows; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class TransportImpl implements WeDPRTransport { + private static final Logger logger = LoggerFactory.getLogger(TransportImpl.class); + // the created transport + private final Transport transport; + private final TransportConfig transportConfig; + + public static WeDPRTransport build(TransportConfig transportConfig) throws WeDPRSDKException { + try { + return new TransportImpl( + TransportConfig.getTransportBuilder() + .buildProTransport(transportConfig.getFrontConfig()), + transportConfig); + } catch (Exception e) { + logger.warn( + "build transport failed, transport config: {}, error: ", + transportConfig.toString(), + e); + throw e; + } + } + + protected TransportImpl(Transport transport, TransportConfig transportConfig) + throws WeDPRSDKException { + logger.info("Build Transport, config: {}", transportConfig.toString()); + this.transport = transport; + this.transport.disOwnMemory(); + this.transportConfig = transportConfig; + } + + @Override + public void start() { + try { + logger.info("start the transport"); + this.transport.start(); + } catch (Exception e) { + logger.warn("start the transport failed, error: ", e); + if (this.transport != null) { + this.transport.stop(); + } + throw e; + } + } + + @Override + public void stop() { + logger.info("stop the transport"); + this.transport.stop(); + } + + /** + * @param component the component used to router + * @throws Exception failed case + */ + @Override + public void registerComponent(String component) { + this.transport.getFront().registerComponent(component); + } + + /** + * @param component the component used to route + * @throws Exception failed case + */ + @Override + public void unRegisterComponent(String component) { + this.transport.getFront().unRegisterComponent(component); + } + + /** + * register the topic + * + * @param topic the topic used to route + * @throws Exception failed case + */ + @Override + public void registerTopic(String topic) throws Exception { + Error result = this.transport.getFront().registerTopic(topic); + Common.checkResult("registerTopic", result); + } + + /** + * unRegister the topic + * + * @param topic the topic used to route + * @throws Exception failed case + */ + @Override + public void unRegisterTopic(String topic) throws Exception { + Error result = this.transport.getFront().unRegisterTopic(topic); + Common.checkResult("unRegisterTopic", result); + } + + /** + * register handlers according to component + * + * @param component the component of the message should handled by the given callback + * @param messageDispatcherCallback the message callback + */ + @Override + public void registerComponentHandler( + String component, MessageDispatcherCallback messageDispatcherCallback) { + this.transport.getFront().register_msg_handler(component, messageDispatcherCallback); + } + + /** + * async get peers information + * + * @param handler the handler that handle the peersInfo + */ + @Override + public void asyncGetPeers(GetPeersCallback handler) { + this.transport.getFront().asyncGetPeers(handler); + } + + @Override + public void registerTopicHandler(String topic, MessageDispatcherCallback messageHandler) { + this.transport.getFront().register_topic_handler(topic, messageHandler); + } + + /** + * async send message by the nodeID + * + * @param topic the topic + * @param dstNode the dstNode + * @param payload the payload + * @param seq the seq of the payload + * @param timeout the timeout setting + * @param errorCallback the handler called after receive the message related to the topic + */ + @SneakyThrows(Exception.class) + @Override + public void asyncSendMessageByNodeID( + String topic, + byte[] dstNode, + byte[] payload, + int seq, + int timeout, + MessageErrorCallback errorCallback, + MessageCallback msgCallback) { + MessageOptionalHeader routeInfo = + IMessageBuilder.buildRouteInfo(this.transport.routeInfoBuilder(), topic); + if (dstNode == null) { + throw new WeDPRSDKException( + "asyncSendMessageByNodeID failed for the dstNode information is empty"); + } + routeInfo.setDstNodeBuffer(dstNode, BigInteger.valueOf(dstNode.length)); + this.transport + .getFront() + .async_send_message( + RouteType.ROUTE_THROUGH_NODEID.ordinal(), + routeInfo, + payload, + BigInteger.valueOf(payload.length), + seq, + timeout, + errorCallback, + msgCallback); + } + + /** + * send message by the agency + * + * @param topic the topic + * @param agency the agency + * @param payload the payload + * @param seq the seq + * @param timeout the timeout + * @param errorCallback the handler called after receive the message related to the topic + */ + @SneakyThrows(Exception.class) + @Override + public void asyncSendMessageByAgency( + String topic, + String agency, + byte[] payload, + int seq, + int timeout, + MessageErrorCallback errorCallback, + MessageCallback msgCallback) { + MessageOptionalHeader routeInfo = + IMessageBuilder.buildRouteInfo(this.transport.routeInfoBuilder(), topic); + if (StringUtils.isBlank(agency)) { + throw new WeDPRSDKException( + "asyncSendMessageByAgency failed for the dstInst information is empty"); + } + routeInfo.setDstInst(agency); + this.transport + .getFront() + .async_send_message( + RouteType.ROUTE_THROUGH_AGENCY.ordinal(), + routeInfo, + payload, + BigInteger.valueOf(payload.length), + seq, + timeout, + errorCallback, + msgCallback); + } + + @SneakyThrows(Exception.class) + @Override + public void asyncSendMessageByComponent( + String topic, + String dstInst, + String component, + byte[] payload, + int seq, + int timeout, + MessageErrorCallback errorCallback, + MessageCallback msgCallback) { + // set the routeInfo + MessageOptionalHeader routeInfo = + IMessageBuilder.buildRouteInfo(this.transport.routeInfoBuilder(), topic); + // Note: support not specify the dstInst + if (StringUtils.isNotBlank(dstInst)) { + routeInfo.setDstInst(dstInst); + } + if (StringUtils.isBlank(component)) { + throw new WeDPRSDKException( + "asyncSendMessageByComponent failed for the component information is empty"); + } + routeInfo.setComponentType(component); + this.transport + .getFront() + .async_send_message( + RouteType.ROUTE_THROUGH_COMPONENT.ordinal(), + routeInfo, + payload, + BigInteger.valueOf(payload.length), + seq, + timeout, + errorCallback, + msgCallback); + } + + /** + * send message by the topic(will register firstly) + * + * @param topic the topic(used to route too + * @param payload the payload(the payload) + * @param seq the seq(the seq) + * @param timeout the timeout + * @param errorCallback the handler + */ + @SneakyThrows(Exception.class) + @Override + public void asyncSendMessageByTopic( + String topic, + String dstInst, + byte[] payload, + int seq, + int timeout, + MessageErrorCallback errorCallback, + MessageCallback msgCallback) { + // set the routeInfo + MessageOptionalHeader routeInfo = + IMessageBuilder.buildRouteInfo(this.transport.routeInfoBuilder(), topic); + if (StringUtils.isBlank(dstInst)) { + throw new WeDPRSDKException("asyncSendMessageByTopic failed for the dstInst is empty"); + } + routeInfo.setDstInst(dstInst); + this.transport + .getFront() + .async_send_message( + RouteType.ROUTE_THROUGH_TOPIC.ordinal(), + routeInfo, + payload, + BigInteger.valueOf(payload.length), + seq, + timeout, + errorCallback, + msgCallback); + } + + @SneakyThrows(Exception.class) + @Override + public void asyncSendResponse( + byte[] dstNode, + String traceID, + byte[] payload, + int seq, + MessageErrorCallback errorCallback) { + if (dstNode == null) { + throw new WeDPRSDKException("asyncSendResponse failed for the dstNode is empty"); + } + this.transport + .getFront() + .async_send_response( + dstNode, + BigInteger.valueOf(dstNode.length), + traceID, + payload, + BigInteger.valueOf(payload.length), + seq, + errorCallback); + } + + /** @param topic the topic to remove */ + @SneakyThrows(Exception.class) + @Override + public void removeTopic(String topic) throws WeDPRSDKException { + if (StringUtils.isBlank(topic)) { + throw new WeDPRSDKException("removeTopic failed for the topic is empty"); + } + Error result = this.transport.getFront().unRegisterTopic(topic); + Common.checkResult("removeTopic", result); + } + + //// the sync interfaces + @Override + public void pushByNodeID(String topic, byte[] dstNodeID, int seq, byte[] payload, int timeout) + throws WeDPRSDKException { + MessageOptionalHeader routeInfo = + IMessageBuilder.buildRouteInfo(this.transport.routeInfoBuilder(), topic); + if (dstNodeID == null) { + throw new WeDPRSDKException("pushByNodeID failed for the dstNode is empty"); + } + routeInfo.setDstNodeBuffer(dstNodeID, BigInteger.valueOf(dstNodeID.length)); + Error result = + this.transport + .getFront() + .push_msg( + RouteType.ROUTE_THROUGH_NODEID.ordinal(), + routeInfo, + payload, + BigInteger.valueOf(payload.length), + seq, + timeout); + Common.checkResult("pushByNodeID", result); + } + + @Override + public void pushByComponent( + String topic, String dstInst, String component, int seq, byte[] payload, int timeout) + throws WeDPRSDKException { + MessageOptionalHeader routeInfo = + IMessageBuilder.buildRouteInfo(this.transport.routeInfoBuilder(), topic); + if (StringUtils.isNotBlank(dstInst)) { + routeInfo.setDstInst(dstInst); + } + if (StringUtils.isBlank(component)) { + throw new WeDPRSDKException("pushByComponent failed for the component is empty"); + } + routeInfo.setComponentType(component); + Error result = + this.transport + .getFront() + .push_msg( + RouteType.ROUTE_THROUGH_COMPONENT.ordinal(), + routeInfo, + payload, + BigInteger.valueOf(payload.length), + seq, + timeout); + Common.checkResult("pushByComponent", result); + } + + @Override + public void pushByInst(String topic, String dstInst, int seq, byte[] payload, int timeout) + throws WeDPRSDKException { + MessageOptionalHeader routeInfo = + IMessageBuilder.buildRouteInfo(this.transport.routeInfoBuilder(), topic); + if (StringUtils.isBlank(dstInst)) { + throw new WeDPRSDKException("pushByInst failed for the dstInst is empty"); + } + routeInfo.setDstInst(dstInst); + Error result = + this.transport + .getFront() + .push_msg( + RouteType.ROUTE_THROUGH_TOPIC.ordinal(), + routeInfo, + payload, + BigInteger.valueOf(payload.length), + seq, + timeout); + Common.checkResult("pushByInst", result); + } + + @Override + public IMessage pop(String topic, int timeout) throws WeDPRSDKException { + if (StringUtils.isBlank(topic)) { + throw new WeDPRSDKException("pop failed for the topic is empty"); + } + Message msg = this.transport.getFront().pop(topic, timeout); + if (msg == null) { + throw new WeDPRSDKException( + Constant.FAILED, "Try to receive msg with topic " + topic + " timeout!"); + } + return IMessageBuilder.build(msg); + } + + @SneakyThrows(Exception.class) + @Override + public IMessage peek(String topic) { + if (StringUtils.isBlank(topic)) { + throw new WeDPRSDKException("peek failed for the topic is empty"); + } + Message msg = this.transport.getFront().peek(topic); + if (msg == null) { + return null; + } + return IMessageBuilder.build(msg); + } + + @Override + public List selectNodeListByPolicy( + RouteType routeType, String dstInst, String dstComponent, String dstNode) { + MessageOptionalHeader routeInfo = + IMessageBuilder.buildRouteInfo(this.transport.routeInfoBuilder()); + if (StringUtils.isNotBlank(dstInst)) { + routeInfo.setDstInst(dstInst); + } + if (StringUtils.isNotBlank(dstComponent)) { + routeInfo.setComponentType(dstComponent); + } + if (StringUtils.isNotBlank(dstNode)) { + routeInfo.setDstNodeBuffer(dstNode.getBytes(), BigInteger.valueOf(dstNode.length())); + } + StringVec result = + this.transport + .getFront() + .selectNodesByRoutePolicy((short) routeType.ordinal(), routeInfo); + if (result == null) { + return null; + } + List nodeList = new ArrayList<>(); + for (int i = 0; i < result.size(); i++) { + nodeList.add(result.get(i)); + } + return nodeList; + } + + private void parseServiceMeta( + List entryPointInfos, + String serviceName, + String meta, + StringVec componentsVec) { + try { + if (StringUtils.isBlank(meta)) { + return; + } + ServiceMeta serviceMeta = + ObjectMapperFactory.getObjectMapper().readValue(meta, ServiceMeta.class); + if (serviceMeta.getServiceInfos() == null || serviceMeta.getServiceInfos().isEmpty()) { + return; + } + for (ServiceMeta.EntryPointMeta entryPointMeta : serviceMeta.getServiceInfos()) { + if (entryPointMeta.getServiceName().equalsIgnoreCase(serviceName)) { + entryPointInfos.add(entryPointMeta); + List components = new ArrayList<>(); + for (int i = 0; i < componentsVec.size(); i++) { + entryPointMeta.getComponents().add(componentsVec.get(i)); + } + } + } + } catch (Exception e) { + logger.warn("parseServiceMeta exception, meta: {}", meta, e); + } + } + + @Override + public List getAliveEntryPoints(String serviceName) { + NodeInfoVec nodeInfoList = this.transport.getFront().getNodeDiscovery().getAliveNodeList(); + List result = new ArrayList<>(); + for (int i = 0; i < nodeInfoList.size(); i++) { + parseServiceMeta( + result, + serviceName, + nodeInfoList.get(i).meta(), + nodeInfoList.get(i).copiedComponents()); + } + return result; + } + + @Override + public void registerService(String serviceName, String entryPoint) throws Exception { + transportConfig + .getServiceMeta() + .addEntryPoint(new ServiceMeta.EntryPointMeta(serviceName, entryPoint)); + // update the meta + this.transport + .getFront() + .updateMetaInfo( + ObjectMapperFactory.getObjectMapper() + .writeValueAsString(transportConfig.getServiceMeta())); + } + + @Override + public TransportConfig getTransportConfig() { + return transportConfig; + } +} diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/transport/model/ServiceMeta.java b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/transport/model/ServiceMeta.java new file mode 100644 index 00000000..9b5c3fcd --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/transport/model/ServiceMeta.java @@ -0,0 +1,77 @@ +/* + * Copyright 2017-2025 [webank-wedpr] + * + * 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. + * + */ + +package com.webank.wedpr.sdk.jni.transport.model; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.webank.wedpr.sdk.jni.common.Common; +import com.webank.wedpr.sdk.jni.common.Constant; +import java.util.ArrayList; +import java.util.List; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.ToString; +import org.apache.commons.lang3.StringUtils; + +@Data +@NoArgsConstructor +@ToString +@JsonIgnoreProperties(ignoreUnknown = true) +public class ServiceMeta { + @Data + @NoArgsConstructor + @ToString + @JsonIgnoreProperties(ignoreUnknown = true) + public static class EntryPointMeta { + private String serviceName; + private String entryPoint; + private List components = new ArrayList<>(); + + public EntryPointMeta(String serviceName, String entryPoint) { + this.serviceName = serviceName; + this.entryPoint = entryPoint; + } + + public String getUrl(String uriPath) { + if (StringUtils.isBlank(uriPath)) { + return Common.getUrl(entryPoint); + } + if (uriPath.startsWith(Constant.URI_SPLITER)) { + return Common.getUrl(entryPoint + uriPath); + } + return Common.getUrl(entryPoint + Constant.URI_SPLITER + uriPath); + } + + public void setComponents(List components) { + if (components == null) { + return; + } + this.components = components; + } + } + // Note: here can't been changed + private List serviceInfos = new ArrayList<>(); + + public void setServiceInfos(List serviceInfos) { + if (serviceInfos == null) { + return; + } + this.serviceInfos = serviceInfos; + } + + public void addEntryPoint(EntryPointMeta entryPointMeta) { + this.serviceInfos.add(entryPointMeta); + } +} diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/transport/model/TransportEndPoint.java b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/transport/model/TransportEndPoint.java new file mode 100644 index 00000000..b155e22d --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/transport/model/TransportEndPoint.java @@ -0,0 +1,75 @@ +/* + * Copyright 2017-2025 [webank-wedpr] + * + * 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. + * + */ + +package com.webank.wedpr.sdk.jni.transport.model; + +import com.webank.wedpr.sdk.jni.generated.EndPoint; + +public class TransportEndPoint { + private final EndPoint endPoint; + + public TransportEndPoint(String hostIp, String listenIp, int listenPort) { + this.endPoint = new EndPoint(); + setHostIP(hostIp); + setListenIP(listenIp); + setListenPort(listenPort); + } + + public String getHostIP() { + return this.endPoint.host(); + } + + protected void setHostIP(String hostIP) { + this.endPoint.setHost(hostIP); + } + + public String getListenIP() { + return this.endPoint.listenIp(); + } + + protected void setListenIP(String listenIP) { + this.endPoint.setListenIp(listenIP); + } + + public Integer getListenPort() { + return this.endPoint.port(); + } + + protected void setListenPort(Integer listenPort) { + this.endPoint.setPort(listenPort); + } + + public EndPoint getEndPoint() { + return endPoint; + } + + public EndPoint getNativeEndPoint() { + return endPoint; + } + + @Override + public String toString() { + return "TransportEndPoint{" + + "hostIP='" + + getHostIP() + + '\'' + + ", listenIP='" + + getListenIP() + + '\'' + + ", listenPort=" + + getListenPort() + + '}'; + } +} diff --git a/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/transport/model/TransportGrpcConfig.java b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/transport/model/TransportGrpcConfig.java new file mode 100644 index 00000000..2c5060cf --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/bindings/src/main/java/com/webank/wedpr/sdk/jni/transport/model/TransportGrpcConfig.java @@ -0,0 +1,62 @@ +/* + * Copyright 2017-2025 [webank-wedpr] + * + * 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. + * + */ + +package com.webank.wedpr.sdk.jni.transport.model; + +import com.webank.wedpr.sdk.jni.generated.*; + +public class TransportGrpcConfig { + private final GrpcConfig grpcConfig = new GrpcConfig(); + public static final String defaultLoadBalancePolicy = "round_robin"; + + public TransportGrpcConfig() { + grpcConfig.setEnableHealthCheck(true); + grpcConfig.setEnableDnslookup(false); + grpcConfig.setLoadBalancePolicy(defaultLoadBalancePolicy); + } + + public void setDefaultLoadBalancePolicy(String loadBalancePolicy) { + grpcConfig.setLoadBalancePolicy(loadBalancePolicy); + } + + public boolean isEnableHealthCheck() { + return grpcConfig.enableHealthCheck(); + } + + public boolean isEnableDnslookup() { + return grpcConfig.enableDnslookup(); + } + + public String getLoadBalancePolicy() { + return grpcConfig.loadBalancePolicy(); + } + + public GrpcConfig getGrpcConfig() { + return grpcConfig; + } + + @Override + public String toString() { + return "TransportGrpcConfig{" + + "enableHealthCheck=" + + isEnableHealthCheck() + + ", enableDnslookup=" + + isEnableDnslookup() + + ", loadBalancePolicy='" + + getLoadBalancePolicy() + + '\'' + + '}'; + } +} diff --git a/cpp/wedpr-transport/sdk-wrapper/java/src/wedpr_java_transportJAVA_wrap.cxx b/cpp/wedpr-transport/sdk-wrapper/java/src/wedpr_java_transportJAVA_wrap.cxx new file mode 100644 index 00000000..f839dee8 --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/src/wedpr_java_transportJAVA_wrap.cxx @@ -0,0 +1,10602 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (https://www.swig.org). + * Version 4.2.1 + * + * Do not make changes to this file unless you know what you are doing - modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + + +#define SWIG_VERSION 0x040201 +#define SWIGJAVA +#define SWIG_DIRECTORS + +/* ----------------------------------------------------------------------------- + * This section contains generic SWIG labels for method/variable + * declarations/attributes, and other compiler dependent labels. + * ----------------------------------------------------------------------------- */ + +/* template workaround for compilers that cannot correctly implement the C++ standard */ +#ifndef SWIGTEMPLATEDISAMBIGUATOR +# if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x560) +# define SWIGTEMPLATEDISAMBIGUATOR template +# elif defined(__HP_aCC) +/* Needed even with `aCC -AA' when `aCC -V' reports HP ANSI C++ B3910B A.03.55 */ +/* If we find a maximum version that requires this, the test would be __HP_aCC <= 35500 for A.03.55 */ +# define SWIGTEMPLATEDISAMBIGUATOR template +# else +# define SWIGTEMPLATEDISAMBIGUATOR +# endif +#endif + +/* inline attribute */ +#ifndef SWIGINLINE +# if defined(__cplusplus) || (defined(__GNUC__) && !defined(__STRICT_ANSI__)) +# define SWIGINLINE inline +# else +# define SWIGINLINE +# endif +#endif + +/* attribute recognised by some compilers to avoid 'unused' warnings */ +#ifndef SWIGUNUSED +# if defined(__GNUC__) +# if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) +# define SWIGUNUSED __attribute__ ((__unused__)) +# else +# define SWIGUNUSED +# endif +# elif defined(__ICC) +# define SWIGUNUSED __attribute__ ((__unused__)) +# else +# define SWIGUNUSED +# endif +#endif + +#ifndef SWIG_MSC_UNSUPPRESS_4505 +# if defined(_MSC_VER) +# pragma warning(disable : 4505) /* unreferenced local function has been removed */ +# endif +#endif + +#ifndef SWIGUNUSEDPARM +# ifdef __cplusplus +# define SWIGUNUSEDPARM(p) +# else +# define SWIGUNUSEDPARM(p) p SWIGUNUSED +# endif +#endif + +/* internal SWIG method */ +#ifndef SWIGINTERN +# define SWIGINTERN static SWIGUNUSED +#endif + +/* internal inline SWIG method */ +#ifndef SWIGINTERNINLINE +# define SWIGINTERNINLINE SWIGINTERN SWIGINLINE +#endif + +/* exporting methods */ +#if defined(__GNUC__) +# if (__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) +# ifndef GCC_HASCLASSVISIBILITY +# define GCC_HASCLASSVISIBILITY +# endif +# endif +#endif + +#ifndef SWIGEXPORT +# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) +# if defined(STATIC_LINKED) +# define SWIGEXPORT +# else +# define SWIGEXPORT __declspec(dllexport) +# endif +# else +# if defined(__GNUC__) && defined(GCC_HASCLASSVISIBILITY) +# define SWIGEXPORT __attribute__ ((visibility("default"))) +# else +# define SWIGEXPORT +# endif +# endif +#endif + +/* calling conventions for Windows */ +#ifndef SWIGSTDCALL +# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) +# define SWIGSTDCALL __stdcall +# else +# define SWIGSTDCALL +# endif +#endif + +/* Deal with Microsoft's attempt at deprecating C standard runtime functions */ +#if !defined(SWIG_NO_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE) +# define _CRT_SECURE_NO_DEPRECATE +#endif + +/* Deal with Microsoft's attempt at deprecating methods in the standard C++ library */ +#if !defined(SWIG_NO_SCL_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_SCL_SECURE_NO_DEPRECATE) +# define _SCL_SECURE_NO_DEPRECATE +#endif + +/* Deal with Apple's deprecated 'AssertMacros.h' from Carbon-framework */ +#if defined(__APPLE__) && !defined(__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES) +# define __ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES 0 +#endif + +/* Intel's compiler complains if a variable which was never initialised is + * cast to void, which is a common idiom which we use to indicate that we + * are aware a variable isn't used. So we just silence that warning. + * See: https://github.com/swig/swig/issues/192 for more discussion. + */ +#ifdef __INTEL_COMPILER +# pragma warning disable 592 +#endif + +#if defined(__cplusplus) && __cplusplus >=201103L +# define SWIG_NULLPTR nullptr +#else +# define SWIG_NULLPTR NULL +#endif + +/* ----------------------------------------------------------------------------- + * swigcompat.swg + * + * Macros to provide support compatibility with older C and C++ standards. + * ----------------------------------------------------------------------------- */ + +/* C99 and C++11 should provide snprintf, but define SWIG_NO_SNPRINTF + * if you're missing it. + */ +#if ((defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L) || \ + (defined __cplusplus && __cplusplus >= 201103L) || \ + defined SWIG_HAVE_SNPRINTF) && \ + !defined SWIG_NO_SNPRINTF +# define SWIG_snprintf(O,S,F,A) snprintf(O,S,F,A) +# define SWIG_snprintf2(O,S,F,A,B) snprintf(O,S,F,A,B) +#else +/* Fallback versions ignore the buffer size, but most of our uses either have a + * fixed maximum possible size or dynamically allocate a buffer that's large + * enough. + */ +# define SWIG_snprintf(O,S,F,A) sprintf(O,F,A) +# define SWIG_snprintf2(O,S,F,A,B) sprintf(O,F,A,B) +#endif + + +#include +#include +#include + + +/* Support for throwing Java exceptions */ +typedef enum { + SWIG_JavaOutOfMemoryError = 1, + SWIG_JavaIOException, + SWIG_JavaRuntimeException, + SWIG_JavaIndexOutOfBoundsException, + SWIG_JavaArithmeticException, + SWIG_JavaIllegalArgumentException, + SWIG_JavaNullPointerException, + SWIG_JavaDirectorPureVirtual, + SWIG_JavaUnknownError, + SWIG_JavaIllegalStateException, +} SWIG_JavaExceptionCodes; + +typedef struct { + SWIG_JavaExceptionCodes code; + const char *java_exception; +} SWIG_JavaExceptions_t; + + +static void SWIGUNUSED SWIG_JavaThrowException(JNIEnv *jenv, SWIG_JavaExceptionCodes code, const char *msg) { + jclass excep; + static const SWIG_JavaExceptions_t java_exceptions[] = { + { SWIG_JavaOutOfMemoryError, "java/lang/OutOfMemoryError" }, + { SWIG_JavaIOException, "java/io/IOException" }, + { SWIG_JavaRuntimeException, "java/lang/RuntimeException" }, + { SWIG_JavaIndexOutOfBoundsException, "java/lang/IndexOutOfBoundsException" }, + { SWIG_JavaArithmeticException, "java/lang/ArithmeticException" }, + { SWIG_JavaIllegalArgumentException, "java/lang/IllegalArgumentException" }, + { SWIG_JavaNullPointerException, "java/lang/NullPointerException" }, + { SWIG_JavaDirectorPureVirtual, "java/lang/RuntimeException" }, + { SWIG_JavaUnknownError, "java/lang/UnknownError" }, + { SWIG_JavaIllegalStateException, "java/lang/IllegalStateException" }, + { (SWIG_JavaExceptionCodes)0, "java/lang/UnknownError" } + }; + const SWIG_JavaExceptions_t *except_ptr = java_exceptions; + + while (except_ptr->code != code && except_ptr->code) + except_ptr++; + + jenv->ExceptionClear(); + excep = jenv->FindClass(except_ptr->java_exception); + if (excep) + jenv->ThrowNew(excep, msg); +} + + +/* Contract support */ + +#define SWIG_contract_assert(nullreturn, expr, msg) do { if (!(expr)) {SWIG_JavaThrowException(jenv, SWIG_JavaIllegalArgumentException, msg); return nullreturn; } } while (0) + +/* SWIG Errors applicable to all language modules, values are reserved from -1 to -99 */ +#define SWIG_UnknownError -1 +#define SWIG_IOError -2 +#define SWIG_RuntimeError -3 +#define SWIG_IndexError -4 +#define SWIG_TypeError -5 +#define SWIG_DivisionByZero -6 +#define SWIG_OverflowError -7 +#define SWIG_SyntaxError -8 +#define SWIG_ValueError -9 +#define SWIG_SystemError -10 +#define SWIG_AttributeError -11 +#define SWIG_MemoryError -12 +#define SWIG_NullReferenceError -13 + + +/* ----------------------------------------------------------------------------- + * director_common.swg + * + * This file contains support for director classes which is common between + * languages. + * ----------------------------------------------------------------------------- */ + +/* + Use -DSWIG_DIRECTOR_STATIC if you prefer to avoid the use of the + 'Swig' namespace. This could be useful for multi-modules projects. +*/ +#ifdef SWIG_DIRECTOR_STATIC +/* Force anonymous (static) namespace */ +#define Swig +#endif +/* ----------------------------------------------------------------------------- + * director.swg + * + * This file contains support for director classes so that Java proxy + * methods can be called from C++. + * ----------------------------------------------------------------------------- */ + +#if defined(DEBUG_DIRECTOR_OWNED) || defined(DEBUG_DIRECTOR_EXCEPTION) || defined(DEBUG_DIRECTOR_THREAD_NAME) +#include +#endif + +#include + +#if defined(SWIG_JAVA_USE_THREAD_NAME) + +#if !defined(SWIG_JAVA_GET_THREAD_NAME) +namespace Swig { + SWIGINTERN int GetThreadName(char *name, size_t len); +} + +#if defined(__linux__) + +#include +SWIGINTERN int Swig::GetThreadName(char *name, size_t len) { + (void)len; +#if defined(PR_GET_NAME) + return prctl(PR_GET_NAME, (unsigned long)name, 0, 0, 0); +#else + (void)name; + return 1; +#endif +} + +#elif defined(__unix__) || defined(__APPLE__) + +#include +SWIGINTERN int Swig::GetThreadName(char *name, size_t len) { + return pthread_getname_np(pthread_self(), name, len); +} + +#else + +SWIGINTERN int Swig::GetThreadName(char *name, size_t len) { + (void)len; + (void)name; + return 1; +} +#endif + +#endif + +#endif + +#if defined(SWIG_JAVA_DETACH_ON_THREAD_END) +#include +#endif + +namespace Swig { + + /* Java object wrapper */ + class JObjectWrapper { + public: + JObjectWrapper() : jthis_(SWIG_NULLPTR), weak_global_(true) { + } + + ~JObjectWrapper() { + jthis_ = SWIG_NULLPTR; + weak_global_ = true; + } + + bool set(JNIEnv *jenv, jobject jobj, bool mem_own, bool weak_global) { + if (!jthis_) { + weak_global_ = weak_global || !mem_own; // hold as weak global if explicitly requested or not owned + if (jobj) + jthis_ = weak_global_ ? jenv->NewWeakGlobalRef(jobj) : jenv->NewGlobalRef(jobj); +#if defined(DEBUG_DIRECTOR_OWNED) + std::cout << "JObjectWrapper::set(" << jobj << ", " << (weak_global ? "weak_global" : "global_ref") << ") -> " << jthis_ << std::endl; +#endif + return true; + } else { +#if defined(DEBUG_DIRECTOR_OWNED) + std::cout << "JObjectWrapper::set(" << jobj << ", " << (weak_global ? "weak_global" : "global_ref") << ") -> already set" << std::endl; +#endif + return false; + } + } + + jobject get(JNIEnv *jenv) const { +#if defined(DEBUG_DIRECTOR_OWNED) + std::cout << "JObjectWrapper::get("; + if (jthis_) + std::cout << jthis_; + else + std::cout << "null"; + std::cout << ") -> return new local ref" << std::endl; +#endif + return (jthis_ ? jenv->NewLocalRef(jthis_) : jthis_); + } + + void release(JNIEnv *jenv) { +#if defined(DEBUG_DIRECTOR_OWNED) + std::cout << "JObjectWrapper::release(" << jthis_ << "): " << (weak_global_ ? "weak global ref" : "global ref") << std::endl; +#endif + if (jthis_) { + if (weak_global_) { + if (jenv->IsSameObject(jthis_, SWIG_NULLPTR) == JNI_FALSE) + jenv->DeleteWeakGlobalRef((jweak)jthis_); + } else + jenv->DeleteGlobalRef(jthis_); + } + + jthis_ = SWIG_NULLPTR; + weak_global_ = true; + } + + /* Only call peek if you know what you are doing wrt to weak/global references */ + jobject peek() { + return jthis_; + } + + /* Java proxy releases ownership of C++ object, C++ object is now + responsible for destruction (creates NewGlobalRef to pin Java proxy) */ + void java_change_ownership(JNIEnv *jenv, jobject jself, bool take_or_release) { + if (take_or_release) { /* Java takes ownership of C++ object's lifetime. */ + if (!weak_global_) { + jenv->DeleteGlobalRef(jthis_); + jthis_ = jenv->NewWeakGlobalRef(jself); + weak_global_ = true; + } + } else { + /* Java releases ownership of C++ object's lifetime */ + if (weak_global_) { + jenv->DeleteWeakGlobalRef((jweak)jthis_); + jthis_ = jenv->NewGlobalRef(jself); + weak_global_ = false; + } + } + } + +#if defined(SWIG_JAVA_DETACH_ON_THREAD_END) + static void detach(void *jvm) { + static_cast(jvm)->DetachCurrentThread(); + } + + static void make_detach_key() { + pthread_key_create(&detach_key_, detach); + } + + /* thread-local key to register a destructor */ + static pthread_key_t detach_key_; +#endif + + private: + /* pointer to Java object */ + jobject jthis_; + /* Local or global reference flag */ + bool weak_global_; + }; + +#if defined(SWIG_JAVA_DETACH_ON_THREAD_END) + pthread_key_t JObjectWrapper::detach_key_; +#endif + + /* Local JNI reference deleter */ + class LocalRefGuard { + JNIEnv *jenv_; + jobject jobj_; + + // non-copyable + LocalRefGuard(const LocalRefGuard &); + LocalRefGuard &operator=(const LocalRefGuard &); + public: + LocalRefGuard(JNIEnv *jenv, jobject jobj): jenv_(jenv), jobj_(jobj) {} + ~LocalRefGuard() { + if (jobj_) + jenv_->DeleteLocalRef(jobj_); + } + }; + + /* director base class */ + class Director { + /* pointer to Java virtual machine */ + JavaVM *swig_jvm_; + + protected: +#if defined (_MSC_VER) && (_MSC_VER<1300) + class JNIEnvWrapper; + friend class JNIEnvWrapper; +#endif + /* Utility class for managing the JNI environment */ + class JNIEnvWrapper { + const Director *director_; + JNIEnv *jenv_; + int env_status; + public: + JNIEnvWrapper(const Director *director) : director_(director), jenv_(SWIG_NULLPTR), env_status(0) { +#if defined(__ANDROID__) + JNIEnv **jenv = &jenv_; +#else + void **jenv = (void **)&jenv_; +#endif + env_status = director_->swig_jvm_->GetEnv((void **)&jenv_, JNI_VERSION_1_2); + JavaVMAttachArgs args; + args.version = JNI_VERSION_1_2; + args.group = SWIG_NULLPTR; + args.name = SWIG_NULLPTR; +#if defined(SWIG_JAVA_USE_THREAD_NAME) + char thread_name[64]; // MAX_TASK_COMM_LEN=16 is hard-coded in the Linux kernel and MacOS has MAXTHREADNAMESIZE=64. + if (Swig::GetThreadName(thread_name, sizeof(thread_name)) == 0) { + args.name = thread_name; +#if defined(DEBUG_DIRECTOR_THREAD_NAME) + std::cout << "JNIEnvWrapper: thread name: " << thread_name << std::endl; + } else { + std::cout << "JNIEnvWrapper: Couldn't set Java thread name" << std::endl; +#endif + } +#endif +#if defined(SWIG_JAVA_ATTACH_CURRENT_THREAD_AS_DAEMON) + // Attach a daemon thread to the JVM. Useful when the JVM should not wait for + // the thread to exit upon shutdown. Only for jdk-1.4 and later. + director_->swig_jvm_->AttachCurrentThreadAsDaemon(jenv, &args); +#else + director_->swig_jvm_->AttachCurrentThread(jenv, &args); +#endif + +#if defined(SWIG_JAVA_DETACH_ON_THREAD_END) + // At least on Android 6, detaching after every call causes a memory leak. + // Instead, register a thread desructor and detach only when the thread ends. + // See https://developer.android.com/training/articles/perf-jni#threads + static pthread_once_t once = PTHREAD_ONCE_INIT; + + pthread_once(&once, JObjectWrapper::make_detach_key); + pthread_setspecific(JObjectWrapper::detach_key_, director->swig_jvm_); +#endif + } + ~JNIEnvWrapper() { +#if !defined(SWIG_JAVA_DETACH_ON_THREAD_END) && !defined(SWIG_JAVA_NO_DETACH_CURRENT_THREAD) + // Some JVMs, eg jdk-1.4.2 and lower on Solaris have a bug and crash with the DetachCurrentThread call. + // However, without this call, the JVM hangs on exit when the thread was not created by the JVM and creates a memory leak. + if (env_status == JNI_EDETACHED) + director_->swig_jvm_->DetachCurrentThread(); +#endif + } + JNIEnv *getJNIEnv() const { + return jenv_; + } + }; + + struct SwigDirectorMethod { + const char *name; + const char *desc; + jmethodID methid; + SwigDirectorMethod(JNIEnv *jenv, jclass baseclass, const char *name, const char *desc) : name(name), desc(desc) { + methid = jenv->GetMethodID(baseclass, name, desc); + } + }; + + /* Java object wrapper */ + JObjectWrapper swig_self_; + + /* Disconnect director from Java object */ + void swig_disconnect_director_self(const char *disconn_method) { + JNIEnvWrapper jnienv(this) ; + JNIEnv *jenv = jnienv.getJNIEnv() ; + jobject jobj = swig_self_.get(jenv); + LocalRefGuard ref_deleter(jenv, jobj); +#if defined(DEBUG_DIRECTOR_OWNED) + std::cout << "Swig::Director::disconnect_director_self(" << jobj << ")" << std::endl; +#endif + if (jobj && jenv->IsSameObject(jobj, SWIG_NULLPTR) == JNI_FALSE) { + jmethodID disconn_meth = jenv->GetMethodID(jenv->GetObjectClass(jobj), disconn_method, "()V"); + if (disconn_meth) { +#if defined(DEBUG_DIRECTOR_OWNED) + std::cout << "Swig::Director::disconnect_director_self upcall to " << disconn_method << std::endl; +#endif + jenv->CallVoidMethod(jobj, disconn_meth); + } + } + } + + jclass swig_new_global_ref(JNIEnv *jenv, const char *classname) { + jclass clz = jenv->FindClass(classname); + return clz ? (jclass)jenv->NewGlobalRef(clz) : SWIG_NULLPTR; + } + + public: + Director(JNIEnv *jenv) : swig_jvm_((JavaVM *) SWIG_NULLPTR), swig_self_() { + /* Acquire the Java VM pointer */ + jenv->GetJavaVM(&swig_jvm_); + } + + virtual ~Director() { + JNIEnvWrapper jnienv(this) ; + JNIEnv *jenv = jnienv.getJNIEnv() ; + swig_self_.release(jenv); + } + + bool swig_set_self(JNIEnv *jenv, jobject jself, bool mem_own, bool weak_global) { + return swig_self_.set(jenv, jself, mem_own, weak_global); + } + + jobject swig_get_self(JNIEnv *jenv) const { + return swig_self_.get(jenv); + } + + // Change C++ object's ownership, relative to Java + void swig_java_change_ownership(JNIEnv *jenv, jobject jself, bool take_or_release) { + swig_self_.java_change_ownership(jenv, jself, take_or_release); + } + }; + + // Zero initialized bool array + template class BoolArray { + bool array_[N]; + public: + BoolArray() { + memset(array_, 0, sizeof(array_)); + } + bool& operator[](size_t n) { + return array_[n]; + } + bool operator[](size_t n) const { + return array_[n]; + } + }; + + // Utility classes and functions for exception handling. + + // Simple holder for a Java string during exception handling, providing access to a c-style string + class JavaString { + public: + JavaString(JNIEnv *jenv, jstring jstr) : jenv_(jenv), jstr_(jstr), cstr_(SWIG_NULLPTR) { + if (jenv_ && jstr_) + cstr_ = (const char *) jenv_->GetStringUTFChars(jstr_, SWIG_NULLPTR); + } + + ~JavaString() { + if (jenv_ && jstr_ && cstr_) + jenv_->ReleaseStringUTFChars(jstr_, cstr_); + } + + const char *c_str(const char *null_string = "null JavaString") const { + return cstr_ ? cstr_ : null_string; + } + + private: + // non-copyable + JavaString(const JavaString &); + JavaString &operator=(const JavaString &); + + JNIEnv *jenv_; + jstring jstr_; + const char *cstr_; + }; + + // Helper class to extract the exception message from a Java throwable + class JavaExceptionMessage { + public: + JavaExceptionMessage(JNIEnv *jenv, jthrowable throwable) : message_(jenv, exceptionMessageFromThrowable(jenv, throwable)) { + } + + // Return a C string of the exception message in the jthrowable passed in the constructor + // If no message is available, null_string is return instead + const char *message(const char *null_string = "Could not get exception message in JavaExceptionMessage") const { + return message_.c_str(null_string); + } + + private: + // non-copyable + JavaExceptionMessage(const JavaExceptionMessage &); + JavaExceptionMessage &operator=(const JavaExceptionMessage &); + + // Get exception message by calling Java method Throwable.getMessage() + static jstring exceptionMessageFromThrowable(JNIEnv *jenv, jthrowable throwable) { + jstring jmsg = SWIG_NULLPTR; + if (jenv && throwable) { + jenv->ExceptionClear(); // Cannot invoke methods with any pending exceptions + jclass throwclz = jenv->GetObjectClass(throwable); + if (throwclz) { + // All Throwable classes have a getMessage() method, so call it to extract the exception message + jmethodID getMessageMethodID = jenv->GetMethodID(throwclz, "getMessage", "()Ljava/lang/String;"); + if (getMessageMethodID) + jmsg = (jstring)jenv->CallObjectMethod(throwable, getMessageMethodID); + } + if (jmsg == SWIG_NULLPTR && jenv->ExceptionCheck()) + jenv->ExceptionClear(); + } + return jmsg; + } + + JavaString message_; + }; + + // C++ Exception class for handling Java exceptions thrown during a director method Java upcall + class DirectorException : public std::exception { + public: + + // Construct exception from a Java throwable + DirectorException(JNIEnv *jenv, jthrowable throwable) : jenv_(jenv), throwable_(throwable), classname_(SWIG_NULLPTR), msg_(SWIG_NULLPTR) { + + // Call Java method Object.getClass().getName() to obtain the throwable's class name (delimited by '/') + if (jenv && throwable) { + jenv->ExceptionClear(); // Cannot invoke methods with any pending exceptions + jclass throwclz = jenv->GetObjectClass(throwable); + if (throwclz) { + jclass clzclz = jenv->GetObjectClass(throwclz); + if (clzclz) { + jmethodID getNameMethodID = jenv->GetMethodID(clzclz, "getName", "()Ljava/lang/String;"); + if (getNameMethodID) { + jstring jstr_classname = (jstring)(jenv->CallObjectMethod(throwclz, getNameMethodID)); + // Copy strings, since there is no guarantee that jenv will be active when handled + if (jstr_classname) { + JavaString jsclassname(jenv, jstr_classname); + const char *classname = jsclassname.c_str(SWIG_NULLPTR); + if (classname) + classname_ = copypath(classname); + } + } + } + } + } + + JavaExceptionMessage exceptionmsg(jenv, throwable); + msg_ = copystr(exceptionmsg.message(SWIG_NULLPTR)); + } + + // More general constructor for handling as a java.lang.RuntimeException + DirectorException(const char *msg) : jenv_(SWIG_NULLPTR), throwable_(SWIG_NULLPTR), classname_(SWIG_NULLPTR), msg_(msg ? copystr(msg) : SWIG_NULLPTR) { + } + + ~DirectorException() throw() { + delete[] classname_; + delete[] msg_; + } + + const char *what() const throw() { + return msg_ ? msg_ : "Unspecified DirectorException message"; + } + + // Reconstruct and raise/throw the Java Exception that caused the DirectorException + // Note that any error in the JNI exception handling results in a Java RuntimeException + void throwException(JNIEnv *jenv) const { + if (jenv) { + if (jenv == jenv_ && throwable_) { + // Throw original exception if not already pending + jthrowable throwable = jenv->ExceptionOccurred(); + if (throwable && jenv->IsSameObject(throwable, throwable_) == JNI_FALSE) { + jenv->ExceptionClear(); + throwable = SWIG_NULLPTR; + } + if (!throwable) + jenv->Throw(throwable_); + } else { + // Try and reconstruct original exception, but original stacktrace is not reconstructed + jenv->ExceptionClear(); + + jmethodID ctorMethodID = SWIG_NULLPTR; + jclass throwableclass = SWIG_NULLPTR; + if (classname_) { + throwableclass = jenv->FindClass(classname_); + if (throwableclass) + ctorMethodID = jenv->GetMethodID(throwableclass, "", "(Ljava/lang/String;)V"); + } + + if (ctorMethodID) { + jenv->ThrowNew(throwableclass, what()); + } else { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, what()); + } + } + } + } + + // Deprecated - use throwException + void raiseJavaException(JNIEnv *jenv) const { + throwException(jenv); + } + + // Create and throw the DirectorException + static void raise(JNIEnv *jenv, jthrowable throwable) { + throw DirectorException(jenv, throwable); + } + + private: + static char *copypath(const char *srcmsg) { + char *target = copystr(srcmsg); + for (char *c=target; *c; ++c) { + if ('.' == *c) + *c = '/'; + } + return target; + } + + static char *copystr(const char *srcmsg) { + char *target = SWIG_NULLPTR; + if (srcmsg) { + size_t msglen = strlen(srcmsg) + 1; + target = new char[msglen]; + strncpy(target, srcmsg, msglen); + } + return target; + } + + JNIEnv *jenv_; + jthrowable throwable_; + const char *classname_; + const char *msg_; + }; + + // Helper method to determine if a Java throwable matches a particular Java class type + // Note side effect of clearing any pending exceptions + SWIGINTERN bool ExceptionMatches(JNIEnv *jenv, jthrowable throwable, const char *classname) { + bool matches = false; + + if (throwable && jenv && classname) { + // Exceptions need to be cleared for correct behavior. + // The caller of ExceptionMatches should restore pending exceptions if desired - + // the caller already has the throwable. + jenv->ExceptionClear(); + + jclass clz = jenv->FindClass(classname); + if (clz) { + jclass classclz = jenv->GetObjectClass(clz); + jmethodID isInstanceMethodID = jenv->GetMethodID(classclz, "isInstance", "(Ljava/lang/Object;)Z"); + if (isInstanceMethodID) { + matches = jenv->CallBooleanMethod(clz, isInstanceMethodID, throwable) != 0; + } + } + +#if defined(DEBUG_DIRECTOR_EXCEPTION) + if (jenv->ExceptionCheck()) { + // Typically occurs when an invalid classname argument is passed resulting in a ClassNotFoundException + JavaExceptionMessage exc(jenv, jenv->ExceptionOccurred()); + std::cout << "Error: ExceptionMatches: class '" << classname << "' : " << exc.message() << std::endl; + } +#endif + } + return matches; + } +} + +namespace Swig { + namespace { + jclass jclass_wedpr_java_transportJNI = NULL; + jmethodID director_method_ids[4]; + } +} + +#ifdef __cplusplus +#include +/* SwigValueWrapper is described in swig.swg */ +template class SwigValueWrapper { + struct SwigSmartPointer { + T *ptr; + SwigSmartPointer(T *p) : ptr(p) { } + ~SwigSmartPointer() { delete ptr; } + SwigSmartPointer& operator=(SwigSmartPointer& rhs) { T* oldptr = ptr; ptr = 0; delete oldptr; ptr = rhs.ptr; rhs.ptr = 0; return *this; } + void reset(T *p) { T* oldptr = ptr; ptr = 0; delete oldptr; ptr = p; } + } pointer; + SwigValueWrapper& operator=(const SwigValueWrapper& rhs); + SwigValueWrapper(const SwigValueWrapper& rhs); +public: + SwigValueWrapper() : pointer(0) { } + SwigValueWrapper& operator=(const T& t) { SwigSmartPointer tmp(new T(t)); pointer = tmp; return *this; } +#if __cplusplus >=201103L + SwigValueWrapper& operator=(T&& t) { SwigSmartPointer tmp(new T(std::move(t))); pointer = tmp; return *this; } + operator T&&() const { return std::move(*pointer.ptr); } +#else + operator T&() const { return *pointer.ptr; } +#endif + T *operator&() const { return pointer.ptr; } + static void reset(SwigValueWrapper& t, T *p) { t.pointer.reset(p); } +}; + +/* + * SwigValueInit() is a generic initialisation solution as the following approach: + * + * T c_result = T(); + * + * doesn't compile for all types for example: + * + * unsigned int c_result = unsigned int(); + */ +template T SwigValueInit() { + return T(); +} + +#if __cplusplus >=201103L +# define SWIG_STD_MOVE(OBJ) std::move(OBJ) +#else +# define SWIG_STD_MOVE(OBJ) OBJ +#endif + +#endif + + +#include // Use the C99 official header + + +#include +#include + + +#include +#include + + +#include + + +#define SWIG_FILE_WITH_INIT +#include +#include +#include +#include "wedpr-transport/sdk/src/TransportBuilder.h" +#include "wedpr-transport/sdk/src/Transport.h" +#include "ppc-framework/libwrapper/Buffer.h" +#include "ppc-framework/front/IFront.h" +#include "ppc-framework/protocol/INodeInfo.h" +#include "ppc-framework/front/INodeDiscovery.h" +#include "ppc-framework/protocol/RouteType.h" +#include "ppc-framework/front/FrontConfig.h" +#include "ppc-framework/protocol/GrpcConfig.h" +#include +#include "ppc-framework/protocol/EndPoint.h" +#include "ppc-framework/protocol/Message.h" +#include "ppc-framework/protocol/MessagePayload.h" + + +/* Check for overflow converting to Java int (always signed 32-bit) from (unsigned variable-bit) size_t */ +SWIGINTERN jint SWIG_JavaIntFromSize_t(size_t size) { + static const jint JINT_MAX = 0x7FFFFFFF; + return (size > (size_t)JINT_MAX) ? -1 : (jint)size; +} + + +SWIGINTERN jint SWIG_VectorSize(size_t size) { + jint sz = SWIG_JavaIntFromSize_t(size); + if (sz == -1) + throw std::out_of_range("vector size is too large to fit into a Java int"); + return sz; +} + +SWIGINTERN std::vector< uint8_t > *new_std_vector_Sl_uint8_t_Sg___SWIG_2(jint count,unsigned char const &value){ + if (count < 0) + throw std::out_of_range("vector count must be positive"); + return new std::vector< unsigned char >(static_cast::size_type>(count), value); + } +SWIGINTERN jint std_vector_Sl_uint8_t_Sg__doCapacity(std::vector< uint8_t > *self){ + return SWIG_VectorSize(self->capacity()); + } +SWIGINTERN void std_vector_Sl_uint8_t_Sg__doReserve(std::vector< uint8_t > *self,jint n){ + if (n < 0) + throw std::out_of_range("vector reserve size must be positive"); + self->reserve(n); + } +SWIGINTERN jint std_vector_Sl_uint8_t_Sg__doSize(std::vector< uint8_t > const *self){ + return SWIG_VectorSize(self->size()); + } +SWIGINTERN void std_vector_Sl_uint8_t_Sg__doAdd__SWIG_0(std::vector< uint8_t > *self,std::vector< unsigned char >::value_type const &x){ + self->push_back(x); + } +SWIGINTERN void std_vector_Sl_uint8_t_Sg__doAdd__SWIG_1(std::vector< uint8_t > *self,jint index,std::vector< unsigned char >::value_type const &x){ + jint size = static_cast(self->size()); + if (0 <= index && index <= size) { + self->insert(self->begin() + index, x); + } else { + throw std::out_of_range("vector index out of range"); + } + } +SWIGINTERN std::vector< unsigned char >::value_type std_vector_Sl_uint8_t_Sg__doRemove(std::vector< uint8_t > *self,jint index){ + jint size = static_cast(self->size()); + if (0 <= index && index < size) { + unsigned char const old_value = (*self)[index]; + self->erase(self->begin() + index); + return old_value; + } else { + throw std::out_of_range("vector index out of range"); + } + } +SWIGINTERN std::vector< unsigned char >::value_type const &std_vector_Sl_uint8_t_Sg__doGet(std::vector< uint8_t > *self,jint index){ + jint size = static_cast(self->size()); + if (index >= 0 && index < size) + return (*self)[index]; + else + throw std::out_of_range("vector index out of range"); + } +SWIGINTERN std::vector< unsigned char >::value_type std_vector_Sl_uint8_t_Sg__doSet(std::vector< uint8_t > *self,jint index,std::vector< unsigned char >::value_type const &val){ + jint size = static_cast(self->size()); + if (index >= 0 && index < size) { + unsigned char const old_value = (*self)[index]; + (*self)[index] = val; + return old_value; + } + else + throw std::out_of_range("vector index out of range"); + } +SWIGINTERN void std_vector_Sl_uint8_t_Sg__doRemoveRange(std::vector< uint8_t > *self,jint fromIndex,jint toIndex){ + jint size = static_cast(self->size()); + if (0 <= fromIndex && fromIndex <= toIndex && toIndex <= size) { + self->erase(self->begin() + fromIndex, self->begin() + toIndex); + } else { + throw std::out_of_range("vector index out of range"); + } + } +SWIGINTERN std::vector< int8_t > *new_std_vector_Sl_int8_t_Sg___SWIG_2(jint count,signed char const &value){ + if (count < 0) + throw std::out_of_range("vector count must be positive"); + return new std::vector< signed char >(static_cast::size_type>(count), value); + } +SWIGINTERN jint std_vector_Sl_int8_t_Sg__doCapacity(std::vector< int8_t > *self){ + return SWIG_VectorSize(self->capacity()); + } +SWIGINTERN void std_vector_Sl_int8_t_Sg__doReserve(std::vector< int8_t > *self,jint n){ + if (n < 0) + throw std::out_of_range("vector reserve size must be positive"); + self->reserve(n); + } +SWIGINTERN jint std_vector_Sl_int8_t_Sg__doSize(std::vector< int8_t > const *self){ + return SWIG_VectorSize(self->size()); + } +SWIGINTERN void std_vector_Sl_int8_t_Sg__doAdd__SWIG_0(std::vector< int8_t > *self,std::vector< signed char >::value_type const &x){ + self->push_back(x); + } +SWIGINTERN void std_vector_Sl_int8_t_Sg__doAdd__SWIG_1(std::vector< int8_t > *self,jint index,std::vector< signed char >::value_type const &x){ + jint size = static_cast(self->size()); + if (0 <= index && index <= size) { + self->insert(self->begin() + index, x); + } else { + throw std::out_of_range("vector index out of range"); + } + } +SWIGINTERN std::vector< signed char >::value_type std_vector_Sl_int8_t_Sg__doRemove(std::vector< int8_t > *self,jint index){ + jint size = static_cast(self->size()); + if (0 <= index && index < size) { + signed char const old_value = (*self)[index]; + self->erase(self->begin() + index); + return old_value; + } else { + throw std::out_of_range("vector index out of range"); + } + } +SWIGINTERN std::vector< signed char >::value_type const &std_vector_Sl_int8_t_Sg__doGet(std::vector< int8_t > *self,jint index){ + jint size = static_cast(self->size()); + if (index >= 0 && index < size) + return (*self)[index]; + else + throw std::out_of_range("vector index out of range"); + } +SWIGINTERN std::vector< signed char >::value_type std_vector_Sl_int8_t_Sg__doSet(std::vector< int8_t > *self,jint index,std::vector< signed char >::value_type const &val){ + jint size = static_cast(self->size()); + if (index >= 0 && index < size) { + signed char const old_value = (*self)[index]; + (*self)[index] = val; + return old_value; + } + else + throw std::out_of_range("vector index out of range"); + } +SWIGINTERN void std_vector_Sl_int8_t_Sg__doRemoveRange(std::vector< int8_t > *self,jint fromIndex,jint toIndex){ + jint size = static_cast(self->size()); + if (0 <= fromIndex && fromIndex <= toIndex && toIndex <= size) { + self->erase(self->begin() + fromIndex, self->begin() + toIndex); + } else { + throw std::out_of_range("vector index out of range"); + } + } +SWIGINTERN std::vector< std::string > *new_std_vector_Sl_std_string_Sg___SWIG_2(jint count,std::string const &value){ + if (count < 0) + throw std::out_of_range("vector count must be positive"); + return new std::vector< std::string >(static_cast::size_type>(count), value); + } +SWIGINTERN jint std_vector_Sl_std_string_Sg__doCapacity(std::vector< std::string > *self){ + return SWIG_VectorSize(self->capacity()); + } +SWIGINTERN void std_vector_Sl_std_string_Sg__doReserve(std::vector< std::string > *self,jint n){ + if (n < 0) + throw std::out_of_range("vector reserve size must be positive"); + self->reserve(n); + } +SWIGINTERN jint std_vector_Sl_std_string_Sg__doSize(std::vector< std::string > const *self){ + return SWIG_VectorSize(self->size()); + } +SWIGINTERN void std_vector_Sl_std_string_Sg__doAdd__SWIG_0(std::vector< std::string > *self,std::vector< std::string >::value_type const &x){ + self->push_back(x); + } +SWIGINTERN void std_vector_Sl_std_string_Sg__doAdd__SWIG_1(std::vector< std::string > *self,jint index,std::vector< std::string >::value_type const &x){ + jint size = static_cast(self->size()); + if (0 <= index && index <= size) { + self->insert(self->begin() + index, x); + } else { + throw std::out_of_range("vector index out of range"); + } + } +SWIGINTERN std::vector< std::string >::value_type std_vector_Sl_std_string_Sg__doRemove(std::vector< std::string > *self,jint index){ + jint size = static_cast(self->size()); + if (0 <= index && index < size) { + std::string const old_value = (*self)[index]; + self->erase(self->begin() + index); + return old_value; + } else { + throw std::out_of_range("vector index out of range"); + } + } +SWIGINTERN std::vector< std::string >::value_type const &std_vector_Sl_std_string_Sg__doGet(std::vector< std::string > *self,jint index){ + jint size = static_cast(self->size()); + if (index >= 0 && index < size) + return (*self)[index]; + else + throw std::out_of_range("vector index out of range"); + } +SWIGINTERN std::vector< std::string >::value_type std_vector_Sl_std_string_Sg__doSet(std::vector< std::string > *self,jint index,std::vector< std::string >::value_type const &val){ + jint size = static_cast(self->size()); + if (index >= 0 && index < size) { + std::string const old_value = (*self)[index]; + (*self)[index] = val; + return old_value; + } + else + throw std::out_of_range("vector index out of range"); + } +SWIGINTERN void std_vector_Sl_std_string_Sg__doRemoveRange(std::vector< std::string > *self,jint fromIndex,jint toIndex){ + jint size = static_cast(self->size()); + if (0 <= fromIndex && fromIndex <= toIndex && toIndex <= size) { + self->erase(self->begin() + fromIndex, self->begin() + toIndex); + } else { + throw std::out_of_range("vector index out of range"); + } + } +SWIGINTERN std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *new_std_vector_Sl_std_shared_ptr_Sl_ppc_protocol_INodeInfo_Sg__Sg___SWIG_2(jint count,std::shared_ptr< ppc::protocol::INodeInfo > const &value){ + if (count < 0) + throw std::out_of_range("vector count must be positive"); + return new std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >(static_cast >::size_type>(count), value); + } +SWIGINTERN jint std_vector_Sl_std_shared_ptr_Sl_ppc_protocol_INodeInfo_Sg__Sg__doCapacity(std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *self){ + return SWIG_VectorSize(self->capacity()); + } +SWIGINTERN void std_vector_Sl_std_shared_ptr_Sl_ppc_protocol_INodeInfo_Sg__Sg__doReserve(std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *self,jint n){ + if (n < 0) + throw std::out_of_range("vector reserve size must be positive"); + self->reserve(n); + } +SWIGINTERN jint std_vector_Sl_std_shared_ptr_Sl_ppc_protocol_INodeInfo_Sg__Sg__doSize(std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > const *self){ + return SWIG_VectorSize(self->size()); + } +SWIGINTERN void std_vector_Sl_std_shared_ptr_Sl_ppc_protocol_INodeInfo_Sg__Sg__doAdd__SWIG_0(std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *self,std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type const &x){ + self->push_back(x); + } +SWIGINTERN void std_vector_Sl_std_shared_ptr_Sl_ppc_protocol_INodeInfo_Sg__Sg__doAdd__SWIG_1(std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *self,jint index,std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type const &x){ + jint size = static_cast(self->size()); + if (0 <= index && index <= size) { + self->insert(self->begin() + index, x); + } else { + throw std::out_of_range("vector index out of range"); + } + } +SWIGINTERN std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type std_vector_Sl_std_shared_ptr_Sl_ppc_protocol_INodeInfo_Sg__Sg__doRemove(std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *self,jint index){ + jint size = static_cast(self->size()); + if (0 <= index && index < size) { + std::shared_ptr< ppc::protocol::INodeInfo > const old_value = (*self)[index]; + self->erase(self->begin() + index); + return old_value; + } else { + throw std::out_of_range("vector index out of range"); + } + } +SWIGINTERN std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type const &std_vector_Sl_std_shared_ptr_Sl_ppc_protocol_INodeInfo_Sg__Sg__doGet(std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *self,jint index){ + jint size = static_cast(self->size()); + if (index >= 0 && index < size) + return (*self)[index]; + else + throw std::out_of_range("vector index out of range"); + } +SWIGINTERN std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type std_vector_Sl_std_shared_ptr_Sl_ppc_protocol_INodeInfo_Sg__Sg__doSet(std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *self,jint index,std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type const &val){ + jint size = static_cast(self->size()); + if (index >= 0 && index < size) { + std::shared_ptr< ppc::protocol::INodeInfo > const old_value = (*self)[index]; + (*self)[index] = val; + return old_value; + } + else + throw std::out_of_range("vector index out of range"); + } +SWIGINTERN void std_vector_Sl_std_shared_ptr_Sl_ppc_protocol_INodeInfo_Sg__Sg__doRemoveRange(std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *self,jint fromIndex,jint toIndex){ + jint size = static_cast(self->size()); + if (0 <= fromIndex && fromIndex <= toIndex && toIndex <= size) { + self->erase(self->begin() + fromIndex, self->begin() + toIndex); + } else { + throw std::out_of_range("vector index out of range"); + } + } + +SWIGINTERN void SWIG_JavaException(JNIEnv *jenv, int code, const char *msg) { + SWIG_JavaExceptionCodes exception_code = SWIG_JavaUnknownError; + switch(code) { + case SWIG_MemoryError: + exception_code = SWIG_JavaOutOfMemoryError; + break; + case SWIG_IOError: + exception_code = SWIG_JavaIOException; + break; + case SWIG_SystemError: + case SWIG_RuntimeError: + exception_code = SWIG_JavaRuntimeException; + break; + case SWIG_OverflowError: + case SWIG_IndexError: + exception_code = SWIG_JavaIndexOutOfBoundsException; + break; + case SWIG_DivisionByZero: + exception_code = SWIG_JavaArithmeticException; + break; + case SWIG_SyntaxError: + case SWIG_ValueError: + case SWIG_TypeError: + exception_code = SWIG_JavaIllegalArgumentException; + break; + case SWIG_UnknownError: + default: + exception_code = SWIG_JavaUnknownError; + break; + } + SWIG_JavaThrowException(jenv, exception_code, msg); +} + + +#include +#include + + +struct SWIG_null_deleter { + void operator() (void const *) const { + } +}; +#define SWIG_NO_NULL_DELETER_0 , SWIG_null_deleter() +#define SWIG_NO_NULL_DELETER_1 +#define SWIG_NO_NULL_DELETER_SWIG_POINTER_NEW +#define SWIG_NO_NULL_DELETER_SWIG_POINTER_OWN + + +#include + + + +/* --------------------------------------------------- + * C++ director class methods + * --------------------------------------------------- */ + +#include "wedpr_java_transportJAVA_wrap.h" + +SwigDirector_ErrorCallback::SwigDirector_ErrorCallback(JNIEnv *jenv) : ppc::front::ErrorCallback(), Swig::Director(jenv) { +} + +SwigDirector_ErrorCallback::~SwigDirector_ErrorCallback() { + swig_disconnect_director_self("swigDirectorDisconnect"); +} + + +void SwigDirector_ErrorCallback::onError(bcos::Error::Ptr error) { + JNIEnvWrapper swigjnienv(this) ; + JNIEnv * jenv = swigjnienv.getJNIEnv() ; + jobject swigjobj = (jobject) NULL ; + jlong jerror ; + + if (!swig_override[0]) { + SWIG_JavaThrowException(JNIEnvWrapper(this).getJNIEnv(), SWIG_JavaDirectorPureVirtual, "Attempted to invoke pure virtual method ppc::front::ErrorCallback::onError."); + return; + } + swigjobj = swig_get_self(jenv); + if (swigjobj && jenv->IsSameObject(swigjobj, NULL) == JNI_FALSE) { + jerror = 0; + if (error) { + *((std::shared_ptr< bcos::Error > **)&jerror) = new std::shared_ptr< bcos::Error >(error); + } + jenv->CallStaticVoidMethod(Swig::jclass_wedpr_java_transportJNI, Swig::director_method_ids[0], swigjobj, jerror); + jthrowable swigerror = jenv->ExceptionOccurred(); + if (swigerror) { + Swig::DirectorException::raise(jenv, swigerror); + } + + } else { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null upcall object in ppc::front::ErrorCallback::onError "); + } + if (swigjobj) jenv->DeleteLocalRef(swigjobj); +} + +void SwigDirector_ErrorCallback::swig_connect_director(JNIEnv *jenv, jobject jself, jclass jcls, bool swig_mem_own, bool weak_global) { + static jclass baseclass = swig_new_global_ref(jenv, "com/webank/wedpr/sdk/jni/generated/ErrorCallback"); + if (!baseclass) return; + static SwigDirectorMethod methods[] = { + SwigDirectorMethod(jenv, baseclass, "onError", "(Lcom/webank/wedpr/sdk/jni/generated/Error;)V") + }; + + if (swig_set_self(jenv, jself, swig_mem_own, weak_global)) { + bool derived = (jenv->IsSameObject(baseclass, jcls) ? false : true); + for (int i = 0; i < 1; ++i) { + swig_override[i] = false; + if (derived) { + jmethodID methid = jenv->GetMethodID(jcls, methods[i].name, methods[i].desc); + swig_override[i] = methods[i].methid && (methid != methods[i].methid); + jenv->ExceptionClear(); + } + } + } +} + + +SwigDirector_MessageDispatcherHandler::SwigDirector_MessageDispatcherHandler(JNIEnv *jenv) : ppc::front::MessageDispatcherHandler(), Swig::Director(jenv) { +} + +SwigDirector_MessageDispatcherHandler::~SwigDirector_MessageDispatcherHandler() { + swig_disconnect_director_self("swigDirectorDisconnect"); +} + + +void SwigDirector_MessageDispatcherHandler::onMessage(ppc::protocol::Message::Ptr msg) { + JNIEnvWrapper swigjnienv(this) ; + JNIEnv * jenv = swigjnienv.getJNIEnv() ; + jobject swigjobj = (jobject) NULL ; + jlong jmsg ; + + if (!swig_override[0]) { + SWIG_JavaThrowException(JNIEnvWrapper(this).getJNIEnv(), SWIG_JavaDirectorPureVirtual, "Attempted to invoke pure virtual method ppc::front::MessageDispatcherHandler::onMessage."); + return; + } + swigjobj = swig_get_self(jenv); + if (swigjobj && jenv->IsSameObject(swigjobj, NULL) == JNI_FALSE) { + jmsg = 0; + if (msg) { + *((std::shared_ptr< ppc::protocol::Message > **)&jmsg) = new std::shared_ptr< ppc::protocol::Message >(msg); + } + jenv->CallStaticVoidMethod(Swig::jclass_wedpr_java_transportJNI, Swig::director_method_ids[1], swigjobj, jmsg); + jthrowable swigerror = jenv->ExceptionOccurred(); + if (swigerror) { + Swig::DirectorException::raise(jenv, swigerror); + } + + } else { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null upcall object in ppc::front::MessageDispatcherHandler::onMessage "); + } + if (swigjobj) jenv->DeleteLocalRef(swigjobj); +} + +void SwigDirector_MessageDispatcherHandler::swig_connect_director(JNIEnv *jenv, jobject jself, jclass jcls, bool swig_mem_own, bool weak_global) { + static jclass baseclass = swig_new_global_ref(jenv, "com/webank/wedpr/sdk/jni/generated/MessageDispatcherHandler"); + if (!baseclass) return; + static SwigDirectorMethod methods[] = { + SwigDirectorMethod(jenv, baseclass, "onMessage", "(Lcom/webank/wedpr/sdk/jni/generated/Message;)V") + }; + + if (swig_set_self(jenv, jself, swig_mem_own, weak_global)) { + bool derived = (jenv->IsSameObject(baseclass, jcls) ? false : true); + for (int i = 0; i < 1; ++i) { + swig_override[i] = false; + if (derived) { + jmethodID methid = jenv->GetMethodID(jcls, methods[i].name, methods[i].desc); + swig_override[i] = methods[i].methid && (methid != methods[i].methid); + jenv->ExceptionClear(); + } + } + } +} + + +SwigDirector_IMessageHandler::SwigDirector_IMessageHandler(JNIEnv *jenv) : ppc::front::IMessageHandler(), Swig::Director(jenv) { +} + +SwigDirector_IMessageHandler::~SwigDirector_IMessageHandler() { + swig_disconnect_director_self("swigDirectorDisconnect"); +} + + +void SwigDirector_IMessageHandler::onMessage(bcos::Error::Ptr e,ppc::protocol::Message::Ptr msg,ppc::front::SendResponseHandler sendResponseHandler) { + JNIEnvWrapper swigjnienv(this) ; + JNIEnv * jenv = swigjnienv.getJNIEnv() ; + jobject swigjobj = (jobject) NULL ; + jlong je ; + jlong jmsg ; + jlong jsendResponseHandler ; + + if (!swig_override[0]) { + SWIG_JavaThrowException(JNIEnvWrapper(this).getJNIEnv(), SWIG_JavaDirectorPureVirtual, "Attempted to invoke pure virtual method ppc::front::IMessageHandler::onMessage."); + return; + } + swigjobj = swig_get_self(jenv); + if (swigjobj && jenv->IsSameObject(swigjobj, NULL) == JNI_FALSE) { + je = 0; + if (e) { + *((std::shared_ptr< bcos::Error > **)&je) = new std::shared_ptr< bcos::Error >(e); + } + jmsg = 0; + if (msg) { + *((std::shared_ptr< ppc::protocol::Message > **)&jmsg) = new std::shared_ptr< ppc::protocol::Message >(msg); + } + jsendResponseHandler = 0; + *((ppc::front::SendResponseHandler **)&jsendResponseHandler) = new ppc::front::SendResponseHandler(SWIG_STD_MOVE(sendResponseHandler)); + jenv->CallStaticVoidMethod(Swig::jclass_wedpr_java_transportJNI, Swig::director_method_ids[2], swigjobj, je, jmsg, jsendResponseHandler); + jthrowable swigerror = jenv->ExceptionOccurred(); + if (swigerror) { + Swig::DirectorException::raise(jenv, swigerror); + } + + } else { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null upcall object in ppc::front::IMessageHandler::onMessage "); + } + if (swigjobj) jenv->DeleteLocalRef(swigjobj); +} + +void SwigDirector_IMessageHandler::swig_connect_director(JNIEnv *jenv, jobject jself, jclass jcls, bool swig_mem_own, bool weak_global) { + static jclass baseclass = swig_new_global_ref(jenv, "com/webank/wedpr/sdk/jni/generated/IMessageHandler"); + if (!baseclass) return; + static SwigDirectorMethod methods[] = { + SwigDirectorMethod(jenv, baseclass, "onMessage", "(Lcom/webank/wedpr/sdk/jni/generated/Error;Lcom/webank/wedpr/sdk/jni/generated/Message;Lcom/webank/wedpr/sdk/jni/generated/SendResponseHandler;)V") + }; + + if (swig_set_self(jenv, jself, swig_mem_own, weak_global)) { + bool derived = (jenv->IsSameObject(baseclass, jcls) ? false : true); + for (int i = 0; i < 1; ++i) { + swig_override[i] = false; + if (derived) { + jmethodID methid = jenv->GetMethodID(jcls, methods[i].name, methods[i].desc); + swig_override[i] = methods[i].methid && (methid != methods[i].methid); + jenv->ExceptionClear(); + } + } + } +} + + +SwigDirector_GetPeersInfoHandler::SwigDirector_GetPeersInfoHandler(JNIEnv *jenv) : ppc::front::GetPeersInfoHandler(), Swig::Director(jenv) { +} + +SwigDirector_GetPeersInfoHandler::~SwigDirector_GetPeersInfoHandler() { + swig_disconnect_director_self("swigDirectorDisconnect"); +} + + +void SwigDirector_GetPeersInfoHandler::onPeersInfo(bcos::Error::Ptr e,std::string const &peersInfo) { + JNIEnvWrapper swigjnienv(this) ; + JNIEnv * jenv = swigjnienv.getJNIEnv() ; + jobject swigjobj = (jobject) NULL ; + jlong je ; + jstring jpeersInfo = 0 ; + + if (!swig_override[0]) { + SWIG_JavaThrowException(JNIEnvWrapper(this).getJNIEnv(), SWIG_JavaDirectorPureVirtual, "Attempted to invoke pure virtual method ppc::front::GetPeersInfoHandler::onPeersInfo."); + return; + } + swigjobj = swig_get_self(jenv); + if (swigjobj && jenv->IsSameObject(swigjobj, NULL) == JNI_FALSE) { + je = 0; + if (e) { + *((std::shared_ptr< bcos::Error > **)&je) = new std::shared_ptr< bcos::Error >(e); + } + jpeersInfo = jenv->NewStringUTF((&peersInfo)->c_str()); + Swig::LocalRefGuard peersInfo_refguard(jenv, jpeersInfo); + jenv->CallStaticVoidMethod(Swig::jclass_wedpr_java_transportJNI, Swig::director_method_ids[3], swigjobj, je, jpeersInfo); + jthrowable swigerror = jenv->ExceptionOccurred(); + if (swigerror) { + Swig::DirectorException::raise(jenv, swigerror); + } + + } else { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null upcall object in ppc::front::GetPeersInfoHandler::onPeersInfo "); + } + if (swigjobj) jenv->DeleteLocalRef(swigjobj); +} + +void SwigDirector_GetPeersInfoHandler::swig_connect_director(JNIEnv *jenv, jobject jself, jclass jcls, bool swig_mem_own, bool weak_global) { + static jclass baseclass = swig_new_global_ref(jenv, "com/webank/wedpr/sdk/jni/generated/GetPeersInfoHandler"); + if (!baseclass) return; + static SwigDirectorMethod methods[] = { + SwigDirectorMethod(jenv, baseclass, "onPeersInfo", "(Lcom/webank/wedpr/sdk/jni/generated/Error;Ljava/lang/String;)V") + }; + + if (swig_set_self(jenv, jself, swig_mem_own, weak_global)) { + bool derived = (jenv->IsSameObject(baseclass, jcls) ? false : true); + for (int i = 0; i < 1; ++i) { + swig_override[i] = false; + if (derived) { + jmethodID methid = jenv->GetMethodID(jcls, methods[i].name, methods[i].desc); + swig_override[i] = methods[i].methid && (methid != methods[i].methid); + jenv->ExceptionClear(); + } + } + } +} + + + +#ifdef __cplusplus +extern "C" { +#endif + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_new_1SharedBcosError(JNIEnv *jenv, jclass jcls) { + jlong jresult = 0 ; + std::shared_ptr< bcos::Error > *result = 0 ; + + (void)jenv; + (void)jcls; + { + try { + result = (std::shared_ptr< bcos::Error > *)new std::shared_ptr< bcos::Error >(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + *(std::shared_ptr< bcos::Error > **)&jresult = (result && *result) ? new std::shared_ptr< bcos::Error >(*result) : 0; + if (1) delete result; + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_delete_1SharedBcosError(JNIEnv *jenv, jclass jcls, jlong jarg1) { + std::shared_ptr< bcos::Error > *arg1 = (std::shared_ptr< bcos::Error > *) 0 ; + std::shared_ptr< bcos::Error > tempnull1 ; + + (void)jenv; + (void)jcls; + arg1 = jarg1 ? *(std::shared_ptr< bcos::Error > **)&jarg1 : &tempnull1; + { + try { + delete arg1; + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_new_1SharedFrontConfig(JNIEnv *jenv, jclass jcls) { + jlong jresult = 0 ; + std::shared_ptr< ppc::front::FrontConfig > *result = 0 ; + + (void)jenv; + (void)jcls; + { + try { + result = (std::shared_ptr< ppc::front::FrontConfig > *)new std::shared_ptr< ppc::front::FrontConfig >(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + *(std::shared_ptr< ppc::front::FrontConfig > **)&jresult = (result && *result) ? new std::shared_ptr< ppc::front::FrontConfig >(*result) : 0; + if (1) delete result; + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_delete_1SharedFrontConfig(JNIEnv *jenv, jclass jcls, jlong jarg1) { + std::shared_ptr< ppc::front::FrontConfig > *arg1 = (std::shared_ptr< ppc::front::FrontConfig > *) 0 ; + std::shared_ptr< ppc::front::FrontConfig > tempnull1 ; + + (void)jenv; + (void)jcls; + arg1 = jarg1 ? *(std::shared_ptr< ppc::front::FrontConfig > **)&jarg1 : &tempnull1; + { + try { + delete arg1; + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_new_1SharedGrpcConfig(JNIEnv *jenv, jclass jcls) { + jlong jresult = 0 ; + std::shared_ptr< ppc::protocol::GrpcConfig > *result = 0 ; + + (void)jenv; + (void)jcls; + { + try { + result = (std::shared_ptr< ppc::protocol::GrpcConfig > *)new std::shared_ptr< ppc::protocol::GrpcConfig >(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + *(std::shared_ptr< ppc::protocol::GrpcConfig > **)&jresult = (result && *result) ? new std::shared_ptr< ppc::protocol::GrpcConfig >(*result) : 0; + if (1) delete result; + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_delete_1SharedGrpcConfig(JNIEnv *jenv, jclass jcls, jlong jarg1) { + std::shared_ptr< ppc::protocol::GrpcConfig > *arg1 = (std::shared_ptr< ppc::protocol::GrpcConfig > *) 0 ; + std::shared_ptr< ppc::protocol::GrpcConfig > tempnull1 ; + + (void)jenv; + (void)jcls; + arg1 = jarg1 ? *(std::shared_ptr< ppc::protocol::GrpcConfig > **)&jarg1 : &tempnull1; + { + try { + delete arg1; + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_new_1SharedFront(JNIEnv *jenv, jclass jcls) { + jlong jresult = 0 ; + std::shared_ptr< ppc::front::IFront > *result = 0 ; + + (void)jenv; + (void)jcls; + { + try { + result = (std::shared_ptr< ppc::front::IFront > *)new std::shared_ptr< ppc::front::IFront >(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + *(std::shared_ptr< ppc::front::IFront > **)&jresult = (result && *result) ? new std::shared_ptr< ppc::front::IFront >(*result) : 0; + if (1) delete result; + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_delete_1SharedFront(JNIEnv *jenv, jclass jcls, jlong jarg1) { + std::shared_ptr< ppc::front::IFront > *arg1 = (std::shared_ptr< ppc::front::IFront > *) 0 ; + std::shared_ptr< ppc::front::IFront > tempnull1 ; + + (void)jenv; + (void)jcls; + arg1 = jarg1 ? *(std::shared_ptr< ppc::front::IFront > **)&jarg1 : &tempnull1; + { + try { + delete arg1; + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_new_1SharedNodeDiscovery(JNIEnv *jenv, jclass jcls) { + jlong jresult = 0 ; + std::shared_ptr< ppc::front::INodeDiscovery > *result = 0 ; + + (void)jenv; + (void)jcls; + { + try { + result = (std::shared_ptr< ppc::front::INodeDiscovery > *)new std::shared_ptr< ppc::front::INodeDiscovery >(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + *(std::shared_ptr< ppc::front::INodeDiscovery > **)&jresult = (result && *result) ? new std::shared_ptr< ppc::front::INodeDiscovery >(*result) : 0; + if (1) delete result; + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_delete_1SharedNodeDiscovery(JNIEnv *jenv, jclass jcls, jlong jarg1) { + std::shared_ptr< ppc::front::INodeDiscovery > *arg1 = (std::shared_ptr< ppc::front::INodeDiscovery > *) 0 ; + std::shared_ptr< ppc::front::INodeDiscovery > tempnull1 ; + + (void)jenv; + (void)jcls; + arg1 = jarg1 ? *(std::shared_ptr< ppc::front::INodeDiscovery > **)&jarg1 : &tempnull1; + { + try { + delete arg1; + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_new_1SharedFrontClient(JNIEnv *jenv, jclass jcls) { + jlong jresult = 0 ; + std::shared_ptr< ppc::front::IFrontClient > *result = 0 ; + + (void)jenv; + (void)jcls; + { + try { + result = (std::shared_ptr< ppc::front::IFrontClient > *)new std::shared_ptr< ppc::front::IFrontClient >(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + *(std::shared_ptr< ppc::front::IFrontClient > **)&jresult = (result && *result) ? new std::shared_ptr< ppc::front::IFrontClient >(*result) : 0; + if (1) delete result; + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_delete_1SharedFrontClient(JNIEnv *jenv, jclass jcls, jlong jarg1) { + std::shared_ptr< ppc::front::IFrontClient > *arg1 = (std::shared_ptr< ppc::front::IFrontClient > *) 0 ; + std::shared_ptr< ppc::front::IFrontClient > tempnull1 ; + + (void)jenv; + (void)jcls; + arg1 = jarg1 ? *(std::shared_ptr< ppc::front::IFrontClient > **)&jarg1 : &tempnull1; + { + try { + delete arg1; + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_new_1SharedErrorCallback(JNIEnv *jenv, jclass jcls) { + jlong jresult = 0 ; + std::shared_ptr< ppc::front::ErrorCallback > *result = 0 ; + + (void)jenv; + (void)jcls; + { + try { + result = (std::shared_ptr< ppc::front::ErrorCallback > *)new std::shared_ptr< ppc::front::ErrorCallback >(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + *(std::shared_ptr< ppc::front::ErrorCallback > **)&jresult = (result && *result) ? new std::shared_ptr< ppc::front::ErrorCallback >(*result) : 0; + if (1) delete result; + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_delete_1SharedErrorCallback(JNIEnv *jenv, jclass jcls, jlong jarg1) { + std::shared_ptr< ppc::front::ErrorCallback > *arg1 = (std::shared_ptr< ppc::front::ErrorCallback > *) 0 ; + std::shared_ptr< ppc::front::ErrorCallback > tempnull1 ; + + (void)jenv; + (void)jcls; + arg1 = jarg1 ? *(std::shared_ptr< ppc::front::ErrorCallback > **)&jarg1 : &tempnull1; + { + try { + delete arg1; + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_new_1SharedMessageDispatcherHandler(JNIEnv *jenv, jclass jcls) { + jlong jresult = 0 ; + std::shared_ptr< ppc::front::MessageDispatcherHandler > *result = 0 ; + + (void)jenv; + (void)jcls; + { + try { + result = (std::shared_ptr< ppc::front::MessageDispatcherHandler > *)new std::shared_ptr< ppc::front::MessageDispatcherHandler >(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + *(std::shared_ptr< ppc::front::MessageDispatcherHandler > **)&jresult = (result && *result) ? new std::shared_ptr< ppc::front::MessageDispatcherHandler >(*result) : 0; + if (1) delete result; + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_delete_1SharedMessageDispatcherHandler(JNIEnv *jenv, jclass jcls, jlong jarg1) { + std::shared_ptr< ppc::front::MessageDispatcherHandler > *arg1 = (std::shared_ptr< ppc::front::MessageDispatcherHandler > *) 0 ; + std::shared_ptr< ppc::front::MessageDispatcherHandler > tempnull1 ; + + (void)jenv; + (void)jcls; + arg1 = jarg1 ? *(std::shared_ptr< ppc::front::MessageDispatcherHandler > **)&jarg1 : &tempnull1; + { + try { + delete arg1; + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_new_1SharedIMessageHandler(JNIEnv *jenv, jclass jcls) { + jlong jresult = 0 ; + std::shared_ptr< ppc::front::IMessageHandler > *result = 0 ; + + (void)jenv; + (void)jcls; + { + try { + result = (std::shared_ptr< ppc::front::IMessageHandler > *)new std::shared_ptr< ppc::front::IMessageHandler >(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + *(std::shared_ptr< ppc::front::IMessageHandler > **)&jresult = (result && *result) ? new std::shared_ptr< ppc::front::IMessageHandler >(*result) : 0; + if (1) delete result; + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_delete_1SharedIMessageHandler(JNIEnv *jenv, jclass jcls, jlong jarg1) { + std::shared_ptr< ppc::front::IMessageHandler > *arg1 = (std::shared_ptr< ppc::front::IMessageHandler > *) 0 ; + std::shared_ptr< ppc::front::IMessageHandler > tempnull1 ; + + (void)jenv; + (void)jcls; + arg1 = jarg1 ? *(std::shared_ptr< ppc::front::IMessageHandler > **)&jarg1 : &tempnull1; + { + try { + delete arg1; + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_new_1SharedGetPeersInfoHandler(JNIEnv *jenv, jclass jcls) { + jlong jresult = 0 ; + std::shared_ptr< ppc::front::GetPeersInfoHandler > *result = 0 ; + + (void)jenv; + (void)jcls; + { + try { + result = (std::shared_ptr< ppc::front::GetPeersInfoHandler > *)new std::shared_ptr< ppc::front::GetPeersInfoHandler >(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + *(std::shared_ptr< ppc::front::GetPeersInfoHandler > **)&jresult = (result && *result) ? new std::shared_ptr< ppc::front::GetPeersInfoHandler >(*result) : 0; + if (1) delete result; + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_delete_1SharedGetPeersInfoHandler(JNIEnv *jenv, jclass jcls, jlong jarg1) { + std::shared_ptr< ppc::front::GetPeersInfoHandler > *arg1 = (std::shared_ptr< ppc::front::GetPeersInfoHandler > *) 0 ; + std::shared_ptr< ppc::front::GetPeersInfoHandler > tempnull1 ; + + (void)jenv; + (void)jcls; + arg1 = jarg1 ? *(std::shared_ptr< ppc::front::GetPeersInfoHandler > **)&jarg1 : &tempnull1; + { + try { + delete arg1; + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_new_1SharedGateway(JNIEnv *jenv, jclass jcls) { + jlong jresult = 0 ; + std::shared_ptr< ppc::gateway::IGateway > *result = 0 ; + + (void)jenv; + (void)jcls; + { + try { + result = (std::shared_ptr< ppc::gateway::IGateway > *)new std::shared_ptr< ppc::gateway::IGateway >(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + *(std::shared_ptr< ppc::gateway::IGateway > **)&jresult = (result && *result) ? new std::shared_ptr< ppc::gateway::IGateway >(*result) : 0; + if (1) delete result; + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_delete_1SharedGateway(JNIEnv *jenv, jclass jcls, jlong jarg1) { + std::shared_ptr< ppc::gateway::IGateway > *arg1 = (std::shared_ptr< ppc::gateway::IGateway > *) 0 ; + std::shared_ptr< ppc::gateway::IGateway > tempnull1 ; + + (void)jenv; + (void)jcls; + arg1 = jarg1 ? *(std::shared_ptr< ppc::gateway::IGateway > **)&jarg1 : &tempnull1; + { + try { + delete arg1; + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_new_1SharedMessage(JNIEnv *jenv, jclass jcls) { + jlong jresult = 0 ; + std::shared_ptr< ppc::protocol::Message > *result = 0 ; + + (void)jenv; + (void)jcls; + { + try { + result = (std::shared_ptr< ppc::protocol::Message > *)new std::shared_ptr< ppc::protocol::Message >(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + *(std::shared_ptr< ppc::protocol::Message > **)&jresult = (result && *result) ? new std::shared_ptr< ppc::protocol::Message >(*result) : 0; + if (1) delete result; + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_delete_1SharedMessage(JNIEnv *jenv, jclass jcls, jlong jarg1) { + std::shared_ptr< ppc::protocol::Message > *arg1 = (std::shared_ptr< ppc::protocol::Message > *) 0 ; + std::shared_ptr< ppc::protocol::Message > tempnull1 ; + + (void)jenv; + (void)jcls; + arg1 = jarg1 ? *(std::shared_ptr< ppc::protocol::Message > **)&jarg1 : &tempnull1; + { + try { + delete arg1; + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_new_1SharedMessageHeader(JNIEnv *jenv, jclass jcls) { + jlong jresult = 0 ; + std::shared_ptr< ppc::protocol::MessageHeader > *result = 0 ; + + (void)jenv; + (void)jcls; + { + try { + result = (std::shared_ptr< ppc::protocol::MessageHeader > *)new std::shared_ptr< ppc::protocol::MessageHeader >(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + *(std::shared_ptr< ppc::protocol::MessageHeader > **)&jresult = (result && *result) ? new std::shared_ptr< ppc::protocol::MessageHeader >(*result) : 0; + if (1) delete result; + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_delete_1SharedMessageHeader(JNIEnv *jenv, jclass jcls, jlong jarg1) { + std::shared_ptr< ppc::protocol::MessageHeader > *arg1 = (std::shared_ptr< ppc::protocol::MessageHeader > *) 0 ; + std::shared_ptr< ppc::protocol::MessageHeader > tempnull1 ; + + (void)jenv; + (void)jcls; + arg1 = jarg1 ? *(std::shared_ptr< ppc::protocol::MessageHeader > **)&jarg1 : &tempnull1; + { + try { + delete arg1; + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_new_1SharedMessagePayload(JNIEnv *jenv, jclass jcls) { + jlong jresult = 0 ; + std::shared_ptr< ppc::protocol::MessagePayload > *result = 0 ; + + (void)jenv; + (void)jcls; + { + try { + result = (std::shared_ptr< ppc::protocol::MessagePayload > *)new std::shared_ptr< ppc::protocol::MessagePayload >(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + *(std::shared_ptr< ppc::protocol::MessagePayload > **)&jresult = (result && *result) ? new std::shared_ptr< ppc::protocol::MessagePayload >(*result) : 0; + if (1) delete result; + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_delete_1SharedMessagePayload(JNIEnv *jenv, jclass jcls, jlong jarg1) { + std::shared_ptr< ppc::protocol::MessagePayload > *arg1 = (std::shared_ptr< ppc::protocol::MessagePayload > *) 0 ; + std::shared_ptr< ppc::protocol::MessagePayload > tempnull1 ; + + (void)jenv; + (void)jcls; + arg1 = jarg1 ? *(std::shared_ptr< ppc::protocol::MessagePayload > **)&jarg1 : &tempnull1; + { + try { + delete arg1; + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_new_1SharedRouteInfo(JNIEnv *jenv, jclass jcls) { + jlong jresult = 0 ; + std::shared_ptr< ppc::protocol::MessageOptionalHeader > *result = 0 ; + + (void)jenv; + (void)jcls; + { + try { + result = (std::shared_ptr< ppc::protocol::MessageOptionalHeader > *)new std::shared_ptr< ppc::protocol::MessageOptionalHeader >(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + *(std::shared_ptr< ppc::protocol::MessageOptionalHeader > **)&jresult = (result && *result) ? new std::shared_ptr< ppc::protocol::MessageOptionalHeader >(*result) : 0; + if (1) delete result; + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_delete_1SharedRouteInfo(JNIEnv *jenv, jclass jcls, jlong jarg1) { + std::shared_ptr< ppc::protocol::MessageOptionalHeader > *arg1 = (std::shared_ptr< ppc::protocol::MessageOptionalHeader > *) 0 ; + std::shared_ptr< ppc::protocol::MessageOptionalHeader > tempnull1 ; + + (void)jenv; + (void)jcls; + arg1 = jarg1 ? *(std::shared_ptr< ppc::protocol::MessageOptionalHeader > **)&jarg1 : &tempnull1; + { + try { + delete arg1; + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_new_1SharedMessageBuilder(JNIEnv *jenv, jclass jcls) { + jlong jresult = 0 ; + std::shared_ptr< ppc::protocol::MessageBuilder > *result = 0 ; + + (void)jenv; + (void)jcls; + { + try { + result = (std::shared_ptr< ppc::protocol::MessageBuilder > *)new std::shared_ptr< ppc::protocol::MessageBuilder >(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + *(std::shared_ptr< ppc::protocol::MessageBuilder > **)&jresult = (result && *result) ? new std::shared_ptr< ppc::protocol::MessageBuilder >(*result) : 0; + if (1) delete result; + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_delete_1SharedMessageBuilder(JNIEnv *jenv, jclass jcls, jlong jarg1) { + std::shared_ptr< ppc::protocol::MessageBuilder > *arg1 = (std::shared_ptr< ppc::protocol::MessageBuilder > *) 0 ; + std::shared_ptr< ppc::protocol::MessageBuilder > tempnull1 ; + + (void)jenv; + (void)jcls; + arg1 = jarg1 ? *(std::shared_ptr< ppc::protocol::MessageBuilder > **)&jarg1 : &tempnull1; + { + try { + delete arg1; + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_new_1SharedMessageHeaderBuilder(JNIEnv *jenv, jclass jcls) { + jlong jresult = 0 ; + std::shared_ptr< ppc::protocol::MessageHeaderBuilder > *result = 0 ; + + (void)jenv; + (void)jcls; + { + try { + result = (std::shared_ptr< ppc::protocol::MessageHeaderBuilder > *)new std::shared_ptr< ppc::protocol::MessageHeaderBuilder >(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + *(std::shared_ptr< ppc::protocol::MessageHeaderBuilder > **)&jresult = (result && *result) ? new std::shared_ptr< ppc::protocol::MessageHeaderBuilder >(*result) : 0; + if (1) delete result; + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_delete_1SharedMessageHeaderBuilder(JNIEnv *jenv, jclass jcls, jlong jarg1) { + std::shared_ptr< ppc::protocol::MessageHeaderBuilder > *arg1 = (std::shared_ptr< ppc::protocol::MessageHeaderBuilder > *) 0 ; + std::shared_ptr< ppc::protocol::MessageHeaderBuilder > tempnull1 ; + + (void)jenv; + (void)jcls; + arg1 = jarg1 ? *(std::shared_ptr< ppc::protocol::MessageHeaderBuilder > **)&jarg1 : &tempnull1; + { + try { + delete arg1; + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_new_1SharedMessagePayloadBuilder(JNIEnv *jenv, jclass jcls) { + jlong jresult = 0 ; + std::shared_ptr< ppc::protocol::MessagePayloadBuilder > *result = 0 ; + + (void)jenv; + (void)jcls; + { + try { + result = (std::shared_ptr< ppc::protocol::MessagePayloadBuilder > *)new std::shared_ptr< ppc::protocol::MessagePayloadBuilder >(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + *(std::shared_ptr< ppc::protocol::MessagePayloadBuilder > **)&jresult = (result && *result) ? new std::shared_ptr< ppc::protocol::MessagePayloadBuilder >(*result) : 0; + if (1) delete result; + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_delete_1SharedMessagePayloadBuilder(JNIEnv *jenv, jclass jcls, jlong jarg1) { + std::shared_ptr< ppc::protocol::MessagePayloadBuilder > *arg1 = (std::shared_ptr< ppc::protocol::MessagePayloadBuilder > *) 0 ; + std::shared_ptr< ppc::protocol::MessagePayloadBuilder > tempnull1 ; + + (void)jenv; + (void)jcls; + arg1 = jarg1 ? *(std::shared_ptr< ppc::protocol::MessagePayloadBuilder > **)&jarg1 : &tempnull1; + { + try { + delete arg1; + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_new_1SharedRouteInfoBuilder(JNIEnv *jenv, jclass jcls) { + jlong jresult = 0 ; + std::shared_ptr< ppc::protocol::MessageOptionalHeaderBuilder > *result = 0 ; + + (void)jenv; + (void)jcls; + { + try { + result = (std::shared_ptr< ppc::protocol::MessageOptionalHeaderBuilder > *)new std::shared_ptr< ppc::protocol::MessageOptionalHeaderBuilder >(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + *(std::shared_ptr< ppc::protocol::MessageOptionalHeaderBuilder > **)&jresult = (result && *result) ? new std::shared_ptr< ppc::protocol::MessageOptionalHeaderBuilder >(*result) : 0; + if (1) delete result; + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_delete_1SharedRouteInfoBuilder(JNIEnv *jenv, jclass jcls, jlong jarg1) { + std::shared_ptr< ppc::protocol::MessageOptionalHeaderBuilder > *arg1 = (std::shared_ptr< ppc::protocol::MessageOptionalHeaderBuilder > *) 0 ; + std::shared_ptr< ppc::protocol::MessageOptionalHeaderBuilder > tempnull1 ; + + (void)jenv; + (void)jcls; + arg1 = jarg1 ? *(std::shared_ptr< ppc::protocol::MessageOptionalHeaderBuilder > **)&jarg1 : &tempnull1; + { + try { + delete arg1; + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_new_1SharedNodeInfo(JNIEnv *jenv, jclass jcls) { + jlong jresult = 0 ; + std::shared_ptr< ppc::protocol::INodeInfo > *result = 0 ; + + (void)jenv; + (void)jcls; + { + try { + result = (std::shared_ptr< ppc::protocol::INodeInfo > *)new std::shared_ptr< ppc::protocol::INodeInfo >(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + *(std::shared_ptr< ppc::protocol::INodeInfo > **)&jresult = (result && *result) ? new std::shared_ptr< ppc::protocol::INodeInfo >(*result) : 0; + if (1) delete result; + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_delete_1SharedNodeInfo(JNIEnv *jenv, jclass jcls, jlong jarg1) { + std::shared_ptr< ppc::protocol::INodeInfo > *arg1 = (std::shared_ptr< ppc::protocol::INodeInfo > *) 0 ; + std::shared_ptr< ppc::protocol::INodeInfo > tempnull1 ; + + (void)jenv; + (void)jcls; + arg1 = jarg1 ? *(std::shared_ptr< ppc::protocol::INodeInfo > **)&jarg1 : &tempnull1; + { + try { + delete arg1; + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_new_1ubytes_1_1SWIG_10(JNIEnv *jenv, jclass jcls) { + jlong jresult = 0 ; + std::vector< uint8_t > *result = 0 ; + + (void)jenv; + (void)jcls; + result = (std::vector< uint8_t > *)new std::vector< uint8_t >(); + *(std::vector< uint8_t > **)&jresult = result; + return jresult; +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_new_1ubytes_1_1SWIG_11(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jlong jresult = 0 ; + std::vector< uint8_t > *arg1 = 0 ; + std::vector< uint8_t > *result = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(std::vector< uint8_t > **)&jarg1; + if (!arg1) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "std::vector< uint8_t > const & is null"); + return 0; + } + result = (std::vector< uint8_t > *)new std::vector< uint8_t >((std::vector< uint8_t > const &)*arg1); + *(std::vector< uint8_t > **)&jresult = result; + return jresult; +} + + +SWIGEXPORT jboolean JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_ubytes_1isEmpty(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jboolean jresult = 0 ; + std::vector< uint8_t > *arg1 = (std::vector< uint8_t > *) 0 ; + bool result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(std::vector< uint8_t > **)&jarg1; + result = (bool)((std::vector< uint8_t > const *)arg1)->empty(); + jresult = (jboolean)result; + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_ubytes_1clear(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + std::vector< uint8_t > *arg1 = (std::vector< uint8_t > *) 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(std::vector< uint8_t > **)&jarg1; + (arg1)->clear(); +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_new_1ubytes_1_1SWIG_12(JNIEnv *jenv, jclass jcls, jint jarg1, jshort jarg2) { + jlong jresult = 0 ; + jint arg1 ; + unsigned char *arg2 = 0 ; + unsigned char temp2 ; + std::vector< uint8_t > *result = 0 ; + + (void)jenv; + (void)jcls; + arg1 = jarg1; + temp2 = (unsigned char)jarg2; + arg2 = &temp2; + try { + result = (std::vector< uint8_t > *)new_std_vector_Sl_uint8_t_Sg___SWIG_2(SWIG_STD_MOVE(arg1),(unsigned char const &)*arg2); + } catch(std::out_of_range &_e) { + SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, (&_e)->what()); + return 0; + } + *(std::vector< uint8_t > **)&jresult = result; + return jresult; +} + + +SWIGEXPORT jint JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_ubytes_1doCapacity(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jint jresult = 0 ; + std::vector< uint8_t > *arg1 = (std::vector< uint8_t > *) 0 ; + jint result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(std::vector< uint8_t > **)&jarg1; + try { + result = std_vector_Sl_uint8_t_Sg__doCapacity(arg1); + } catch(std::out_of_range &_e) { + SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, (&_e)->what()); + return 0; + } + jresult = result; + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_ubytes_1doReserve(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jint jarg2) { + std::vector< uint8_t > *arg1 = (std::vector< uint8_t > *) 0 ; + jint arg2 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(std::vector< uint8_t > **)&jarg1; + arg2 = jarg2; + try { + std_vector_Sl_uint8_t_Sg__doReserve(arg1,SWIG_STD_MOVE(arg2)); + } catch(std::length_error &_e) { + SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, (&_e)->what()); + return ; + } catch(std::out_of_range &_e) { + SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, (&_e)->what()); + return ; + } +} + + +SWIGEXPORT jint JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_ubytes_1doSize(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jint jresult = 0 ; + std::vector< uint8_t > *arg1 = (std::vector< uint8_t > *) 0 ; + jint result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(std::vector< uint8_t > **)&jarg1; + try { + result = std_vector_Sl_uint8_t_Sg__doSize((std::vector< unsigned char > const *)arg1); + } catch(std::out_of_range &_e) { + SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, (&_e)->what()); + return 0; + } + jresult = result; + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_ubytes_1doAdd_1_1SWIG_10(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jshort jarg2) { + std::vector< uint8_t > *arg1 = (std::vector< uint8_t > *) 0 ; + std::vector< unsigned char >::value_type *arg2 = 0 ; + std::vector< unsigned char >::value_type temp2 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(std::vector< uint8_t > **)&jarg1; + temp2 = (std::vector< unsigned char >::value_type)jarg2; + arg2 = &temp2; + std_vector_Sl_uint8_t_Sg__doAdd__SWIG_0(arg1,(unsigned char const &)*arg2); +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_ubytes_1doAdd_1_1SWIG_11(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jint jarg2, jshort jarg3) { + std::vector< uint8_t > *arg1 = (std::vector< uint8_t > *) 0 ; + jint arg2 ; + std::vector< unsigned char >::value_type *arg3 = 0 ; + std::vector< unsigned char >::value_type temp3 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(std::vector< uint8_t > **)&jarg1; + arg2 = jarg2; + temp3 = (std::vector< unsigned char >::value_type)jarg3; + arg3 = &temp3; + try { + std_vector_Sl_uint8_t_Sg__doAdd__SWIG_1(arg1,SWIG_STD_MOVE(arg2),(unsigned char const &)*arg3); + } catch(std::out_of_range &_e) { + SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, (&_e)->what()); + return ; + } +} + + +SWIGEXPORT jshort JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_ubytes_1doRemove(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jint jarg2) { + jshort jresult = 0 ; + std::vector< uint8_t > *arg1 = (std::vector< uint8_t > *) 0 ; + jint arg2 ; + std::vector< unsigned char >::value_type result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(std::vector< uint8_t > **)&jarg1; + arg2 = jarg2; + try { + result = (std::vector< unsigned char >::value_type)std_vector_Sl_uint8_t_Sg__doRemove(arg1,SWIG_STD_MOVE(arg2)); + } catch(std::out_of_range &_e) { + SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, (&_e)->what()); + return 0; + } + jresult = (jshort)result; + return jresult; +} + + +SWIGEXPORT jshort JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_ubytes_1doGet(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jint jarg2) { + jshort jresult = 0 ; + std::vector< uint8_t > *arg1 = (std::vector< uint8_t > *) 0 ; + jint arg2 ; + std::vector< unsigned char >::value_type *result = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(std::vector< uint8_t > **)&jarg1; + arg2 = jarg2; + try { + result = (std::vector< unsigned char >::value_type *) &std_vector_Sl_uint8_t_Sg__doGet(arg1,SWIG_STD_MOVE(arg2)); + } catch(std::out_of_range &_e) { + SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, (&_e)->what()); + return 0; + } + jresult = (jshort)*result; + return jresult; +} + + +SWIGEXPORT jshort JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_ubytes_1doSet(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jint jarg2, jshort jarg3) { + jshort jresult = 0 ; + std::vector< uint8_t > *arg1 = (std::vector< uint8_t > *) 0 ; + jint arg2 ; + std::vector< unsigned char >::value_type *arg3 = 0 ; + std::vector< unsigned char >::value_type temp3 ; + std::vector< unsigned char >::value_type result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(std::vector< uint8_t > **)&jarg1; + arg2 = jarg2; + temp3 = (std::vector< unsigned char >::value_type)jarg3; + arg3 = &temp3; + try { + result = (std::vector< unsigned char >::value_type)std_vector_Sl_uint8_t_Sg__doSet(arg1,SWIG_STD_MOVE(arg2),(unsigned char const &)*arg3); + } catch(std::out_of_range &_e) { + SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, (&_e)->what()); + return 0; + } + jresult = (jshort)result; + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_ubytes_1doRemoveRange(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jint jarg2, jint jarg3) { + std::vector< uint8_t > *arg1 = (std::vector< uint8_t > *) 0 ; + jint arg2 ; + jint arg3 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(std::vector< uint8_t > **)&jarg1; + arg2 = jarg2; + arg3 = jarg3; + try { + std_vector_Sl_uint8_t_Sg__doRemoveRange(arg1,SWIG_STD_MOVE(arg2),SWIG_STD_MOVE(arg3)); + } catch(std::out_of_range &_e) { + SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, (&_e)->what()); + return ; + } +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_delete_1ubytes(JNIEnv *jenv, jclass jcls, jlong jarg1) { + std::vector< uint8_t > *arg1 = (std::vector< uint8_t > *) 0 ; + + (void)jenv; + (void)jcls; + arg1 = *(std::vector< uint8_t > **)&jarg1; + { + try { + delete arg1; + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_new_1ibytes_1_1SWIG_10(JNIEnv *jenv, jclass jcls) { + jlong jresult = 0 ; + std::vector< int8_t > *result = 0 ; + + (void)jenv; + (void)jcls; + result = (std::vector< int8_t > *)new std::vector< int8_t >(); + *(std::vector< int8_t > **)&jresult = result; + return jresult; +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_new_1ibytes_1_1SWIG_11(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jlong jresult = 0 ; + std::vector< int8_t > *arg1 = 0 ; + std::vector< int8_t > *result = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(std::vector< int8_t > **)&jarg1; + if (!arg1) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "std::vector< int8_t > const & is null"); + return 0; + } + result = (std::vector< int8_t > *)new std::vector< int8_t >((std::vector< int8_t > const &)*arg1); + *(std::vector< int8_t > **)&jresult = result; + return jresult; +} + + +SWIGEXPORT jboolean JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_ibytes_1isEmpty(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jboolean jresult = 0 ; + std::vector< int8_t > *arg1 = (std::vector< int8_t > *) 0 ; + bool result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(std::vector< int8_t > **)&jarg1; + result = (bool)((std::vector< int8_t > const *)arg1)->empty(); + jresult = (jboolean)result; + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_ibytes_1clear(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + std::vector< int8_t > *arg1 = (std::vector< int8_t > *) 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(std::vector< int8_t > **)&jarg1; + (arg1)->clear(); +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_new_1ibytes_1_1SWIG_12(JNIEnv *jenv, jclass jcls, jint jarg1, jbyte jarg2) { + jlong jresult = 0 ; + jint arg1 ; + signed char *arg2 = 0 ; + signed char temp2 ; + std::vector< int8_t > *result = 0 ; + + (void)jenv; + (void)jcls; + arg1 = jarg1; + temp2 = (signed char)jarg2; + arg2 = &temp2; + try { + result = (std::vector< int8_t > *)new_std_vector_Sl_int8_t_Sg___SWIG_2(SWIG_STD_MOVE(arg1),(signed char const &)*arg2); + } catch(std::out_of_range &_e) { + SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, (&_e)->what()); + return 0; + } + *(std::vector< int8_t > **)&jresult = result; + return jresult; +} + + +SWIGEXPORT jint JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_ibytes_1doCapacity(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jint jresult = 0 ; + std::vector< int8_t > *arg1 = (std::vector< int8_t > *) 0 ; + jint result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(std::vector< int8_t > **)&jarg1; + try { + result = std_vector_Sl_int8_t_Sg__doCapacity(arg1); + } catch(std::out_of_range &_e) { + SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, (&_e)->what()); + return 0; + } + jresult = result; + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_ibytes_1doReserve(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jint jarg2) { + std::vector< int8_t > *arg1 = (std::vector< int8_t > *) 0 ; + jint arg2 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(std::vector< int8_t > **)&jarg1; + arg2 = jarg2; + try { + std_vector_Sl_int8_t_Sg__doReserve(arg1,SWIG_STD_MOVE(arg2)); + } catch(std::length_error &_e) { + SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, (&_e)->what()); + return ; + } catch(std::out_of_range &_e) { + SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, (&_e)->what()); + return ; + } +} + + +SWIGEXPORT jint JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_ibytes_1doSize(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jint jresult = 0 ; + std::vector< int8_t > *arg1 = (std::vector< int8_t > *) 0 ; + jint result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(std::vector< int8_t > **)&jarg1; + try { + result = std_vector_Sl_int8_t_Sg__doSize((std::vector< signed char > const *)arg1); + } catch(std::out_of_range &_e) { + SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, (&_e)->what()); + return 0; + } + jresult = result; + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_ibytes_1doAdd_1_1SWIG_10(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jbyte jarg2) { + std::vector< int8_t > *arg1 = (std::vector< int8_t > *) 0 ; + std::vector< signed char >::value_type *arg2 = 0 ; + std::vector< signed char >::value_type temp2 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(std::vector< int8_t > **)&jarg1; + temp2 = (std::vector< signed char >::value_type)jarg2; + arg2 = &temp2; + std_vector_Sl_int8_t_Sg__doAdd__SWIG_0(arg1,(signed char const &)*arg2); +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_ibytes_1doAdd_1_1SWIG_11(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jint jarg2, jbyte jarg3) { + std::vector< int8_t > *arg1 = (std::vector< int8_t > *) 0 ; + jint arg2 ; + std::vector< signed char >::value_type *arg3 = 0 ; + std::vector< signed char >::value_type temp3 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(std::vector< int8_t > **)&jarg1; + arg2 = jarg2; + temp3 = (std::vector< signed char >::value_type)jarg3; + arg3 = &temp3; + try { + std_vector_Sl_int8_t_Sg__doAdd__SWIG_1(arg1,SWIG_STD_MOVE(arg2),(signed char const &)*arg3); + } catch(std::out_of_range &_e) { + SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, (&_e)->what()); + return ; + } +} + + +SWIGEXPORT jbyte JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_ibytes_1doRemove(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jint jarg2) { + jbyte jresult = 0 ; + std::vector< int8_t > *arg1 = (std::vector< int8_t > *) 0 ; + jint arg2 ; + std::vector< signed char >::value_type result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(std::vector< int8_t > **)&jarg1; + arg2 = jarg2; + try { + result = (std::vector< signed char >::value_type)std_vector_Sl_int8_t_Sg__doRemove(arg1,SWIG_STD_MOVE(arg2)); + } catch(std::out_of_range &_e) { + SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, (&_e)->what()); + return 0; + } + jresult = (jbyte)result; + return jresult; +} + + +SWIGEXPORT jbyte JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_ibytes_1doGet(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jint jarg2) { + jbyte jresult = 0 ; + std::vector< int8_t > *arg1 = (std::vector< int8_t > *) 0 ; + jint arg2 ; + std::vector< signed char >::value_type *result = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(std::vector< int8_t > **)&jarg1; + arg2 = jarg2; + try { + result = (std::vector< signed char >::value_type *) &std_vector_Sl_int8_t_Sg__doGet(arg1,SWIG_STD_MOVE(arg2)); + } catch(std::out_of_range &_e) { + SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, (&_e)->what()); + return 0; + } + jresult = (jbyte)*result; + return jresult; +} + + +SWIGEXPORT jbyte JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_ibytes_1doSet(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jint jarg2, jbyte jarg3) { + jbyte jresult = 0 ; + std::vector< int8_t > *arg1 = (std::vector< int8_t > *) 0 ; + jint arg2 ; + std::vector< signed char >::value_type *arg3 = 0 ; + std::vector< signed char >::value_type temp3 ; + std::vector< signed char >::value_type result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(std::vector< int8_t > **)&jarg1; + arg2 = jarg2; + temp3 = (std::vector< signed char >::value_type)jarg3; + arg3 = &temp3; + try { + result = (std::vector< signed char >::value_type)std_vector_Sl_int8_t_Sg__doSet(arg1,SWIG_STD_MOVE(arg2),(signed char const &)*arg3); + } catch(std::out_of_range &_e) { + SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, (&_e)->what()); + return 0; + } + jresult = (jbyte)result; + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_ibytes_1doRemoveRange(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jint jarg2, jint jarg3) { + std::vector< int8_t > *arg1 = (std::vector< int8_t > *) 0 ; + jint arg2 ; + jint arg3 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(std::vector< int8_t > **)&jarg1; + arg2 = jarg2; + arg3 = jarg3; + try { + std_vector_Sl_int8_t_Sg__doRemoveRange(arg1,SWIG_STD_MOVE(arg2),SWIG_STD_MOVE(arg3)); + } catch(std::out_of_range &_e) { + SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, (&_e)->what()); + return ; + } +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_delete_1ibytes(JNIEnv *jenv, jclass jcls, jlong jarg1) { + std::vector< int8_t > *arg1 = (std::vector< int8_t > *) 0 ; + + (void)jenv; + (void)jcls; + arg1 = *(std::vector< int8_t > **)&jarg1; + { + try { + delete arg1; + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_new_1StringVec_1_1SWIG_10(JNIEnv *jenv, jclass jcls) { + jlong jresult = 0 ; + std::vector< std::string > *result = 0 ; + + (void)jenv; + (void)jcls; + result = (std::vector< std::string > *)new std::vector< std::string >(); + *(std::vector< std::string > **)&jresult = result; + return jresult; +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_new_1StringVec_1_1SWIG_11(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jlong jresult = 0 ; + std::vector< std::string > *arg1 = 0 ; + std::vector< std::string > *result = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(std::vector< std::string > **)&jarg1; + if (!arg1) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "std::vector< std::string > const & is null"); + return 0; + } + result = (std::vector< std::string > *)new std::vector< std::string >((std::vector< std::string > const &)*arg1); + *(std::vector< std::string > **)&jresult = result; + return jresult; +} + + +SWIGEXPORT jboolean JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_StringVec_1isEmpty(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jboolean jresult = 0 ; + std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ; + bool result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(std::vector< std::string > **)&jarg1; + result = (bool)((std::vector< std::string > const *)arg1)->empty(); + jresult = (jboolean)result; + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_StringVec_1clear(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(std::vector< std::string > **)&jarg1; + (arg1)->clear(); +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_new_1StringVec_1_1SWIG_12(JNIEnv *jenv, jclass jcls, jint jarg1, jstring jarg2) { + jlong jresult = 0 ; + jint arg1 ; + std::string *arg2 = 0 ; + std::vector< std::string > *result = 0 ; + + (void)jenv; + (void)jcls; + arg1 = jarg1; + if(!jarg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null string"); + return 0; + } + const char *arg2_pstr = (const char *)jenv->GetStringUTFChars(jarg2, 0); + if (!arg2_pstr) return 0; + std::string arg2_str(arg2_pstr); + arg2 = &arg2_str; + jenv->ReleaseStringUTFChars(jarg2, arg2_pstr); + try { + result = (std::vector< std::string > *)new_std_vector_Sl_std_string_Sg___SWIG_2(SWIG_STD_MOVE(arg1),(std::string const &)*arg2); + } catch(std::out_of_range &_e) { + SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, (&_e)->what()); + return 0; + } + *(std::vector< std::string > **)&jresult = result; + return jresult; +} + + +SWIGEXPORT jint JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_StringVec_1doCapacity(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jint jresult = 0 ; + std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ; + jint result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(std::vector< std::string > **)&jarg1; + try { + result = std_vector_Sl_std_string_Sg__doCapacity(arg1); + } catch(std::out_of_range &_e) { + SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, (&_e)->what()); + return 0; + } + jresult = result; + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_StringVec_1doReserve(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jint jarg2) { + std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ; + jint arg2 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(std::vector< std::string > **)&jarg1; + arg2 = jarg2; + try { + std_vector_Sl_std_string_Sg__doReserve(arg1,SWIG_STD_MOVE(arg2)); + } catch(std::length_error &_e) { + SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, (&_e)->what()); + return ; + } catch(std::out_of_range &_e) { + SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, (&_e)->what()); + return ; + } +} + + +SWIGEXPORT jint JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_StringVec_1doSize(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jint jresult = 0 ; + std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ; + jint result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(std::vector< std::string > **)&jarg1; + try { + result = std_vector_Sl_std_string_Sg__doSize((std::vector< std::string > const *)arg1); + } catch(std::out_of_range &_e) { + SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, (&_e)->what()); + return 0; + } + jresult = result; + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_StringVec_1doAdd_1_1SWIG_10(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jstring jarg2) { + std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ; + std::vector< std::string >::value_type *arg2 = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(std::vector< std::string > **)&jarg1; + if(!jarg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null string"); + return ; + } + const char *arg2_pstr = (const char *)jenv->GetStringUTFChars(jarg2, 0); + if (!arg2_pstr) return ; + std::vector< std::string >::value_type arg2_str(arg2_pstr); + arg2 = &arg2_str; + jenv->ReleaseStringUTFChars(jarg2, arg2_pstr); + std_vector_Sl_std_string_Sg__doAdd__SWIG_0(arg1,(std::string const &)*arg2); +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_StringVec_1doAdd_1_1SWIG_11(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jint jarg2, jstring jarg3) { + std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ; + jint arg2 ; + std::vector< std::string >::value_type *arg3 = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(std::vector< std::string > **)&jarg1; + arg2 = jarg2; + if(!jarg3) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null string"); + return ; + } + const char *arg3_pstr = (const char *)jenv->GetStringUTFChars(jarg3, 0); + if (!arg3_pstr) return ; + std::vector< std::string >::value_type arg3_str(arg3_pstr); + arg3 = &arg3_str; + jenv->ReleaseStringUTFChars(jarg3, arg3_pstr); + try { + std_vector_Sl_std_string_Sg__doAdd__SWIG_1(arg1,SWIG_STD_MOVE(arg2),(std::string const &)*arg3); + } catch(std::out_of_range &_e) { + SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, (&_e)->what()); + return ; + } +} + + +SWIGEXPORT jstring JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_StringVec_1doRemove(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jint jarg2) { + jstring jresult = 0 ; + std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ; + jint arg2 ; + std::vector< std::string >::value_type result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(std::vector< std::string > **)&jarg1; + arg2 = jarg2; + try { + result = std_vector_Sl_std_string_Sg__doRemove(arg1,SWIG_STD_MOVE(arg2)); + } catch(std::out_of_range &_e) { + SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, (&_e)->what()); + return 0; + } + jresult = jenv->NewStringUTF((&result)->c_str()); + return jresult; +} + + +SWIGEXPORT jstring JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_StringVec_1doGet(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jint jarg2) { + jstring jresult = 0 ; + std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ; + jint arg2 ; + std::vector< std::string >::value_type *result = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(std::vector< std::string > **)&jarg1; + arg2 = jarg2; + try { + result = (std::vector< std::string >::value_type *) &std_vector_Sl_std_string_Sg__doGet(arg1,SWIG_STD_MOVE(arg2)); + } catch(std::out_of_range &_e) { + SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, (&_e)->what()); + return 0; + } + jresult = jenv->NewStringUTF(result->c_str()); + return jresult; +} + + +SWIGEXPORT jstring JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_StringVec_1doSet(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jint jarg2, jstring jarg3) { + jstring jresult = 0 ; + std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ; + jint arg2 ; + std::vector< std::string >::value_type *arg3 = 0 ; + std::vector< std::string >::value_type result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(std::vector< std::string > **)&jarg1; + arg2 = jarg2; + if(!jarg3) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null string"); + return 0; + } + const char *arg3_pstr = (const char *)jenv->GetStringUTFChars(jarg3, 0); + if (!arg3_pstr) return 0; + std::vector< std::string >::value_type arg3_str(arg3_pstr); + arg3 = &arg3_str; + jenv->ReleaseStringUTFChars(jarg3, arg3_pstr); + try { + result = std_vector_Sl_std_string_Sg__doSet(arg1,SWIG_STD_MOVE(arg2),(std::string const &)*arg3); + } catch(std::out_of_range &_e) { + SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, (&_e)->what()); + return 0; + } + jresult = jenv->NewStringUTF((&result)->c_str()); + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_StringVec_1doRemoveRange(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jint jarg2, jint jarg3) { + std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ; + jint arg2 ; + jint arg3 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(std::vector< std::string > **)&jarg1; + arg2 = jarg2; + arg3 = jarg3; + try { + std_vector_Sl_std_string_Sg__doRemoveRange(arg1,SWIG_STD_MOVE(arg2),SWIG_STD_MOVE(arg3)); + } catch(std::out_of_range &_e) { + SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, (&_e)->what()); + return ; + } +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_delete_1StringVec(JNIEnv *jenv, jclass jcls, jlong jarg1) { + std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ; + + (void)jenv; + (void)jcls; + arg1 = *(std::vector< std::string > **)&jarg1; + { + try { + delete arg1; + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_new_1NodeInfoVec_1_1SWIG_10(JNIEnv *jenv, jclass jcls) { + jlong jresult = 0 ; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *result = 0 ; + + (void)jenv; + (void)jcls; + result = (std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *)new std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >(); + *(std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > **)&jresult = result; + return jresult; +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_new_1NodeInfoVec_1_1SWIG_11(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jlong jresult = 0 ; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *arg1 = 0 ; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *result = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > **)&jarg1; + if (!arg1) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > const & is null"); + return 0; + } + result = (std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *)new std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >((std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > const &)*arg1); + *(std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > **)&jresult = result; + return jresult; +} + + +SWIGEXPORT jboolean JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_NodeInfoVec_1isEmpty(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jboolean jresult = 0 ; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *arg1 = (std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *) 0 ; + bool result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > **)&jarg1; + result = (bool)((std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > const *)arg1)->empty(); + jresult = (jboolean)result; + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_NodeInfoVec_1clear(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *arg1 = (std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *) 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > **)&jarg1; + (arg1)->clear(); +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_new_1NodeInfoVec_1_1SWIG_12(JNIEnv *jenv, jclass jcls, jint jarg1, jlong jarg2, jobject jarg2_) { + jlong jresult = 0 ; + jint arg1 ; + std::shared_ptr< ppc::protocol::INodeInfo > *arg2 = 0 ; + std::shared_ptr< ppc::protocol::INodeInfo > tempnull2 ; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *result = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg2_; + arg1 = jarg1; + arg2 = jarg2 ? *(std::shared_ptr< ppc::protocol::INodeInfo > **)&jarg2 : &tempnull2; + try { + result = (std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *)new_std_vector_Sl_std_shared_ptr_Sl_ppc_protocol_INodeInfo_Sg__Sg___SWIG_2(SWIG_STD_MOVE(arg1),(std::shared_ptr< ppc::protocol::INodeInfo > const &)*arg2); + } catch(std::out_of_range &_e) { + SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, (&_e)->what()); + return 0; + } + *(std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > **)&jresult = result; + return jresult; +} + + +SWIGEXPORT jint JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_NodeInfoVec_1doCapacity(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jint jresult = 0 ; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *arg1 = (std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *) 0 ; + jint result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > **)&jarg1; + try { + result = std_vector_Sl_std_shared_ptr_Sl_ppc_protocol_INodeInfo_Sg__Sg__doCapacity(arg1); + } catch(std::out_of_range &_e) { + SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, (&_e)->what()); + return 0; + } + jresult = result; + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_NodeInfoVec_1doReserve(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jint jarg2) { + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *arg1 = (std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *) 0 ; + jint arg2 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > **)&jarg1; + arg2 = jarg2; + try { + std_vector_Sl_std_shared_ptr_Sl_ppc_protocol_INodeInfo_Sg__Sg__doReserve(arg1,SWIG_STD_MOVE(arg2)); + } catch(std::length_error &_e) { + SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, (&_e)->what()); + return ; + } catch(std::out_of_range &_e) { + SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, (&_e)->what()); + return ; + } +} + + +SWIGEXPORT jint JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_NodeInfoVec_1doSize(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jint jresult = 0 ; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *arg1 = (std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *) 0 ; + jint result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > **)&jarg1; + try { + result = std_vector_Sl_std_shared_ptr_Sl_ppc_protocol_INodeInfo_Sg__Sg__doSize((std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > const *)arg1); + } catch(std::out_of_range &_e) { + SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, (&_e)->what()); + return 0; + } + jresult = result; + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_NodeInfoVec_1doAdd_1_1SWIG_10(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2, jobject jarg2_) { + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *arg1 = (std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *) 0 ; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type *arg2 = 0 ; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type tempnull2 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + (void)jarg2_; + arg1 = *(std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > **)&jarg1; + arg2 = jarg2 ? *(std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type **)&jarg2 : &tempnull2; + std_vector_Sl_std_shared_ptr_Sl_ppc_protocol_INodeInfo_Sg__Sg__doAdd__SWIG_0(arg1,(std::shared_ptr< ppc::protocol::INodeInfo > const &)*arg2); +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_NodeInfoVec_1doAdd_1_1SWIG_11(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jint jarg2, jlong jarg3, jobject jarg3_) { + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *arg1 = (std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *) 0 ; + jint arg2 ; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type *arg3 = 0 ; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type tempnull3 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + (void)jarg3_; + arg1 = *(std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > **)&jarg1; + arg2 = jarg2; + arg3 = jarg3 ? *(std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type **)&jarg3 : &tempnull3; + try { + std_vector_Sl_std_shared_ptr_Sl_ppc_protocol_INodeInfo_Sg__Sg__doAdd__SWIG_1(arg1,SWIG_STD_MOVE(arg2),(std::shared_ptr< ppc::protocol::INodeInfo > const &)*arg3); + } catch(std::out_of_range &_e) { + SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, (&_e)->what()); + return ; + } +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_NodeInfoVec_1doRemove(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jint jarg2) { + jlong jresult = 0 ; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *arg1 = (std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *) 0 ; + jint arg2 ; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > **)&jarg1; + arg2 = jarg2; + try { + result = std_vector_Sl_std_shared_ptr_Sl_ppc_protocol_INodeInfo_Sg__Sg__doRemove(arg1,SWIG_STD_MOVE(arg2)); + } catch(std::out_of_range &_e) { + SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, (&_e)->what()); + return 0; + } + *(std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type **)&jresult = result ? new std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type(result) : 0; + return jresult; +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_NodeInfoVec_1doGet(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jint jarg2) { + jlong jresult = 0 ; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *arg1 = (std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *) 0 ; + jint arg2 ; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type *result = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > **)&jarg1; + arg2 = jarg2; + try { + result = (std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type *) &std_vector_Sl_std_shared_ptr_Sl_ppc_protocol_INodeInfo_Sg__Sg__doGet(arg1,SWIG_STD_MOVE(arg2)); + } catch(std::out_of_range &_e) { + SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, (&_e)->what()); + return 0; + } + *(std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type **)&jresult = *result ? new std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type(*result) : 0; + return jresult; +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_NodeInfoVec_1doSet(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jint jarg2, jlong jarg3, jobject jarg3_) { + jlong jresult = 0 ; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *arg1 = (std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *) 0 ; + jint arg2 ; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type *arg3 = 0 ; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type tempnull3 ; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + (void)jarg3_; + arg1 = *(std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > **)&jarg1; + arg2 = jarg2; + arg3 = jarg3 ? *(std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type **)&jarg3 : &tempnull3; + try { + result = std_vector_Sl_std_shared_ptr_Sl_ppc_protocol_INodeInfo_Sg__Sg__doSet(arg1,SWIG_STD_MOVE(arg2),(std::shared_ptr< ppc::protocol::INodeInfo > const &)*arg3); + } catch(std::out_of_range &_e) { + SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, (&_e)->what()); + return 0; + } + *(std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type **)&jresult = result ? new std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type(result) : 0; + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_NodeInfoVec_1doRemoveRange(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jint jarg2, jint jarg3) { + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *arg1 = (std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *) 0 ; + jint arg2 ; + jint arg3 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > **)&jarg1; + arg2 = jarg2; + arg3 = jarg3; + try { + std_vector_Sl_std_shared_ptr_Sl_ppc_protocol_INodeInfo_Sg__Sg__doRemoveRange(arg1,SWIG_STD_MOVE(arg2),SWIG_STD_MOVE(arg3)); + } catch(std::out_of_range &_e) { + SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, (&_e)->what()); + return ; + } +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_delete_1NodeInfoVec(JNIEnv *jenv, jclass jcls, jlong jarg1) { + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *arg1 = (std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *) 0 ; + + (void)jenv; + (void)jcls; + arg1 = *(std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > **)&jarg1; + { + try { + delete arg1; + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_Error_1buildError_1_1SWIG_10(JNIEnv *jenv, jclass jcls, jbyteArray jarg1, jbyteArray jarg2, jint jarg3, jint jarg4, jstring jarg5) { + jlong jresult = 0 ; + char *arg1 = (char *) 0 ; + char *arg2 = (char *) 0 ; + int arg3 ; + int32_t arg4 ; + std::string *arg5 = 0 ; + bcos::Error result; + + (void)jenv; + (void)jcls; + { + arg1 = (char *) jenv->GetByteArrayElements(jarg1, 0); + } + { + arg2 = (char *) jenv->GetByteArrayElements(jarg2, 0); + } + arg3 = (int)jarg3; + arg4 = (int32_t)jarg4; + if(!jarg5) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null string"); + return 0; + } + const char *arg5_pstr = (const char *)jenv->GetStringUTFChars(jarg5, 0); + if (!arg5_pstr) return 0; + std::string arg5_str(arg5_pstr); + arg5 = &arg5_str; + jenv->ReleaseStringUTFChars(jarg5, arg5_pstr); + { + try { + result = bcos::Error::buildError((char const *)arg1,(char const *)arg2,arg3,arg4,(std::string const &)*arg5); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + *(std::shared_ptr< bcos::Error > **)&jresult = new std::shared_ptr< bcos::Error >(new bcos::Error(result)); + { + jenv->ReleaseByteArrayElements(jarg1, (jbyte *) arg1, 0); + } + { + jenv->ReleaseByteArrayElements(jarg2, (jbyte *) arg2, 0); + } + + + return jresult; +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_Error_1buildError_1_1SWIG_11(JNIEnv *jenv, jclass jcls, jbyteArray jarg1, jbyteArray jarg2, jint jarg3, jint jarg4, jstring jarg5, jlong jarg6, jobject jarg6_) { + jlong jresult = 0 ; + char *arg1 = (char *) 0 ; + char *arg2 = (char *) 0 ; + int arg3 ; + int32_t arg4 ; + std::string *arg5 = 0 ; + bcos::Error *arg6 = 0 ; + bcos::Error result; + + (void)jenv; + (void)jcls; + (void)jarg6_; + { + arg1 = (char *) jenv->GetByteArrayElements(jarg1, 0); + } + { + arg2 = (char *) jenv->GetByteArrayElements(jarg2, 0); + } + arg3 = (int)jarg3; + arg4 = (int32_t)jarg4; + if(!jarg5) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null string"); + return 0; + } + const char *arg5_pstr = (const char *)jenv->GetStringUTFChars(jarg5, 0); + if (!arg5_pstr) return 0; + std::string arg5_str(arg5_pstr); + arg5 = &arg5_str; + jenv->ReleaseStringUTFChars(jarg5, arg5_pstr); + + arg6 = (bcos::Error *)((*(std::shared_ptr< const bcos::Error > **)&jarg6) ? (*(std::shared_ptr< const bcos::Error > **)&jarg6)->get() : 0); + if (!arg6) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "bcos::Error const & reference is null"); + return 0; + } + { + try { + result = bcos::Error::buildError((char const *)arg1,(char const *)arg2,arg3,arg4,(std::string const &)*arg5,(bcos::Error const &)*arg6); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + *(std::shared_ptr< bcos::Error > **)&jresult = new std::shared_ptr< bcos::Error >(new bcos::Error(result)); + { + jenv->ReleaseByteArrayElements(jarg1, (jbyte *) arg1, 0); + } + { + jenv->ReleaseByteArrayElements(jarg2, (jbyte *) arg2, 0); + } + + + return jresult; +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_Error_1buildError_1_1SWIG_12(JNIEnv *jenv, jclass jcls, jbyteArray jarg1, jbyteArray jarg2, jint jarg3, jint jarg4, jstring jarg5, jlong jarg6) { + jlong jresult = 0 ; + char *arg1 = (char *) 0 ; + char *arg2 = (char *) 0 ; + int arg3 ; + int32_t arg4 ; + std::string *arg5 = 0 ; + std::exception *arg6 = 0 ; + bcos::Error result; + + (void)jenv; + (void)jcls; + { + arg1 = (char *) jenv->GetByteArrayElements(jarg1, 0); + } + { + arg2 = (char *) jenv->GetByteArrayElements(jarg2, 0); + } + arg3 = (int)jarg3; + arg4 = (int32_t)jarg4; + if(!jarg5) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null string"); + return 0; + } + const char *arg5_pstr = (const char *)jenv->GetStringUTFChars(jarg5, 0); + if (!arg5_pstr) return 0; + std::string arg5_str(arg5_pstr); + arg5 = &arg5_str; + jenv->ReleaseStringUTFChars(jarg5, arg5_pstr); + arg6 = *(std::exception **)&jarg6; + if (!arg6) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "std::exception const & is null"); + return 0; + } + { + try { + result = bcos::Error::buildError((char const *)arg1,(char const *)arg2,arg3,arg4,(std::string const &)*arg5,(std::exception const &)*arg6); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + *(std::shared_ptr< bcos::Error > **)&jresult = new std::shared_ptr< bcos::Error >(new bcos::Error(result)); + { + jenv->ReleaseByteArrayElements(jarg1, (jbyte *) arg1, 0); + } + { + jenv->ReleaseByteArrayElements(jarg2, (jbyte *) arg2, 0); + } + + + return jresult; +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_new_1Error_1_1SWIG_10(JNIEnv *jenv, jclass jcls) { + jlong jresult = 0 ; + bcos::Error *result = 0 ; + + (void)jenv; + (void)jcls; + { + try { + result = (bcos::Error *)new bcos::Error(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + + *(std::shared_ptr< bcos::Error > **)&jresult = result ? new std::shared_ptr< bcos::Error >(result SWIG_NO_NULL_DELETER_1) : 0; + + return jresult; +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_new_1Error_1_1SWIG_11(JNIEnv *jenv, jclass jcls, jlong jarg1, jstring jarg2) { + jlong jresult = 0 ; + int64_t arg1 ; + std::string arg2 ; + bcos::Error *result = 0 ; + + (void)jenv; + (void)jcls; + arg1 = (int64_t)jarg1; + if(!jarg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null string"); + return 0; + } + const char *arg2_pstr = (const char *)jenv->GetStringUTFChars(jarg2, 0); + if (!arg2_pstr) return 0; + (&arg2)->assign(arg2_pstr); + jenv->ReleaseStringUTFChars(jarg2, arg2_pstr); + { + try { + result = (bcos::Error *)new bcos::Error(arg1,arg2); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + + *(std::shared_ptr< bcos::Error > **)&jresult = result ? new std::shared_ptr< bcos::Error >(result SWIG_NO_NULL_DELETER_1) : 0; + + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_delete_1Error(JNIEnv *jenv, jclass jcls, jlong jarg1) { + bcos::Error *arg1 = (bcos::Error *) 0 ; + std::shared_ptr< bcos::Error > *smartarg1 = 0 ; + + (void)jenv; + (void)jcls; + + smartarg1 = *(std::shared_ptr< bcos::Error > **)&jarg1; + arg1 = (bcos::Error *)(smartarg1 ? smartarg1->get() : 0); + { + try { + (void)arg1; delete smartarg1; + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_Error_1errorCode(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jlong jresult = 0 ; + bcos::Error *arg1 = (bcos::Error *) 0 ; + std::shared_ptr< bcos::Error const > *smartarg1 = 0 ; + int64_t result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< const bcos::Error > **)&jarg1; + arg1 = (bcos::Error *)(smartarg1 ? smartarg1->get() : 0); + { + try { + result = (int64_t)((bcos::Error const *)arg1)->errorCode(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + jresult = (jlong)result; + return jresult; +} + + +SWIGEXPORT jstring JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_Error_1errorMessage(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jstring jresult = 0 ; + bcos::Error *arg1 = (bcos::Error *) 0 ; + std::shared_ptr< bcos::Error const > *smartarg1 = 0 ; + std::string *result = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< const bcos::Error > **)&jarg1; + arg1 = (bcos::Error *)(smartarg1 ? smartarg1->get() : 0); + { + try { + result = (std::string *) &((bcos::Error const *)arg1)->errorMessage(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + jresult = jenv->NewStringUTF(result->c_str()); + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_Error_1setErrorCode(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2) { + bcos::Error *arg1 = (bcos::Error *) 0 ; + int64_t arg2 ; + std::shared_ptr< bcos::Error > *smartarg1 = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< bcos::Error > **)&jarg1; + arg1 = (bcos::Error *)(smartarg1 ? smartarg1->get() : 0); + arg2 = (int64_t)jarg2; + { + try { + (arg1)->setErrorCode(arg2); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_Error_1setErrorMessage(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jstring jarg2) { + bcos::Error *arg1 = (bcos::Error *) 0 ; + std::string *arg2 = 0 ; + std::shared_ptr< bcos::Error > *smartarg1 = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< bcos::Error > **)&jarg1; + arg1 = (bcos::Error *)(smartarg1 ? smartarg1->get() : 0); + if(!jarg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null string"); + return ; + } + const char *arg2_pstr = (const char *)jenv->GetStringUTFChars(jarg2, 0); + if (!arg2_pstr) return ; + std::string arg2_str(arg2_pstr); + arg2 = &arg2_str; + jenv->ReleaseStringUTFChars(jarg2, arg2_pstr); + { + try { + (arg1)->setErrorMessage((std::string const &)*arg2); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_InputBuffer_1data_1set(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2) { + InputBuffer *arg1 = (InputBuffer *) 0 ; + unsigned char *arg2 = (unsigned char *) 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(InputBuffer **)&jarg1; + arg2 = *(unsigned char **)&jarg2; + if (arg1) (arg1)->data = (unsigned char const *)arg2; +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_InputBuffer_1data_1get(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jlong jresult = 0 ; + InputBuffer *arg1 = (InputBuffer *) 0 ; + unsigned char *result = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(InputBuffer **)&jarg1; + result = (unsigned char *) ((arg1)->data); + *(unsigned char **)&jresult = result; + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_InputBuffer_1len_1set(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jobject jarg2) { + InputBuffer *arg1 = (InputBuffer *) 0 ; + uint64_t arg2 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(InputBuffer **)&jarg1; + { + jclass clazz; + jmethodID mid; + jbyteArray ba; + jbyte* bae; + jsize sz; + int i; + + if (!jarg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "BigInteger null"); + return ; + } + clazz = jenv->GetObjectClass(jarg2); + mid = jenv->GetMethodID(clazz, "toByteArray", "()[B"); + ba = (jbyteArray)jenv->CallObjectMethod(jarg2, mid); + bae = jenv->GetByteArrayElements(ba, 0); + sz = jenv->GetArrayLength(ba); + arg2 = 0; + if (sz > 0) { + arg2 = (uint64_t)(signed char)bae[0]; + for(i=1; iReleaseByteArrayElements(ba, bae, 0); + } + if (arg1) (arg1)->len = arg2; +} + + +SWIGEXPORT jobject JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_InputBuffer_1len_1get(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jobject jresult = 0 ; + InputBuffer *arg1 = (InputBuffer *) 0 ; + uint64_t result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(InputBuffer **)&jarg1; + result = (uint64_t) ((arg1)->len); + { + jbyteArray ba = jenv->NewByteArray(9); + jbyte* bae = jenv->GetByteArrayElements(ba, 0); + jclass clazz = jenv->FindClass("java/math/BigInteger"); + jmethodID mid = jenv->GetMethodID(clazz, "", "([B)V"); + jobject bigint; + int i; + + bae[0] = 0; + for(i=1; i<9; i++ ) { + bae[i] = (jbyte)(result>>8*(8-i)); + } + + jenv->ReleaseByteArrayElements(ba, bae, 0); + bigint = jenv->NewObject(clazz, mid, ba); + jenv->DeleteLocalRef(ba); + jresult = bigint; + } + return jresult; +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_new_1InputBuffer(JNIEnv *jenv, jclass jcls) { + jlong jresult = 0 ; + InputBuffer *result = 0 ; + + (void)jenv; + (void)jcls; + { + try { + result = (InputBuffer *)new InputBuffer(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + *(InputBuffer **)&jresult = result; + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_delete_1InputBuffer(JNIEnv *jenv, jclass jcls, jlong jarg1) { + InputBuffer *arg1 = (InputBuffer *) 0 ; + + (void)jenv; + (void)jcls; + arg1 = *(InputBuffer **)&jarg1; + { + try { + delete arg1; + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_OutputBuffer_1data_1set(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2) { + OutputBuffer *arg1 = (OutputBuffer *) 0 ; + unsigned char *arg2 = (unsigned char *) 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(OutputBuffer **)&jarg1; + arg2 = *(unsigned char **)&jarg2; + if (arg1) (arg1)->data = arg2; +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_OutputBuffer_1data_1get(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jlong jresult = 0 ; + OutputBuffer *arg1 = (OutputBuffer *) 0 ; + unsigned char *result = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(OutputBuffer **)&jarg1; + result = (unsigned char *) ((arg1)->data); + *(unsigned char **)&jresult = result; + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_OutputBuffer_1len_1set(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jobject jarg2) { + OutputBuffer *arg1 = (OutputBuffer *) 0 ; + uint64_t arg2 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(OutputBuffer **)&jarg1; + { + jclass clazz; + jmethodID mid; + jbyteArray ba; + jbyte* bae; + jsize sz; + int i; + + if (!jarg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "BigInteger null"); + return ; + } + clazz = jenv->GetObjectClass(jarg2); + mid = jenv->GetMethodID(clazz, "toByteArray", "()[B"); + ba = (jbyteArray)jenv->CallObjectMethod(jarg2, mid); + bae = jenv->GetByteArrayElements(ba, 0); + sz = jenv->GetArrayLength(ba); + arg2 = 0; + if (sz > 0) { + arg2 = (uint64_t)(signed char)bae[0]; + for(i=1; iReleaseByteArrayElements(ba, bae, 0); + } + if (arg1) (arg1)->len = arg2; +} + + +SWIGEXPORT jobject JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_OutputBuffer_1len_1get(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jobject jresult = 0 ; + OutputBuffer *arg1 = (OutputBuffer *) 0 ; + uint64_t result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(OutputBuffer **)&jarg1; + result = (uint64_t) ((arg1)->len); + { + jbyteArray ba = jenv->NewByteArray(9); + jbyte* bae = jenv->GetByteArrayElements(ba, 0); + jclass clazz = jenv->FindClass("java/math/BigInteger"); + jmethodID mid = jenv->GetMethodID(clazz, "", "([B)V"); + jobject bigint; + int i; + + bae[0] = 0; + for(i=1; i<9; i++ ) { + bae[i] = (jbyte)(result>>8*(8-i)); + } + + jenv->ReleaseByteArrayElements(ba, bae, 0); + bigint = jenv->NewObject(clazz, mid, ba); + jenv->DeleteLocalRef(ba); + jresult = bigint; + } + return jresult; +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_new_1OutputBuffer(JNIEnv *jenv, jclass jcls) { + jlong jresult = 0 ; + OutputBuffer *result = 0 ; + + (void)jenv; + (void)jcls; + { + try { + result = (OutputBuffer *)new OutputBuffer(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + *(OutputBuffer **)&jresult = result; + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_delete_1OutputBuffer(JNIEnv *jenv, jclass jcls, jlong jarg1) { + OutputBuffer *arg1 = (OutputBuffer *) 0 ; + + (void)jenv; + (void)jcls; + arg1 = *(OutputBuffer **)&jarg1; + { + try { + delete arg1; + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_delete_1FrontConfig(JNIEnv *jenv, jclass jcls, jlong jarg1) { + ppc::front::FrontConfig *arg1 = (ppc::front::FrontConfig *) 0 ; + std::shared_ptr< ppc::front::FrontConfig > *smartarg1 = 0 ; + + (void)jenv; + (void)jcls; + + smartarg1 = *(std::shared_ptr< ppc::front::FrontConfig > **)&jarg1; + arg1 = (ppc::front::FrontConfig *)(smartarg1 ? smartarg1->get() : 0); + { + try { + (void)arg1; delete smartarg1; + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT jint JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_FrontConfig_1threadPoolSize(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jint jresult = 0 ; + ppc::front::FrontConfig *arg1 = (ppc::front::FrontConfig *) 0 ; + std::shared_ptr< ppc::front::FrontConfig const > *smartarg1 = 0 ; + int result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< const ppc::front::FrontConfig > **)&jarg1; + arg1 = (ppc::front::FrontConfig *)(smartarg1 ? smartarg1->get() : 0); + { + try { + result = (int)((ppc::front::FrontConfig const *)arg1)->threadPoolSize(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + jresult = (jint)result; + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_FrontConfig_1setThreadPoolSize(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jint jarg2) { + ppc::front::FrontConfig *arg1 = (ppc::front::FrontConfig *) 0 ; + int arg2 ; + std::shared_ptr< ppc::front::FrontConfig > *smartarg1 = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< ppc::front::FrontConfig > **)&jarg1; + arg1 = (ppc::front::FrontConfig *)(smartarg1 ? smartarg1->get() : 0); + arg2 = (int)jarg2; + { + try { + (arg1)->setThreadPoolSize(arg2); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT jstring JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_FrontConfig_1nodeID(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jstring jresult = 0 ; + ppc::front::FrontConfig *arg1 = (ppc::front::FrontConfig *) 0 ; + std::shared_ptr< ppc::front::FrontConfig const > *smartarg1 = 0 ; + std::string *result = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< const ppc::front::FrontConfig > **)&jarg1; + arg1 = (ppc::front::FrontConfig *)(smartarg1 ? smartarg1->get() : 0); + { + try { + result = (std::string *) &((ppc::front::FrontConfig const *)arg1)->nodeID(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + jresult = jenv->NewStringUTF(result->c_str()); + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_FrontConfig_1setNodeID(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jstring jarg2) { + ppc::front::FrontConfig *arg1 = (ppc::front::FrontConfig *) 0 ; + std::string *arg2 = 0 ; + std::shared_ptr< ppc::front::FrontConfig > *smartarg1 = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< ppc::front::FrontConfig > **)&jarg1; + arg1 = (ppc::front::FrontConfig *)(smartarg1 ? smartarg1->get() : 0); + if(!jarg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null string"); + return ; + } + const char *arg2_pstr = (const char *)jenv->GetStringUTFChars(jarg2, 0); + if (!arg2_pstr) return ; + std::string arg2_str(arg2_pstr); + arg2 = &arg2_str; + jenv->ReleaseStringUTFChars(jarg2, arg2_pstr); + { + try { + (arg1)->setNodeID((std::string const &)*arg2); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_FrontConfig_1selfEndPoint(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jlong jresult = 0 ; + ppc::front::FrontConfig *arg1 = (ppc::front::FrontConfig *) 0 ; + std::shared_ptr< ppc::front::FrontConfig const > *smartarg1 = 0 ; + ppc::protocol::EndPoint *result = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< const ppc::front::FrontConfig > **)&jarg1; + arg1 = (ppc::front::FrontConfig *)(smartarg1 ? smartarg1->get() : 0); + { + try { + result = (ppc::protocol::EndPoint *) &((ppc::front::FrontConfig const *)arg1)->selfEndPoint(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + *(ppc::protocol::EndPoint **)&jresult = result; + return jresult; +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_FrontConfig_1mutableSelfEndPoint(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jlong jresult = 0 ; + ppc::front::FrontConfig *arg1 = (ppc::front::FrontConfig *) 0 ; + std::shared_ptr< ppc::front::FrontConfig > *smartarg1 = 0 ; + ppc::protocol::EndPoint *result = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< ppc::front::FrontConfig > **)&jarg1; + arg1 = (ppc::front::FrontConfig *)(smartarg1 ? smartarg1->get() : 0); + { + try { + result = (ppc::protocol::EndPoint *) &(arg1)->mutableSelfEndPoint(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + *(ppc::protocol::EndPoint **)&jresult = result; + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_FrontConfig_1setSelfEndPoint(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2, jobject jarg2_) { + ppc::front::FrontConfig *arg1 = (ppc::front::FrontConfig *) 0 ; + ppc::protocol::EndPoint *arg2 = 0 ; + std::shared_ptr< ppc::front::FrontConfig > *smartarg1 = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + (void)jarg2_; + + smartarg1 = *(std::shared_ptr< ppc::front::FrontConfig > **)&jarg1; + arg1 = (ppc::front::FrontConfig *)(smartarg1 ? smartarg1->get() : 0); + arg2 = *(ppc::protocol::EndPoint **)&jarg2; + if (!arg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "ppc::protocol::EndPoint const & is null"); + return ; + } + { + try { + (arg1)->setSelfEndPoint((ppc::protocol::EndPoint const &)*arg2); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_FrontConfig_1setGatewayGrpcTarget(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jstring jarg2) { + ppc::front::FrontConfig *arg1 = (ppc::front::FrontConfig *) 0 ; + std::string *arg2 = 0 ; + std::shared_ptr< ppc::front::FrontConfig > *smartarg1 = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< ppc::front::FrontConfig > **)&jarg1; + arg1 = (ppc::front::FrontConfig *)(smartarg1 ? smartarg1->get() : 0); + if(!jarg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null string"); + return ; + } + const char *arg2_pstr = (const char *)jenv->GetStringUTFChars(jarg2, 0); + if (!arg2_pstr) return ; + std::string arg2_str(arg2_pstr); + arg2 = &arg2_str; + jenv->ReleaseStringUTFChars(jarg2, arg2_pstr); + { + try { + (arg1)->setGatewayGrpcTarget((std::string const &)*arg2); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT jstring JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_FrontConfig_1gatewayGrpcTarget(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jstring jresult = 0 ; + ppc::front::FrontConfig *arg1 = (ppc::front::FrontConfig *) 0 ; + std::shared_ptr< ppc::front::FrontConfig const > *smartarg1 = 0 ; + std::string *result = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< const ppc::front::FrontConfig > **)&jarg1; + arg1 = (ppc::front::FrontConfig *)(smartarg1 ? smartarg1->get() : 0); + { + try { + result = (std::string *) &((ppc::front::FrontConfig const *)arg1)->gatewayGrpcTarget(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + jresult = jenv->NewStringUTF(result->c_str()); + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_FrontConfig_1setGrpcConfig(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2, jobject jarg2_) { + ppc::front::FrontConfig *arg1 = (ppc::front::FrontConfig *) 0 ; + ppc::protocol::GrpcConfig::Ptr arg2 ; + std::shared_ptr< ppc::front::FrontConfig > *smartarg1 = 0 ; + ppc::protocol::GrpcConfig::Ptr *argp2 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + (void)jarg2_; + + smartarg1 = *(std::shared_ptr< ppc::front::FrontConfig > **)&jarg1; + arg1 = (ppc::front::FrontConfig *)(smartarg1 ? smartarg1->get() : 0); + argp2 = *(ppc::protocol::GrpcConfig::Ptr **)&jarg2; + if (argp2) arg2 = *argp2; + { + try { + (arg1)->setGrpcConfig(arg2); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_FrontConfig_1grpcConfig(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jlong jresult = 0 ; + ppc::front::FrontConfig *arg1 = (ppc::front::FrontConfig *) 0 ; + std::shared_ptr< ppc::front::FrontConfig const > *smartarg1 = 0 ; + ppc::protocol::GrpcConfig::Ptr *result = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< const ppc::front::FrontConfig > **)&jarg1; + arg1 = (ppc::front::FrontConfig *)(smartarg1 ? smartarg1->get() : 0); + { + try { + result = (ppc::protocol::GrpcConfig::Ptr *) &((ppc::front::FrontConfig const *)arg1)->grpcConfig(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + *(ppc::protocol::GrpcConfig::Ptr **)&jresult = *result ? new ppc::protocol::GrpcConfig::Ptr(*result) : 0; + return jresult; +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_FrontConfig_1generateNodeInfo(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jlong jresult = 0 ; + ppc::front::FrontConfig *arg1 = (ppc::front::FrontConfig *) 0 ; + std::shared_ptr< ppc::front::FrontConfig const > *smartarg1 = 0 ; + ppc::protocol::INodeInfo::Ptr result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< const ppc::front::FrontConfig > **)&jarg1; + arg1 = (ppc::front::FrontConfig *)(smartarg1 ? smartarg1->get() : 0); + { + try { + result = ((ppc::front::FrontConfig const *)arg1)->generateNodeInfo(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + *(ppc::protocol::INodeInfo::Ptr **)&jresult = result ? new ppc::protocol::INodeInfo::Ptr(result) : 0; + return jresult; +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_FrontConfig_1getComponents(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jlong jresult = 0 ; + ppc::front::FrontConfig *arg1 = (ppc::front::FrontConfig *) 0 ; + std::shared_ptr< ppc::front::FrontConfig const > *smartarg1 = 0 ; + std::vector< std::string > *result = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< const ppc::front::FrontConfig > **)&jarg1; + arg1 = (ppc::front::FrontConfig *)(smartarg1 ? smartarg1->get() : 0); + { + try { + result = (std::vector< std::string > *) &((ppc::front::FrontConfig const *)arg1)->getComponents(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + *(std::vector< std::string > **)&jresult = result; + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_FrontConfig_1setComponents(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2, jobject jarg2_) { + ppc::front::FrontConfig *arg1 = (ppc::front::FrontConfig *) 0 ; + std::vector< std::string > *arg2 = 0 ; + std::shared_ptr< ppc::front::FrontConfig > *smartarg1 = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + (void)jarg2_; + + smartarg1 = *(std::shared_ptr< ppc::front::FrontConfig > **)&jarg1; + arg1 = (ppc::front::FrontConfig *)(smartarg1 ? smartarg1->get() : 0); + arg2 = *(std::vector< std::string > **)&jarg2; + if (!arg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "std::vector< std::string > const & is null"); + return ; + } + { + try { + (arg1)->setComponents((std::vector< std::string > const &)*arg2); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_FrontConfig_1addComponent(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jstring jarg2) { + ppc::front::FrontConfig *arg1 = (ppc::front::FrontConfig *) 0 ; + std::string *arg2 = 0 ; + std::shared_ptr< ppc::front::FrontConfig > *smartarg1 = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< ppc::front::FrontConfig > **)&jarg1; + arg1 = (ppc::front::FrontConfig *)(smartarg1 ? smartarg1->get() : 0); + if(!jarg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null string"); + return ; + } + const char *arg2_pstr = (const char *)jenv->GetStringUTFChars(jarg2, 0); + if (!arg2_pstr) return ; + std::string arg2_str(arg2_pstr); + arg2 = &arg2_str; + jenv->ReleaseStringUTFChars(jarg2, arg2_pstr); + { + try { + (arg1)->addComponent((std::string const &)*arg2); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_FrontConfig_1mutableComponents(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jlong jresult = 0 ; + ppc::front::FrontConfig *arg1 = (ppc::front::FrontConfig *) 0 ; + std::shared_ptr< ppc::front::FrontConfig > *smartarg1 = 0 ; + std::vector< std::string > *result = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< ppc::front::FrontConfig > **)&jarg1; + arg1 = (ppc::front::FrontConfig *)(smartarg1 ? smartarg1->get() : 0); + { + try { + result = (std::vector< std::string > *) &(arg1)->mutableComponents(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + *(std::vector< std::string > **)&jresult = result; + return jresult; +} + + +SWIGEXPORT jstring JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_FrontConfig_1meta(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jstring jresult = 0 ; + ppc::front::FrontConfig *arg1 = (ppc::front::FrontConfig *) 0 ; + std::shared_ptr< ppc::front::FrontConfig const > *smartarg1 = 0 ; + std::string result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< const ppc::front::FrontConfig > **)&jarg1; + arg1 = (ppc::front::FrontConfig *)(smartarg1 ? smartarg1->get() : 0); + { + try { + result = ((ppc::front::FrontConfig const *)arg1)->meta(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + jresult = jenv->NewStringUTF((&result)->c_str()); + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_FrontConfig_1setMeta(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jstring jarg2) { + ppc::front::FrontConfig *arg1 = (ppc::front::FrontConfig *) 0 ; + std::string arg2 ; + std::shared_ptr< ppc::front::FrontConfig > *smartarg1 = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< ppc::front::FrontConfig > **)&jarg1; + arg1 = (ppc::front::FrontConfig *)(smartarg1 ? smartarg1->get() : 0); + if(!jarg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null string"); + return ; + } + const char *arg2_pstr = (const char *)jenv->GetStringUTFChars(jarg2, 0); + if (!arg2_pstr) return ; + (&arg2)->assign(arg2_pstr); + jenv->ReleaseStringUTFChars(jarg2, arg2_pstr); + { + try { + (arg1)->setMeta(arg2); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_delete_1FrontConfigBuilder(JNIEnv *jenv, jclass jcls, jlong jarg1) { + ppc::front::FrontConfigBuilder *arg1 = (ppc::front::FrontConfigBuilder *) 0 ; + + (void)jenv; + (void)jcls; + arg1 = *(ppc::front::FrontConfigBuilder **)&jarg1; + { + try { + delete arg1; + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_FrontConfigBuilder_1build_1_1SWIG_10(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jlong jresult = 0 ; + ppc::front::FrontConfigBuilder *arg1 = (ppc::front::FrontConfigBuilder *) 0 ; + ppc::front::FrontConfig::Ptr result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(ppc::front::FrontConfigBuilder **)&jarg1; + { + try { + result = ((ppc::front::FrontConfigBuilder const *)arg1)->build(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + *(ppc::front::FrontConfig::Ptr **)&jresult = result ? new ppc::front::FrontConfig::Ptr(result) : 0; + return jresult; +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_FrontConfigBuilder_1build_1_1SWIG_11(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jint jarg2, jstring jarg3) { + jlong jresult = 0 ; + ppc::front::FrontConfigBuilder *arg1 = (ppc::front::FrontConfigBuilder *) 0 ; + int arg2 ; + std::string arg3 ; + ppc::front::FrontConfig::Ptr result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(ppc::front::FrontConfigBuilder **)&jarg1; + arg2 = (int)jarg2; + if(!jarg3) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null string"); + return 0; + } + const char *arg3_pstr = (const char *)jenv->GetStringUTFChars(jarg3, 0); + if (!arg3_pstr) return 0; + (&arg3)->assign(arg3_pstr); + jenv->ReleaseStringUTFChars(jarg3, arg3_pstr); + { + try { + result = ((ppc::front::FrontConfigBuilder const *)arg1)->build(arg2,arg3); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + *(ppc::front::FrontConfig::Ptr **)&jresult = result ? new ppc::front::FrontConfig::Ptr(result) : 0; + return jresult; +} + + +SWIGEXPORT jstring JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_printFrontDesc(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jstring jresult = 0 ; + ppc::front::FrontConfig::Ptr *arg1 = 0 ; + ppc::front::FrontConfig::Ptr tempnull1 ; + std::string result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = jarg1 ? *(ppc::front::FrontConfig::Ptr **)&jarg1 : &tempnull1; + { + try { + result = ppc::front::printFrontDesc((std::shared_ptr< ppc::front::FrontConfig > const &)*arg1); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + jresult = jenv->NewStringUTF((&result)->c_str()); + return jresult; +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_new_1EndPoint_1_1SWIG_10(JNIEnv *jenv, jclass jcls) { + jlong jresult = 0 ; + ppc::protocol::EndPoint *result = 0 ; + + (void)jenv; + (void)jcls; + { + try { + result = (ppc::protocol::EndPoint *)new ppc::protocol::EndPoint(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + *(ppc::protocol::EndPoint **)&jresult = result; + return jresult; +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_new_1EndPoint_1_1SWIG_11(JNIEnv *jenv, jclass jcls, jstring jarg1, jint jarg2) { + jlong jresult = 0 ; + std::string *arg1 = 0 ; + uint16_t arg2 ; + ppc::protocol::EndPoint *result = 0 ; + + (void)jenv; + (void)jcls; + if(!jarg1) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null string"); + return 0; + } + const char *arg1_pstr = (const char *)jenv->GetStringUTFChars(jarg1, 0); + if (!arg1_pstr) return 0; + std::string arg1_str(arg1_pstr); + arg1 = &arg1_str; + jenv->ReleaseStringUTFChars(jarg1, arg1_pstr); + arg2 = (uint16_t)jarg2; + { + try { + result = (ppc::protocol::EndPoint *)new ppc::protocol::EndPoint((std::string const &)*arg1,arg2); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + *(ppc::protocol::EndPoint **)&jresult = result; + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_delete_1EndPoint(JNIEnv *jenv, jclass jcls, jlong jarg1) { + ppc::protocol::EndPoint *arg1 = (ppc::protocol::EndPoint *) 0 ; + + (void)jenv; + (void)jcls; + arg1 = *(ppc::protocol::EndPoint **)&jarg1; + { + try { + delete arg1; + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT jstring JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_EndPoint_1host(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jstring jresult = 0 ; + ppc::protocol::EndPoint *arg1 = (ppc::protocol::EndPoint *) 0 ; + std::string *result = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(ppc::protocol::EndPoint **)&jarg1; + { + try { + result = (std::string *) &((ppc::protocol::EndPoint const *)arg1)->host(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + jresult = jenv->NewStringUTF(result->c_str()); + return jresult; +} + + +SWIGEXPORT jint JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_EndPoint_1port(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jint jresult = 0 ; + ppc::protocol::EndPoint *arg1 = (ppc::protocol::EndPoint *) 0 ; + uint16_t result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(ppc::protocol::EndPoint **)&jarg1; + { + try { + result = (uint16_t)((ppc::protocol::EndPoint const *)arg1)->port(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + jresult = (jint)result; + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_EndPoint_1setHost(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jstring jarg2) { + ppc::protocol::EndPoint *arg1 = (ppc::protocol::EndPoint *) 0 ; + std::string arg2 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(ppc::protocol::EndPoint **)&jarg1; + if(!jarg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null string"); + return ; + } + const char *arg2_pstr = (const char *)jenv->GetStringUTFChars(jarg2, 0); + if (!arg2_pstr) return ; + (&arg2)->assign(arg2_pstr); + jenv->ReleaseStringUTFChars(jarg2, arg2_pstr); + { + try { + (arg1)->setHost(arg2); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_EndPoint_1setPort(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jint jarg2) { + ppc::protocol::EndPoint *arg1 = (ppc::protocol::EndPoint *) 0 ; + uint16_t arg2 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(ppc::protocol::EndPoint **)&jarg1; + arg2 = (uint16_t)jarg2; + { + try { + (arg1)->setPort(arg2); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_EndPoint_1setListenIp(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jstring jarg2) { + ppc::protocol::EndPoint *arg1 = (ppc::protocol::EndPoint *) 0 ; + std::string *arg2 = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(ppc::protocol::EndPoint **)&jarg1; + if(!jarg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null string"); + return ; + } + const char *arg2_pstr = (const char *)jenv->GetStringUTFChars(jarg2, 0); + if (!arg2_pstr) return ; + std::string arg2_str(arg2_pstr); + arg2 = &arg2_str; + jenv->ReleaseStringUTFChars(jarg2, arg2_pstr); + { + try { + (arg1)->setListenIp((std::string const &)*arg2); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT jstring JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_EndPoint_1entryPoint(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jstring jresult = 0 ; + ppc::protocol::EndPoint *arg1 = (ppc::protocol::EndPoint *) 0 ; + std::string result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(ppc::protocol::EndPoint **)&jarg1; + { + try { + result = ((ppc::protocol::EndPoint const *)arg1)->entryPoint(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + jresult = jenv->NewStringUTF((&result)->c_str()); + return jresult; +} + + +SWIGEXPORT jstring JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_EndPoint_1listenEndPoint(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jstring jresult = 0 ; + ppc::protocol::EndPoint *arg1 = (ppc::protocol::EndPoint *) 0 ; + std::string result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(ppc::protocol::EndPoint **)&jarg1; + { + try { + result = ((ppc::protocol::EndPoint const *)arg1)->listenEndPoint(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + jresult = jenv->NewStringUTF((&result)->c_str()); + return jresult; +} + + +SWIGEXPORT jstring JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_EndPoint_1listenIp(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jstring jresult = 0 ; + ppc::protocol::EndPoint *arg1 = (ppc::protocol::EndPoint *) 0 ; + std::string *result = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(ppc::protocol::EndPoint **)&jarg1; + { + try { + result = (std::string *) &((ppc::protocol::EndPoint const *)arg1)->listenIp(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + jresult = jenv->NewStringUTF(result->c_str()); + return jresult; +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_new_1GrpcConfig(JNIEnv *jenv, jclass jcls) { + jlong jresult = 0 ; + ppc::protocol::GrpcConfig *result = 0 ; + + (void)jenv; + (void)jcls; + { + try { + result = (ppc::protocol::GrpcConfig *)new ppc::protocol::GrpcConfig(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + + *(std::shared_ptr< ppc::protocol::GrpcConfig > **)&jresult = result ? new std::shared_ptr< ppc::protocol::GrpcConfig >(result SWIG_NO_NULL_DELETER_1) : 0; + + return jresult; +} + + +SWIGEXPORT jstring JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_GrpcConfig_1loadBalancePolicy(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jstring jresult = 0 ; + ppc::protocol::GrpcConfig *arg1 = (ppc::protocol::GrpcConfig *) 0 ; + std::shared_ptr< ppc::protocol::GrpcConfig const > *smartarg1 = 0 ; + std::string *result = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< const ppc::protocol::GrpcConfig > **)&jarg1; + arg1 = (ppc::protocol::GrpcConfig *)(smartarg1 ? smartarg1->get() : 0); + { + try { + result = (std::string *) &((ppc::protocol::GrpcConfig const *)arg1)->loadBalancePolicy(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + jresult = jenv->NewStringUTF(result->c_str()); + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_GrpcConfig_1setLoadBalancePolicy(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jstring jarg2) { + ppc::protocol::GrpcConfig *arg1 = (ppc::protocol::GrpcConfig *) 0 ; + std::string *arg2 = 0 ; + std::shared_ptr< ppc::protocol::GrpcConfig > *smartarg1 = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< ppc::protocol::GrpcConfig > **)&jarg1; + arg1 = (ppc::protocol::GrpcConfig *)(smartarg1 ? smartarg1->get() : 0); + if(!jarg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null string"); + return ; + } + const char *arg2_pstr = (const char *)jenv->GetStringUTFChars(jarg2, 0); + if (!arg2_pstr) return ; + std::string arg2_str(arg2_pstr); + arg2 = &arg2_str; + jenv->ReleaseStringUTFChars(jarg2, arg2_pstr); + { + try { + (arg1)->setLoadBalancePolicy((std::string const &)*arg2); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT jboolean JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_GrpcConfig_1enableHealthCheck(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jboolean jresult = 0 ; + ppc::protocol::GrpcConfig *arg1 = (ppc::protocol::GrpcConfig *) 0 ; + std::shared_ptr< ppc::protocol::GrpcConfig const > *smartarg1 = 0 ; + bool result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< const ppc::protocol::GrpcConfig > **)&jarg1; + arg1 = (ppc::protocol::GrpcConfig *)(smartarg1 ? smartarg1->get() : 0); + { + try { + result = (bool)((ppc::protocol::GrpcConfig const *)arg1)->enableHealthCheck(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + jresult = (jboolean)result; + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_GrpcConfig_1setEnableHealthCheck(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jboolean jarg2) { + ppc::protocol::GrpcConfig *arg1 = (ppc::protocol::GrpcConfig *) 0 ; + bool arg2 ; + std::shared_ptr< ppc::protocol::GrpcConfig > *smartarg1 = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< ppc::protocol::GrpcConfig > **)&jarg1; + arg1 = (ppc::protocol::GrpcConfig *)(smartarg1 ? smartarg1->get() : 0); + arg2 = jarg2 ? true : false; + { + try { + (arg1)->setEnableHealthCheck(arg2); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_GrpcConfig_1setEnableDnslookup(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jboolean jarg2) { + ppc::protocol::GrpcConfig *arg1 = (ppc::protocol::GrpcConfig *) 0 ; + bool arg2 ; + std::shared_ptr< ppc::protocol::GrpcConfig > *smartarg1 = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< ppc::protocol::GrpcConfig > **)&jarg1; + arg1 = (ppc::protocol::GrpcConfig *)(smartarg1 ? smartarg1->get() : 0); + arg2 = jarg2 ? true : false; + { + try { + (arg1)->setEnableDnslookup(arg2); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT jboolean JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_GrpcConfig_1enableDnslookup(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jboolean jresult = 0 ; + ppc::protocol::GrpcConfig *arg1 = (ppc::protocol::GrpcConfig *) 0 ; + std::shared_ptr< ppc::protocol::GrpcConfig const > *smartarg1 = 0 ; + bool result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< const ppc::protocol::GrpcConfig > **)&jarg1; + arg1 = (ppc::protocol::GrpcConfig *)(smartarg1 ? smartarg1->get() : 0); + { + try { + result = (bool)((ppc::protocol::GrpcConfig const *)arg1)->enableDnslookup(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + jresult = (jboolean)result; + return jresult; +} + + +SWIGEXPORT jobject JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_GrpcConfig_1maxSendMessageSize(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jobject jresult = 0 ; + ppc::protocol::GrpcConfig *arg1 = (ppc::protocol::GrpcConfig *) 0 ; + std::shared_ptr< ppc::protocol::GrpcConfig const > *smartarg1 = 0 ; + uint64_t result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< const ppc::protocol::GrpcConfig > **)&jarg1; + arg1 = (ppc::protocol::GrpcConfig *)(smartarg1 ? smartarg1->get() : 0); + { + try { + result = (uint64_t)((ppc::protocol::GrpcConfig const *)arg1)->maxSendMessageSize(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + { + jbyteArray ba = jenv->NewByteArray(9); + jbyte* bae = jenv->GetByteArrayElements(ba, 0); + jclass clazz = jenv->FindClass("java/math/BigInteger"); + jmethodID mid = jenv->GetMethodID(clazz, "", "([B)V"); + jobject bigint; + int i; + + bae[0] = 0; + for(i=1; i<9; i++ ) { + bae[i] = (jbyte)(result>>8*(8-i)); + } + + jenv->ReleaseByteArrayElements(ba, bae, 0); + bigint = jenv->NewObject(clazz, mid, ba); + jenv->DeleteLocalRef(ba); + jresult = bigint; + } + return jresult; +} + + +SWIGEXPORT jobject JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_GrpcConfig_1maxReceivedMessageSize(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jobject jresult = 0 ; + ppc::protocol::GrpcConfig *arg1 = (ppc::protocol::GrpcConfig *) 0 ; + std::shared_ptr< ppc::protocol::GrpcConfig const > *smartarg1 = 0 ; + uint64_t result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< const ppc::protocol::GrpcConfig > **)&jarg1; + arg1 = (ppc::protocol::GrpcConfig *)(smartarg1 ? smartarg1->get() : 0); + { + try { + result = (uint64_t)((ppc::protocol::GrpcConfig const *)arg1)->maxReceivedMessageSize(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + { + jbyteArray ba = jenv->NewByteArray(9); + jbyte* bae = jenv->GetByteArrayElements(ba, 0); + jclass clazz = jenv->FindClass("java/math/BigInteger"); + jmethodID mid = jenv->GetMethodID(clazz, "", "([B)V"); + jobject bigint; + int i; + + bae[0] = 0; + for(i=1; i<9; i++ ) { + bae[i] = (jbyte)(result>>8*(8-i)); + } + + jenv->ReleaseByteArrayElements(ba, bae, 0); + bigint = jenv->NewObject(clazz, mid, ba); + jenv->DeleteLocalRef(ba); + jresult = bigint; + } + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_GrpcConfig_1setMaxSendMessageSize(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jobject jarg2) { + ppc::protocol::GrpcConfig *arg1 = (ppc::protocol::GrpcConfig *) 0 ; + uint64_t arg2 ; + std::shared_ptr< ppc::protocol::GrpcConfig > *smartarg1 = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< ppc::protocol::GrpcConfig > **)&jarg1; + arg1 = (ppc::protocol::GrpcConfig *)(smartarg1 ? smartarg1->get() : 0); + { + jclass clazz; + jmethodID mid; + jbyteArray ba; + jbyte* bae; + jsize sz; + int i; + + if (!jarg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "BigInteger null"); + return ; + } + clazz = jenv->GetObjectClass(jarg2); + mid = jenv->GetMethodID(clazz, "toByteArray", "()[B"); + ba = (jbyteArray)jenv->CallObjectMethod(jarg2, mid); + bae = jenv->GetByteArrayElements(ba, 0); + sz = jenv->GetArrayLength(ba); + arg2 = 0; + if (sz > 0) { + arg2 = (uint64_t)(signed char)bae[0]; + for(i=1; iReleaseByteArrayElements(ba, bae, 0); + } + { + try { + (arg1)->setMaxSendMessageSize(arg2); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_GrpcConfig_1setMaxReceivedMessageSize(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jobject jarg2) { + ppc::protocol::GrpcConfig *arg1 = (ppc::protocol::GrpcConfig *) 0 ; + uint64_t arg2 ; + std::shared_ptr< ppc::protocol::GrpcConfig > *smartarg1 = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< ppc::protocol::GrpcConfig > **)&jarg1; + arg1 = (ppc::protocol::GrpcConfig *)(smartarg1 ? smartarg1->get() : 0); + { + jclass clazz; + jmethodID mid; + jbyteArray ba; + jbyte* bae; + jsize sz; + int i; + + if (!jarg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "BigInteger null"); + return ; + } + clazz = jenv->GetObjectClass(jarg2); + mid = jenv->GetMethodID(clazz, "toByteArray", "()[B"); + ba = (jbyteArray)jenv->CallObjectMethod(jarg2, mid); + bae = jenv->GetByteArrayElements(ba, 0); + sz = jenv->GetArrayLength(ba); + arg2 = 0; + if (sz > 0) { + arg2 = (uint64_t)(signed char)bae[0]; + for(i=1; iReleaseByteArrayElements(ba, bae, 0); + } + { + try { + (arg1)->setMaxReceivedMessageSize(arg2); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT jint JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_GrpcConfig_1compressAlgorithm(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jint jresult = 0 ; + ppc::protocol::GrpcConfig *arg1 = (ppc::protocol::GrpcConfig *) 0 ; + std::shared_ptr< ppc::protocol::GrpcConfig const > *smartarg1 = 0 ; + int result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< const ppc::protocol::GrpcConfig > **)&jarg1; + arg1 = (ppc::protocol::GrpcConfig *)(smartarg1 ? smartarg1->get() : 0); + { + try { + result = (int)((ppc::protocol::GrpcConfig const *)arg1)->compressAlgorithm(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + jresult = (jint)result; + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_GrpcConfig_1setCompressAlgorithm(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jint jarg2) { + ppc::protocol::GrpcConfig *arg1 = (ppc::protocol::GrpcConfig *) 0 ; + int arg2 ; + std::shared_ptr< ppc::protocol::GrpcConfig > *smartarg1 = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< ppc::protocol::GrpcConfig > **)&jarg1; + arg1 = (ppc::protocol::GrpcConfig *)(smartarg1 ? smartarg1->get() : 0); + arg2 = (int)jarg2; + { + try { + (arg1)->setCompressAlgorithm(arg2); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT jobject JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_GrpcConfig_1maxMsgSize(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jobject jresult = 0 ; + ppc::protocol::GrpcConfig *arg1 = (ppc::protocol::GrpcConfig *) 0 ; + std::shared_ptr< ppc::protocol::GrpcConfig const > *smartarg1 = 0 ; + uint64_t result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< const ppc::protocol::GrpcConfig > **)&jarg1; + arg1 = (ppc::protocol::GrpcConfig *)(smartarg1 ? smartarg1->get() : 0); + { + try { + result = (uint64_t)((ppc::protocol::GrpcConfig const *)arg1)->maxMsgSize(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + { + jbyteArray ba = jenv->NewByteArray(9); + jbyte* bae = jenv->GetByteArrayElements(ba, 0); + jclass clazz = jenv->FindClass("java/math/BigInteger"); + jmethodID mid = jenv->GetMethodID(clazz, "", "([B)V"); + jobject bigint; + int i; + + bae[0] = 0; + for(i=1; i<9; i++ ) { + bae[i] = (jbyte)(result>>8*(8-i)); + } + + jenv->ReleaseByteArrayElements(ba, bae, 0); + bigint = jenv->NewObject(clazz, mid, ba); + jenv->DeleteLocalRef(ba); + jresult = bigint; + } + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_GrpcConfig_1setMaxMsgSize(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jobject jarg2) { + ppc::protocol::GrpcConfig *arg1 = (ppc::protocol::GrpcConfig *) 0 ; + uint64_t arg2 ; + std::shared_ptr< ppc::protocol::GrpcConfig > *smartarg1 = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< ppc::protocol::GrpcConfig > **)&jarg1; + arg1 = (ppc::protocol::GrpcConfig *)(smartarg1 ? smartarg1->get() : 0); + { + jclass clazz; + jmethodID mid; + jbyteArray ba; + jbyte* bae; + jsize sz; + int i; + + if (!jarg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "BigInteger null"); + return ; + } + clazz = jenv->GetObjectClass(jarg2); + mid = jenv->GetMethodID(clazz, "toByteArray", "()[B"); + ba = (jbyteArray)jenv->CallObjectMethod(jarg2, mid); + bae = jenv->GetByteArrayElements(ba, 0); + sz = jenv->GetArrayLength(ba); + arg2 = 0; + if (sz > 0) { + arg2 = (uint64_t)(signed char)bae[0]; + for(i=1; iReleaseByteArrayElements(ba, bae, 0); + } + { + try { + (arg1)->setMaxMsgSize(arg2); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_new_1GrpcServerConfig_1_1SWIG_10(JNIEnv *jenv, jclass jcls) { + jlong jresult = 0 ; + ppc::protocol::GrpcServerConfig *result = 0 ; + + (void)jenv; + (void)jcls; + { + try { + result = (ppc::protocol::GrpcServerConfig *)new ppc::protocol::GrpcServerConfig(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + *(ppc::protocol::GrpcServerConfig **)&jresult = result; + return jresult; +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_new_1GrpcServerConfig_1_1SWIG_11(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jboolean jarg2) { + jlong jresult = 0 ; + ppc::protocol::EndPoint arg1 ; + bool arg2 ; + ppc::protocol::EndPoint *argp1 ; + ppc::protocol::GrpcServerConfig *result = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + argp1 = *(ppc::protocol::EndPoint **)&jarg1; + if (!argp1) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "Attempt to dereference null ppc::protocol::EndPoint"); + return 0; + } + arg1 = *argp1; + arg2 = jarg2 ? true : false; + { + try { + result = (ppc::protocol::GrpcServerConfig *)new ppc::protocol::GrpcServerConfig(arg1,arg2); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + *(ppc::protocol::GrpcServerConfig **)&jresult = result; + return jresult; +} + + +SWIGEXPORT jstring JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_GrpcServerConfig_1listenEndPoint(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jstring jresult = 0 ; + ppc::protocol::GrpcServerConfig *arg1 = (ppc::protocol::GrpcServerConfig *) 0 ; + std::string result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(ppc::protocol::GrpcServerConfig **)&jarg1; + { + try { + result = ((ppc::protocol::GrpcServerConfig const *)arg1)->listenEndPoint(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + jresult = jenv->NewStringUTF((&result)->c_str()); + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_GrpcServerConfig_1setEndPoint(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2, jobject jarg2_) { + ppc::protocol::GrpcServerConfig *arg1 = (ppc::protocol::GrpcServerConfig *) 0 ; + ppc::protocol::EndPoint arg2 ; + ppc::protocol::EndPoint *argp2 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + (void)jarg2_; + arg1 = *(ppc::protocol::GrpcServerConfig **)&jarg1; + argp2 = *(ppc::protocol::EndPoint **)&jarg2; + if (!argp2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "Attempt to dereference null ppc::protocol::EndPoint"); + return ; + } + arg2 = *argp2; + { + try { + (arg1)->setEndPoint(arg2); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_GrpcServerConfig_1setEnableHealthCheck(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jboolean jarg2) { + ppc::protocol::GrpcServerConfig *arg1 = (ppc::protocol::GrpcServerConfig *) 0 ; + bool arg2 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(ppc::protocol::GrpcServerConfig **)&jarg1; + arg2 = jarg2 ? true : false; + { + try { + (arg1)->setEnableHealthCheck(arg2); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_GrpcServerConfig_1endPoint(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jlong jresult = 0 ; + ppc::protocol::GrpcServerConfig *arg1 = (ppc::protocol::GrpcServerConfig *) 0 ; + ppc::protocol::EndPoint *result = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(ppc::protocol::GrpcServerConfig **)&jarg1; + { + try { + result = (ppc::protocol::EndPoint *) &((ppc::protocol::GrpcServerConfig const *)arg1)->endPoint(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + *(ppc::protocol::EndPoint **)&jresult = result; + return jresult; +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_GrpcServerConfig_1mutableEndPoint(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jlong jresult = 0 ; + ppc::protocol::GrpcServerConfig *arg1 = (ppc::protocol::GrpcServerConfig *) 0 ; + ppc::protocol::EndPoint *result = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(ppc::protocol::GrpcServerConfig **)&jarg1; + { + try { + result = (ppc::protocol::EndPoint *) &(arg1)->mutableEndPoint(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + *(ppc::protocol::EndPoint **)&jresult = result; + return jresult; +} + + +SWIGEXPORT jboolean JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_GrpcServerConfig_1enableHealthCheck(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jboolean jresult = 0 ; + ppc::protocol::GrpcServerConfig *arg1 = (ppc::protocol::GrpcServerConfig *) 0 ; + bool result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(ppc::protocol::GrpcServerConfig **)&jarg1; + { + try { + result = (bool)((ppc::protocol::GrpcServerConfig const *)arg1)->enableHealthCheck(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + jresult = (jboolean)result; + return jresult; +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_GrpcServerConfig_1grpcConfig(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jlong jresult = 0 ; + ppc::protocol::GrpcServerConfig *arg1 = (ppc::protocol::GrpcServerConfig *) 0 ; + ppc::protocol::GrpcConfig::Ptr *result = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(ppc::protocol::GrpcServerConfig **)&jarg1; + { + try { + result = (ppc::protocol::GrpcConfig::Ptr *) &((ppc::protocol::GrpcServerConfig const *)arg1)->grpcConfig(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + *(ppc::protocol::GrpcConfig::Ptr **)&jresult = *result ? new ppc::protocol::GrpcConfig::Ptr(*result) : 0; + return jresult; +} + + +SWIGEXPORT jstring JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_printGrpcConfig(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jstring jresult = 0 ; + ppc::protocol::GrpcConfig::Ptr *arg1 = 0 ; + ppc::protocol::GrpcConfig::Ptr tempnull1 ; + std::string result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = jarg1 ? *(ppc::protocol::GrpcConfig::Ptr **)&jarg1 : &tempnull1; + { + try { + result = ppc::protocol::printGrpcConfig((std::shared_ptr< ppc::protocol::GrpcConfig > const &)*arg1); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + jresult = jenv->NewStringUTF((&result)->c_str()); + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_delete_1MessageOptionalHeader(JNIEnv *jenv, jclass jcls, jlong jarg1) { + ppc::protocol::MessageOptionalHeader *arg1 = (ppc::protocol::MessageOptionalHeader *) 0 ; + std::shared_ptr< ppc::protocol::MessageOptionalHeader > *smartarg1 = 0 ; + + (void)jenv; + (void)jcls; + + smartarg1 = *(std::shared_ptr< ppc::protocol::MessageOptionalHeader > **)&jarg1; + arg1 = (ppc::protocol::MessageOptionalHeader *)(smartarg1 ? smartarg1->get() : 0); + { + try { + (void)arg1; delete smartarg1; + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_MessageOptionalHeader_1encode(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2, jobject jarg2_) { + ppc::protocol::MessageOptionalHeader *arg1 = (ppc::protocol::MessageOptionalHeader *) 0 ; + bcos::bytes *arg2 = 0 ; + std::shared_ptr< ppc::protocol::MessageOptionalHeader const > *smartarg1 = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + (void)jarg2_; + + smartarg1 = *(std::shared_ptr< const ppc::protocol::MessageOptionalHeader > **)&jarg1; + arg1 = (ppc::protocol::MessageOptionalHeader *)(smartarg1 ? smartarg1->get() : 0); + + arg2 = (bcos::bytes *)((*(std::shared_ptr< bcos::bytes > **)&jarg2) ? (*(std::shared_ptr< bcos::bytes > **)&jarg2)->get() : 0); + if (!arg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "bcos::bytes & reference is null"); + return ; + } + { + try { + ((ppc::protocol::MessageOptionalHeader const *)arg1)->encode(*arg2); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_MessageOptionalHeader_1decode(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2, jobject jarg3) { + jlong jresult = 0 ; + ppc::protocol::MessageOptionalHeader *arg1 = (ppc::protocol::MessageOptionalHeader *) 0 ; + bcos::bytesConstRef arg2 ; + uint64_t arg3 ; + std::shared_ptr< ppc::protocol::MessageOptionalHeader > *smartarg1 = 0 ; + bcos::bytesConstRef *argp2 ; + int64_t result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< ppc::protocol::MessageOptionalHeader > **)&jarg1; + arg1 = (ppc::protocol::MessageOptionalHeader *)(smartarg1 ? smartarg1->get() : 0); + argp2 = *(bcos::bytesConstRef **)&jarg2; + if (!argp2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "Attempt to dereference null bcos::bytesConstRef"); + return 0; + } + arg2 = *argp2; + { + jclass clazz; + jmethodID mid; + jbyteArray ba; + jbyte* bae; + jsize sz; + int i; + + if (!jarg3) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "BigInteger null"); + return 0; + } + clazz = jenv->GetObjectClass(jarg3); + mid = jenv->GetMethodID(clazz, "toByteArray", "()[B"); + ba = (jbyteArray)jenv->CallObjectMethod(jarg3, mid); + bae = jenv->GetByteArrayElements(ba, 0); + sz = jenv->GetArrayLength(ba); + arg3 = 0; + if (sz > 0) { + arg3 = (uint64_t const)(signed char)bae[0]; + for(i=1; iReleaseByteArrayElements(ba, bae, 0); + } + { + try { + result = (int64_t)(arg1)->decode(arg2,arg3); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + jresult = (jlong)result; + return jresult; +} + + +SWIGEXPORT jstring JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_MessageOptionalHeader_1componentType(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jstring jresult = 0 ; + ppc::protocol::MessageOptionalHeader *arg1 = (ppc::protocol::MessageOptionalHeader *) 0 ; + std::shared_ptr< ppc::protocol::MessageOptionalHeader const > *smartarg1 = 0 ; + std::string result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< const ppc::protocol::MessageOptionalHeader > **)&jarg1; + arg1 = (ppc::protocol::MessageOptionalHeader *)(smartarg1 ? smartarg1->get() : 0); + { + try { + result = ((ppc::protocol::MessageOptionalHeader const *)arg1)->componentType(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + jresult = jenv->NewStringUTF((&result)->c_str()); + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_MessageOptionalHeader_1setComponentType(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jstring jarg2) { + ppc::protocol::MessageOptionalHeader *arg1 = (ppc::protocol::MessageOptionalHeader *) 0 ; + std::string arg2 ; + std::shared_ptr< ppc::protocol::MessageOptionalHeader > *smartarg1 = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< ppc::protocol::MessageOptionalHeader > **)&jarg1; + arg1 = (ppc::protocol::MessageOptionalHeader *)(smartarg1 ? smartarg1->get() : 0); + if(!jarg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null string"); + return ; + } + const char *arg2_pstr = (const char *)jenv->GetStringUTFChars(jarg2, 0); + if (!arg2_pstr) return ; + (&arg2)->assign(arg2_pstr); + jenv->ReleaseStringUTFChars(jarg2, arg2_pstr); + { + try { + (arg1)->setComponentType(arg2); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT jbyteArray JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_MessageOptionalHeader_1srcNodeBuffer(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jbyteArray jresult = 0 ; + ppc::protocol::MessageOptionalHeader *arg1 = (ppc::protocol::MessageOptionalHeader *) 0 ; + std::shared_ptr< ppc::protocol::MessageOptionalHeader const > *smartarg1 = 0 ; + OutputBuffer result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< const ppc::protocol::MessageOptionalHeader > **)&jarg1; + arg1 = (ppc::protocol::MessageOptionalHeader *)(smartarg1 ? smartarg1->get() : 0); + { + try { + result = ((ppc::protocol::MessageOptionalHeader const *)arg1)->srcNodeBuffer(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + { + jresult = jenv->NewByteArray((&result)->len); + jenv->SetByteArrayRegion(jresult, 0, (&result)->len, (jbyte *) (&result)->data); + } + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_MessageOptionalHeader_1setSrcNodeBuffer(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jbyteArray jarg2, jobject jarg3) { + ppc::protocol::MessageOptionalHeader *arg1 = (ppc::protocol::MessageOptionalHeader *) 0 ; + char *arg2 = (char *) 0 ; + uint64_t arg3 ; + std::shared_ptr< ppc::protocol::MessageOptionalHeader > *smartarg1 = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< ppc::protocol::MessageOptionalHeader > **)&jarg1; + arg1 = (ppc::protocol::MessageOptionalHeader *)(smartarg1 ? smartarg1->get() : 0); + { + arg2 = (char *) jenv->GetByteArrayElements(jarg2, 0); + } + { + jclass clazz; + jmethodID mid; + jbyteArray ba; + jbyte* bae; + jsize sz; + int i; + + if (!jarg3) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "BigInteger null"); + return ; + } + clazz = jenv->GetObjectClass(jarg3); + mid = jenv->GetMethodID(clazz, "toByteArray", "()[B"); + ba = (jbyteArray)jenv->CallObjectMethod(jarg3, mid); + bae = jenv->GetByteArrayElements(ba, 0); + sz = jenv->GetArrayLength(ba); + arg3 = 0; + if (sz > 0) { + arg3 = (uint64_t)(signed char)bae[0]; + for(i=1; iReleaseByteArrayElements(ba, bae, 0); + } + { + try { + (arg1)->setSrcNodeBuffer(arg2,arg3); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } + { + jenv->ReleaseByteArrayElements(jarg2, (jbyte *) arg2, 0); + } + +} + + +SWIGEXPORT jbyteArray JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_MessageOptionalHeader_1dstNodeBuffer(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jbyteArray jresult = 0 ; + ppc::protocol::MessageOptionalHeader *arg1 = (ppc::protocol::MessageOptionalHeader *) 0 ; + std::shared_ptr< ppc::protocol::MessageOptionalHeader const > *smartarg1 = 0 ; + OutputBuffer result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< const ppc::protocol::MessageOptionalHeader > **)&jarg1; + arg1 = (ppc::protocol::MessageOptionalHeader *)(smartarg1 ? smartarg1->get() : 0); + { + try { + result = ((ppc::protocol::MessageOptionalHeader const *)arg1)->dstNodeBuffer(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + { + jresult = jenv->NewByteArray((&result)->len); + jenv->SetByteArrayRegion(jresult, 0, (&result)->len, (jbyte *) (&result)->data); + } + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_MessageOptionalHeader_1setDstNodeBuffer(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jbyteArray jarg2, jobject jarg3) { + ppc::protocol::MessageOptionalHeader *arg1 = (ppc::protocol::MessageOptionalHeader *) 0 ; + char *arg2 = (char *) 0 ; + uint64_t arg3 ; + std::shared_ptr< ppc::protocol::MessageOptionalHeader > *smartarg1 = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< ppc::protocol::MessageOptionalHeader > **)&jarg1; + arg1 = (ppc::protocol::MessageOptionalHeader *)(smartarg1 ? smartarg1->get() : 0); + { + arg2 = (char *) jenv->GetByteArrayElements(jarg2, 0); + } + { + jclass clazz; + jmethodID mid; + jbyteArray ba; + jbyte* bae; + jsize sz; + int i; + + if (!jarg3) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "BigInteger null"); + return ; + } + clazz = jenv->GetObjectClass(jarg3); + mid = jenv->GetMethodID(clazz, "toByteArray", "()[B"); + ba = (jbyteArray)jenv->CallObjectMethod(jarg3, mid); + bae = jenv->GetByteArrayElements(ba, 0); + sz = jenv->GetArrayLength(ba); + arg3 = 0; + if (sz > 0) { + arg3 = (uint64_t)(signed char)bae[0]; + for(i=1; iReleaseByteArrayElements(ba, bae, 0); + } + { + try { + (arg1)->setDstNodeBuffer(arg2,arg3); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } + { + jenv->ReleaseByteArrayElements(jarg2, (jbyte *) arg2, 0); + } + +} + + +SWIGEXPORT jstring JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_MessageOptionalHeader_1dstInst(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jstring jresult = 0 ; + ppc::protocol::MessageOptionalHeader *arg1 = (ppc::protocol::MessageOptionalHeader *) 0 ; + std::shared_ptr< ppc::protocol::MessageOptionalHeader const > *smartarg1 = 0 ; + std::string *result = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< const ppc::protocol::MessageOptionalHeader > **)&jarg1; + arg1 = (ppc::protocol::MessageOptionalHeader *)(smartarg1 ? smartarg1->get() : 0); + { + try { + result = (std::string *) &((ppc::protocol::MessageOptionalHeader const *)arg1)->dstInst(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + jresult = jenv->NewStringUTF(result->c_str()); + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_MessageOptionalHeader_1setDstInst(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jstring jarg2) { + ppc::protocol::MessageOptionalHeader *arg1 = (ppc::protocol::MessageOptionalHeader *) 0 ; + std::string *arg2 = 0 ; + std::shared_ptr< ppc::protocol::MessageOptionalHeader > *smartarg1 = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< ppc::protocol::MessageOptionalHeader > **)&jarg1; + arg1 = (ppc::protocol::MessageOptionalHeader *)(smartarg1 ? smartarg1->get() : 0); + if(!jarg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null string"); + return ; + } + const char *arg2_pstr = (const char *)jenv->GetStringUTFChars(jarg2, 0); + if (!arg2_pstr) return ; + std::string arg2_str(arg2_pstr); + arg2 = &arg2_str; + jenv->ReleaseStringUTFChars(jarg2, arg2_pstr); + { + try { + (arg1)->setDstInst((std::string const &)*arg2); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT jstring JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_MessageOptionalHeader_1topic(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jstring jresult = 0 ; + ppc::protocol::MessageOptionalHeader *arg1 = (ppc::protocol::MessageOptionalHeader *) 0 ; + std::shared_ptr< ppc::protocol::MessageOptionalHeader const > *smartarg1 = 0 ; + std::string *result = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< const ppc::protocol::MessageOptionalHeader > **)&jarg1; + arg1 = (ppc::protocol::MessageOptionalHeader *)(smartarg1 ? smartarg1->get() : 0); + { + try { + result = (std::string *) &((ppc::protocol::MessageOptionalHeader const *)arg1)->topic(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + jresult = jenv->NewStringUTF(result->c_str()); + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_MessageOptionalHeader_1setTopic_1_1SWIG_10(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2) { + ppc::protocol::MessageOptionalHeader *arg1 = (ppc::protocol::MessageOptionalHeader *) 0 ; + std::string *arg2 = 0 ; + std::shared_ptr< ppc::protocol::MessageOptionalHeader > *smartarg1 = 0 ; + std::unique_ptr< std::string > rvrdeleter2 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< ppc::protocol::MessageOptionalHeader > **)&jarg1; + arg1 = (ppc::protocol::MessageOptionalHeader *)(smartarg1 ? smartarg1->get() : 0); + arg2 = *(std::string **)&jarg2; + if (!arg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "std::string && is null"); + return ; + } + rvrdeleter2.reset(arg2); + { + try { + (arg1)->setTopic((std::string &&)*arg2); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_MessageOptionalHeader_1setTopic_1_1SWIG_11(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jstring jarg2) { + ppc::protocol::MessageOptionalHeader *arg1 = (ppc::protocol::MessageOptionalHeader *) 0 ; + std::string *arg2 = 0 ; + std::shared_ptr< ppc::protocol::MessageOptionalHeader > *smartarg1 = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< ppc::protocol::MessageOptionalHeader > **)&jarg1; + arg1 = (ppc::protocol::MessageOptionalHeader *)(smartarg1 ? smartarg1->get() : 0); + if(!jarg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null string"); + return ; + } + const char *arg2_pstr = (const char *)jenv->GetStringUTFChars(jarg2, 0); + if (!arg2_pstr) return ; + std::string arg2_str(arg2_pstr); + arg2 = &arg2_str; + jenv->ReleaseStringUTFChars(jarg2, arg2_pstr); + { + try { + (arg1)->setTopic((std::string const &)*arg2); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT jstring JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_MessageOptionalHeader_1srcInst(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jstring jresult = 0 ; + ppc::protocol::MessageOptionalHeader *arg1 = (ppc::protocol::MessageOptionalHeader *) 0 ; + std::shared_ptr< ppc::protocol::MessageOptionalHeader const > *smartarg1 = 0 ; + std::string result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< const ppc::protocol::MessageOptionalHeader > **)&jarg1; + arg1 = (ppc::protocol::MessageOptionalHeader *)(smartarg1 ? smartarg1->get() : 0); + { + try { + result = ((ppc::protocol::MessageOptionalHeader const *)arg1)->srcInst(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + jresult = jenv->NewStringUTF((&result)->c_str()); + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_MessageOptionalHeader_1setSrcInst(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jstring jarg2) { + ppc::protocol::MessageOptionalHeader *arg1 = (ppc::protocol::MessageOptionalHeader *) 0 ; + std::string *arg2 = 0 ; + std::shared_ptr< ppc::protocol::MessageOptionalHeader > *smartarg1 = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< ppc::protocol::MessageOptionalHeader > **)&jarg1; + arg1 = (ppc::protocol::MessageOptionalHeader *)(smartarg1 ? smartarg1->get() : 0); + if(!jarg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null string"); + return ; + } + const char *arg2_pstr = (const char *)jenv->GetStringUTFChars(jarg2, 0); + if (!arg2_pstr) return ; + std::string arg2_str(arg2_pstr); + arg2 = &arg2_str; + jenv->ReleaseStringUTFChars(jarg2, arg2_pstr); + { + try { + (arg1)->setSrcInst((std::string const &)*arg2); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_delete_1MessageHeader(JNIEnv *jenv, jclass jcls, jlong jarg1) { + ppc::protocol::MessageHeader *arg1 = (ppc::protocol::MessageHeader *) 0 ; + std::shared_ptr< ppc::protocol::MessageHeader > *smartarg1 = 0 ; + + (void)jenv; + (void)jcls; + + smartarg1 = *(std::shared_ptr< ppc::protocol::MessageHeader > **)&jarg1; + arg1 = (ppc::protocol::MessageHeader *)(smartarg1 ? smartarg1->get() : 0); + { + try { + (void)arg1; delete smartarg1; + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_MessageHeader_1encode(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2, jobject jarg2_) { + ppc::protocol::MessageHeader *arg1 = (ppc::protocol::MessageHeader *) 0 ; + bcos::bytes *arg2 = 0 ; + std::shared_ptr< ppc::protocol::MessageHeader const > *smartarg1 = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + (void)jarg2_; + + smartarg1 = *(std::shared_ptr< const ppc::protocol::MessageHeader > **)&jarg1; + arg1 = (ppc::protocol::MessageHeader *)(smartarg1 ? smartarg1->get() : 0); + + arg2 = (bcos::bytes *)((*(std::shared_ptr< bcos::bytes > **)&jarg2) ? (*(std::shared_ptr< bcos::bytes > **)&jarg2)->get() : 0); + if (!arg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "bcos::bytes & reference is null"); + return ; + } + { + try { + ((ppc::protocol::MessageHeader const *)arg1)->encode(*arg2); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_MessageHeader_1decode(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2) { + jlong jresult = 0 ; + ppc::protocol::MessageHeader *arg1 = (ppc::protocol::MessageHeader *) 0 ; + bcos::bytesConstRef arg2 ; + std::shared_ptr< ppc::protocol::MessageHeader > *smartarg1 = 0 ; + bcos::bytesConstRef *argp2 ; + int64_t result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< ppc::protocol::MessageHeader > **)&jarg1; + arg1 = (ppc::protocol::MessageHeader *)(smartarg1 ? smartarg1->get() : 0); + argp2 = *(bcos::bytesConstRef **)&jarg2; + if (!argp2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "Attempt to dereference null bcos::bytesConstRef"); + return 0; + } + arg2 = *argp2; + { + try { + result = (int64_t)(arg1)->decode(arg2); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + jresult = (jlong)result; + return jresult; +} + + +SWIGEXPORT jshort JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_MessageHeader_1version(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jshort jresult = 0 ; + ppc::protocol::MessageHeader *arg1 = (ppc::protocol::MessageHeader *) 0 ; + std::shared_ptr< ppc::protocol::MessageHeader const > *smartarg1 = 0 ; + uint8_t result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< const ppc::protocol::MessageHeader > **)&jarg1; + arg1 = (ppc::protocol::MessageHeader *)(smartarg1 ? smartarg1->get() : 0); + { + try { + result = (uint8_t)((ppc::protocol::MessageHeader const *)arg1)->version(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + jresult = (jshort)result; + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_MessageHeader_1setVersion(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jint jarg2) { + ppc::protocol::MessageHeader *arg1 = (ppc::protocol::MessageHeader *) 0 ; + uint16_t arg2 ; + std::shared_ptr< ppc::protocol::MessageHeader > *smartarg1 = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< ppc::protocol::MessageHeader > **)&jarg1; + arg1 = (ppc::protocol::MessageHeader *)(smartarg1 ? smartarg1->get() : 0); + arg2 = (uint16_t)jarg2; + { + try { + (arg1)->setVersion(arg2); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT jstring JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_MessageHeader_1traceID(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jstring jresult = 0 ; + ppc::protocol::MessageHeader *arg1 = (ppc::protocol::MessageHeader *) 0 ; + std::shared_ptr< ppc::protocol::MessageHeader const > *smartarg1 = 0 ; + std::string *result = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< const ppc::protocol::MessageHeader > **)&jarg1; + arg1 = (ppc::protocol::MessageHeader *)(smartarg1 ? smartarg1->get() : 0); + { + try { + result = (std::string *) &((ppc::protocol::MessageHeader const *)arg1)->traceID(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + jresult = jenv->NewStringUTF(result->c_str()); + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_MessageHeader_1setTraceID(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jstring jarg2) { + ppc::protocol::MessageHeader *arg1 = (ppc::protocol::MessageHeader *) 0 ; + std::string arg2 ; + std::shared_ptr< ppc::protocol::MessageHeader > *smartarg1 = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< ppc::protocol::MessageHeader > **)&jarg1; + arg1 = (ppc::protocol::MessageHeader *)(smartarg1 ? smartarg1->get() : 0); + if(!jarg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null string"); + return ; + } + const char *arg2_pstr = (const char *)jenv->GetStringUTFChars(jarg2, 0); + if (!arg2_pstr) return ; + (&arg2)->assign(arg2_pstr); + jenv->ReleaseStringUTFChars(jarg2, arg2_pstr); + { + try { + (arg1)->setTraceID(arg2); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT jstring JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_MessageHeader_1srcGwNode(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jstring jresult = 0 ; + ppc::protocol::MessageHeader *arg1 = (ppc::protocol::MessageHeader *) 0 ; + std::shared_ptr< ppc::protocol::MessageHeader const > *smartarg1 = 0 ; + std::string *result = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< const ppc::protocol::MessageHeader > **)&jarg1; + arg1 = (ppc::protocol::MessageHeader *)(smartarg1 ? smartarg1->get() : 0); + { + try { + result = (std::string *) &((ppc::protocol::MessageHeader const *)arg1)->srcGwNode(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + jresult = jenv->NewStringUTF(result->c_str()); + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_MessageHeader_1setSrcGwNode(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jstring jarg2) { + ppc::protocol::MessageHeader *arg1 = (ppc::protocol::MessageHeader *) 0 ; + std::string *arg2 = 0 ; + std::shared_ptr< ppc::protocol::MessageHeader > *smartarg1 = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< ppc::protocol::MessageHeader > **)&jarg1; + arg1 = (ppc::protocol::MessageHeader *)(smartarg1 ? smartarg1->get() : 0); + if(!jarg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null string"); + return ; + } + const char *arg2_pstr = (const char *)jenv->GetStringUTFChars(jarg2, 0); + if (!arg2_pstr) return ; + std::string arg2_str(arg2_pstr); + arg2 = &arg2_str; + jenv->ReleaseStringUTFChars(jarg2, arg2_pstr); + { + try { + (arg1)->setSrcGwNode((std::string const &)*arg2); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT jstring JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_MessageHeader_1dstGwNode(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jstring jresult = 0 ; + ppc::protocol::MessageHeader *arg1 = (ppc::protocol::MessageHeader *) 0 ; + std::shared_ptr< ppc::protocol::MessageHeader const > *smartarg1 = 0 ; + std::string *result = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< const ppc::protocol::MessageHeader > **)&jarg1; + arg1 = (ppc::protocol::MessageHeader *)(smartarg1 ? smartarg1->get() : 0); + { + try { + result = (std::string *) &((ppc::protocol::MessageHeader const *)arg1)->dstGwNode(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + jresult = jenv->NewStringUTF(result->c_str()); + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_MessageHeader_1setDstGwNode(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jstring jarg2) { + ppc::protocol::MessageHeader *arg1 = (ppc::protocol::MessageHeader *) 0 ; + std::string *arg2 = 0 ; + std::shared_ptr< ppc::protocol::MessageHeader > *smartarg1 = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< ppc::protocol::MessageHeader > **)&jarg1; + arg1 = (ppc::protocol::MessageHeader *)(smartarg1 ? smartarg1->get() : 0); + if(!jarg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null string"); + return ; + } + const char *arg2_pstr = (const char *)jenv->GetStringUTFChars(jarg2, 0); + if (!arg2_pstr) return ; + std::string arg2_str(arg2_pstr); + arg2 = &arg2_str; + jenv->ReleaseStringUTFChars(jarg2, arg2_pstr); + { + try { + (arg1)->setDstGwNode((std::string const &)*arg2); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT jint JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_MessageHeader_1packetType(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jint jresult = 0 ; + ppc::protocol::MessageHeader *arg1 = (ppc::protocol::MessageHeader *) 0 ; + std::shared_ptr< ppc::protocol::MessageHeader const > *smartarg1 = 0 ; + uint16_t result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< const ppc::protocol::MessageHeader > **)&jarg1; + arg1 = (ppc::protocol::MessageHeader *)(smartarg1 ? smartarg1->get() : 0); + { + try { + result = (uint16_t)((ppc::protocol::MessageHeader const *)arg1)->packetType(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + jresult = (jint)result; + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_MessageHeader_1setPacketType(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jint jarg2) { + ppc::protocol::MessageHeader *arg1 = (ppc::protocol::MessageHeader *) 0 ; + uint16_t arg2 ; + std::shared_ptr< ppc::protocol::MessageHeader > *smartarg1 = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< ppc::protocol::MessageHeader > **)&jarg1; + arg1 = (ppc::protocol::MessageHeader *)(smartarg1 ? smartarg1->get() : 0); + arg2 = (uint16_t)jarg2; + { + try { + (arg1)->setPacketType(arg2); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT jshort JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_MessageHeader_1ttl(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jshort jresult = 0 ; + ppc::protocol::MessageHeader *arg1 = (ppc::protocol::MessageHeader *) 0 ; + std::shared_ptr< ppc::protocol::MessageHeader const > *smartarg1 = 0 ; + int16_t result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< const ppc::protocol::MessageHeader > **)&jarg1; + arg1 = (ppc::protocol::MessageHeader *)(smartarg1 ? smartarg1->get() : 0); + { + try { + result = (int16_t)((ppc::protocol::MessageHeader const *)arg1)->ttl(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + jresult = (jshort)result; + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_MessageHeader_1setTTL(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jint jarg2) { + ppc::protocol::MessageHeader *arg1 = (ppc::protocol::MessageHeader *) 0 ; + uint16_t arg2 ; + std::shared_ptr< ppc::protocol::MessageHeader > *smartarg1 = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< ppc::protocol::MessageHeader > **)&jarg1; + arg1 = (ppc::protocol::MessageHeader *)(smartarg1 ? smartarg1->get() : 0); + arg2 = (uint16_t)jarg2; + { + try { + (arg1)->setTTL(arg2); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT jint JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_MessageHeader_1ext(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jint jresult = 0 ; + ppc::protocol::MessageHeader *arg1 = (ppc::protocol::MessageHeader *) 0 ; + std::shared_ptr< ppc::protocol::MessageHeader const > *smartarg1 = 0 ; + uint16_t result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< const ppc::protocol::MessageHeader > **)&jarg1; + arg1 = (ppc::protocol::MessageHeader *)(smartarg1 ? smartarg1->get() : 0); + { + try { + result = (uint16_t)((ppc::protocol::MessageHeader const *)arg1)->ext(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + jresult = (jint)result; + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_MessageHeader_1setExt(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jint jarg2) { + ppc::protocol::MessageHeader *arg1 = (ppc::protocol::MessageHeader *) 0 ; + uint16_t arg2 ; + std::shared_ptr< ppc::protocol::MessageHeader > *smartarg1 = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< ppc::protocol::MessageHeader > **)&jarg1; + arg1 = (ppc::protocol::MessageHeader *)(smartarg1 ? smartarg1->get() : 0); + arg2 = (uint16_t)jarg2; + { + try { + (arg1)->setExt(arg2); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_MessageHeader_1optionalField(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jlong jresult = 0 ; + ppc::protocol::MessageHeader *arg1 = (ppc::protocol::MessageHeader *) 0 ; + std::shared_ptr< ppc::protocol::MessageHeader const > *smartarg1 = 0 ; + ppc::protocol::MessageOptionalHeader::Ptr result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< const ppc::protocol::MessageHeader > **)&jarg1; + arg1 = (ppc::protocol::MessageHeader *)(smartarg1 ? smartarg1->get() : 0); + { + try { + result = ((ppc::protocol::MessageHeader const *)arg1)->optionalField(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + *(ppc::protocol::MessageOptionalHeader::Ptr **)&jresult = result ? new ppc::protocol::MessageOptionalHeader::Ptr(result) : 0; + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_MessageHeader_1setOptionalField(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2, jobject jarg2_) { + ppc::protocol::MessageHeader *arg1 = (ppc::protocol::MessageHeader *) 0 ; + ppc::protocol::MessageOptionalHeader::Ptr arg2 ; + std::shared_ptr< ppc::protocol::MessageHeader > *smartarg1 = 0 ; + ppc::protocol::MessageOptionalHeader::Ptr *argp2 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + (void)jarg2_; + + smartarg1 = *(std::shared_ptr< ppc::protocol::MessageHeader > **)&jarg1; + arg1 = (ppc::protocol::MessageHeader *)(smartarg1 ? smartarg1->get() : 0); + argp2 = *(ppc::protocol::MessageOptionalHeader::Ptr **)&jarg2; + if (argp2) arg2 = *argp2; + { + try { + (arg1)->setOptionalField(arg2); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT jint JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_MessageHeader_1length(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jint jresult = 0 ; + ppc::protocol::MessageHeader *arg1 = (ppc::protocol::MessageHeader *) 0 ; + std::shared_ptr< ppc::protocol::MessageHeader const > *smartarg1 = 0 ; + uint16_t result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< const ppc::protocol::MessageHeader > **)&jarg1; + arg1 = (ppc::protocol::MessageHeader *)(smartarg1 ? smartarg1->get() : 0); + { + try { + result = (uint16_t)((ppc::protocol::MessageHeader const *)arg1)->length(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + jresult = (jint)result; + return jresult; +} + + +SWIGEXPORT jboolean JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_MessageHeader_1isRespPacket(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jboolean jresult = 0 ; + ppc::protocol::MessageHeader *arg1 = (ppc::protocol::MessageHeader *) 0 ; + std::shared_ptr< ppc::protocol::MessageHeader const > *smartarg1 = 0 ; + bool result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< const ppc::protocol::MessageHeader > **)&jarg1; + arg1 = (ppc::protocol::MessageHeader *)(smartarg1 ? smartarg1->get() : 0); + { + try { + result = (bool)((ppc::protocol::MessageHeader const *)arg1)->isRespPacket(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + jresult = (jboolean)result; + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_MessageHeader_1setRespPacket(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + ppc::protocol::MessageHeader *arg1 = (ppc::protocol::MessageHeader *) 0 ; + std::shared_ptr< ppc::protocol::MessageHeader > *smartarg1 = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< ppc::protocol::MessageHeader > **)&jarg1; + arg1 = (ppc::protocol::MessageHeader *)(smartarg1 ? smartarg1->get() : 0); + { + try { + (arg1)->setRespPacket(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_MessageHeader_1srcP2PNodeIDView(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jlong jresult = 0 ; + ppc::protocol::MessageHeader *arg1 = (ppc::protocol::MessageHeader *) 0 ; + std::shared_ptr< ppc::protocol::MessageHeader const > *smartarg1 = 0 ; + std::string_view result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< const ppc::protocol::MessageHeader > **)&jarg1; + arg1 = (ppc::protocol::MessageHeader *)(smartarg1 ? smartarg1->get() : 0); + { + try { + result = ((ppc::protocol::MessageHeader const *)arg1)->srcP2PNodeIDView(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + *(std::string_view **)&jresult = new std::string_view(result); + return jresult; +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_MessageHeader_1dstP2PNodeIDView(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jlong jresult = 0 ; + ppc::protocol::MessageHeader *arg1 = (ppc::protocol::MessageHeader *) 0 ; + std::shared_ptr< ppc::protocol::MessageHeader const > *smartarg1 = 0 ; + std::string_view result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< const ppc::protocol::MessageHeader > **)&jarg1; + arg1 = (ppc::protocol::MessageHeader *)(smartarg1 ? smartarg1->get() : 0); + { + try { + result = ((ppc::protocol::MessageHeader const *)arg1)->dstP2PNodeIDView(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + *(std::string_view **)&jresult = new std::string_view(result); + return jresult; +} + + +SWIGEXPORT jint JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_MessageHeader_1routeType(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jint jresult = 0 ; + ppc::protocol::MessageHeader *arg1 = (ppc::protocol::MessageHeader *) 0 ; + std::shared_ptr< ppc::protocol::MessageHeader const > *smartarg1 = 0 ; + uint16_t result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< const ppc::protocol::MessageHeader > **)&jarg1; + arg1 = (ppc::protocol::MessageHeader *)(smartarg1 ? smartarg1->get() : 0); + { + try { + result = (uint16_t)((ppc::protocol::MessageHeader const *)arg1)->routeType(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + jresult = (jint)result; + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_MessageHeader_1setRouteType(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2) { + ppc::protocol::MessageHeader *arg1 = (ppc::protocol::MessageHeader *) 0 ; + ppc::protocol::RouteType arg2 ; + std::shared_ptr< ppc::protocol::MessageHeader > *smartarg1 = 0 ; + ppc::protocol::RouteType *argp2 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< ppc::protocol::MessageHeader > **)&jarg1; + arg1 = (ppc::protocol::MessageHeader *)(smartarg1 ? smartarg1->get() : 0); + argp2 = *(ppc::protocol::RouteType **)&jarg2; + if (!argp2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "Attempt to dereference null ppc::protocol::RouteType"); + return ; + } + arg2 = *argp2; + { + try { + (arg1)->setRouteType(arg2); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT jboolean JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_MessageHeader_1hasOptionalField(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jboolean jresult = 0 ; + ppc::protocol::MessageHeader *arg1 = (ppc::protocol::MessageHeader *) 0 ; + std::shared_ptr< ppc::protocol::MessageHeader const > *smartarg1 = 0 ; + bool result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< const ppc::protocol::MessageHeader > **)&jarg1; + arg1 = (ppc::protocol::MessageHeader *)(smartarg1 ? smartarg1->get() : 0); + { + try { + result = (bool)((ppc::protocol::MessageHeader const *)arg1)->hasOptionalField(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + jresult = (jboolean)result; + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_delete_1Message(JNIEnv *jenv, jclass jcls, jlong jarg1) { + ppc::protocol::Message *arg1 = (ppc::protocol::Message *) 0 ; + std::shared_ptr< ppc::protocol::Message > *smartarg1 = 0 ; + + (void)jenv; + (void)jcls; + + smartarg1 = *(std::shared_ptr< ppc::protocol::Message > **)&jarg1; + arg1 = (ppc::protocol::Message *)(smartarg1 ? smartarg1->get() : 0); + { + try { + (void)arg1; delete smartarg1; + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_Message_1header(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jlong jresult = 0 ; + ppc::protocol::Message *arg1 = (ppc::protocol::Message *) 0 ; + std::shared_ptr< ppc::protocol::Message const > *smartarg1 = 0 ; + ppc::protocol::MessageHeader::Ptr result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< const ppc::protocol::Message > **)&jarg1; + arg1 = (ppc::protocol::Message *)(smartarg1 ? smartarg1->get() : 0); + { + try { + result = ((ppc::protocol::Message const *)arg1)->header(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + *(ppc::protocol::MessageHeader::Ptr **)&jresult = result ? new ppc::protocol::MessageHeader::Ptr(result) : 0; + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_Message_1setHeader(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2, jobject jarg2_) { + ppc::protocol::Message *arg1 = (ppc::protocol::Message *) 0 ; + ppc::protocol::MessageHeader::Ptr arg2 ; + std::shared_ptr< ppc::protocol::Message > *smartarg1 = 0 ; + ppc::protocol::MessageHeader::Ptr *argp2 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + (void)jarg2_; + + smartarg1 = *(std::shared_ptr< ppc::protocol::Message > **)&jarg1; + arg1 = (ppc::protocol::Message *)(smartarg1 ? smartarg1->get() : 0); + argp2 = *(ppc::protocol::MessageHeader::Ptr **)&jarg2; + if (argp2) arg2 = *argp2; + { + try { + (arg1)->setHeader(arg2); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT jint JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_Message_1version(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jint jresult = 0 ; + ppc::protocol::Message *arg1 = (ppc::protocol::Message *) 0 ; + std::shared_ptr< ppc::protocol::Message const > *smartarg1 = 0 ; + uint16_t result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< const ppc::protocol::Message > **)&jarg1; + arg1 = (ppc::protocol::Message *)(smartarg1 ? smartarg1->get() : 0); + { + try { + result = (uint16_t)((ppc::protocol::Message const *)arg1)->version(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + jresult = (jint)result; + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_Message_1setVersion(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jint jarg2) { + ppc::protocol::Message *arg1 = (ppc::protocol::Message *) 0 ; + uint16_t arg2 ; + std::shared_ptr< ppc::protocol::Message > *smartarg1 = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< ppc::protocol::Message > **)&jarg1; + arg1 = (ppc::protocol::Message *)(smartarg1 ? smartarg1->get() : 0); + arg2 = (uint16_t)jarg2; + { + try { + (arg1)->setVersion(arg2); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT jint JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_Message_1packetType(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jint jresult = 0 ; + ppc::protocol::Message *arg1 = (ppc::protocol::Message *) 0 ; + std::shared_ptr< ppc::protocol::Message const > *smartarg1 = 0 ; + uint16_t result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< const ppc::protocol::Message > **)&jarg1; + arg1 = (ppc::protocol::Message *)(smartarg1 ? smartarg1->get() : 0); + { + try { + result = (uint16_t)((ppc::protocol::Message const *)arg1)->packetType(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + jresult = (jint)result; + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_Message_1setPacketType(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jint jarg2) { + ppc::protocol::Message *arg1 = (ppc::protocol::Message *) 0 ; + uint16_t arg2 ; + std::shared_ptr< ppc::protocol::Message > *smartarg1 = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< ppc::protocol::Message > **)&jarg1; + arg1 = (ppc::protocol::Message *)(smartarg1 ? smartarg1->get() : 0); + arg2 = (uint16_t)jarg2; + { + try { + (arg1)->setPacketType(arg2); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT jstring JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_Message_1seq(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jstring jresult = 0 ; + ppc::protocol::Message *arg1 = (ppc::protocol::Message *) 0 ; + std::shared_ptr< ppc::protocol::Message const > *smartarg1 = 0 ; + std::string *result = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< const ppc::protocol::Message > **)&jarg1; + arg1 = (ppc::protocol::Message *)(smartarg1 ? smartarg1->get() : 0); + { + try { + result = (std::string *) &((ppc::protocol::Message const *)arg1)->seq(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + jresult = jenv->NewStringUTF(result->c_str()); + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_Message_1setSeq(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jstring jarg2) { + ppc::protocol::Message *arg1 = (ppc::protocol::Message *) 0 ; + std::string arg2 ; + std::shared_ptr< ppc::protocol::Message > *smartarg1 = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< ppc::protocol::Message > **)&jarg1; + arg1 = (ppc::protocol::Message *)(smartarg1 ? smartarg1->get() : 0); + if(!jarg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null string"); + return ; + } + const char *arg2_pstr = (const char *)jenv->GetStringUTFChars(jarg2, 0); + if (!arg2_pstr) return ; + (&arg2)->assign(arg2_pstr); + jenv->ReleaseStringUTFChars(jarg2, arg2_pstr); + { + try { + (arg1)->setSeq(arg2); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT jint JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_Message_1ext(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jint jresult = 0 ; + ppc::protocol::Message *arg1 = (ppc::protocol::Message *) 0 ; + std::shared_ptr< ppc::protocol::Message const > *smartarg1 = 0 ; + uint16_t result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< const ppc::protocol::Message > **)&jarg1; + arg1 = (ppc::protocol::Message *)(smartarg1 ? smartarg1->get() : 0); + { + try { + result = (uint16_t)((ppc::protocol::Message const *)arg1)->ext(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + jresult = (jint)result; + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_Message_1setExt(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jint jarg2) { + ppc::protocol::Message *arg1 = (ppc::protocol::Message *) 0 ; + uint16_t arg2 ; + std::shared_ptr< ppc::protocol::Message > *smartarg1 = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< ppc::protocol::Message > **)&jarg1; + arg1 = (ppc::protocol::Message *)(smartarg1 ? smartarg1->get() : 0); + arg2 = (uint16_t)jarg2; + { + try { + (arg1)->setExt(arg2); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT jboolean JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_Message_1isRespPacket(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jboolean jresult = 0 ; + ppc::protocol::Message *arg1 = (ppc::protocol::Message *) 0 ; + std::shared_ptr< ppc::protocol::Message const > *smartarg1 = 0 ; + bool result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< const ppc::protocol::Message > **)&jarg1; + arg1 = (ppc::protocol::Message *)(smartarg1 ? smartarg1->get() : 0); + { + try { + result = (bool)((ppc::protocol::Message const *)arg1)->isRespPacket(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + jresult = (jboolean)result; + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_Message_1setRespPacket(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + ppc::protocol::Message *arg1 = (ppc::protocol::Message *) 0 ; + std::shared_ptr< ppc::protocol::Message > *smartarg1 = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< ppc::protocol::Message > **)&jarg1; + arg1 = (ppc::protocol::Message *)(smartarg1 ? smartarg1->get() : 0); + { + try { + (arg1)->setRespPacket(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_Message_1setPayload(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2, jobject jarg2_) { + ppc::protocol::Message *arg1 = (ppc::protocol::Message *) 0 ; + std::shared_ptr< bcos::bytes > arg2 ; + std::shared_ptr< ppc::protocol::Message > *smartarg1 = 0 ; + std::shared_ptr< bcos::bytes > *argp2 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + (void)jarg2_; + + smartarg1 = *(std::shared_ptr< ppc::protocol::Message > **)&jarg1; + arg1 = (ppc::protocol::Message *)(smartarg1 ? smartarg1->get() : 0); + argp2 = *(std::shared_ptr< bcos::bytes > **)&jarg2; + if (argp2) arg2 = *argp2; + { + try { + (arg1)->setPayload(arg2); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT jbyteArray JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_Message_1payloadBuffer(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jbyteArray jresult = 0 ; + ppc::protocol::Message *arg1 = (ppc::protocol::Message *) 0 ; + std::shared_ptr< ppc::protocol::Message const > *smartarg1 = 0 ; + OutputBuffer result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< const ppc::protocol::Message > **)&jarg1; + arg1 = (ppc::protocol::Message *)(smartarg1 ? smartarg1->get() : 0); + { + try { + result = ((ppc::protocol::Message const *)arg1)->payloadBuffer(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + { + jresult = jenv->NewByteArray((&result)->len); + jenv->SetByteArrayRegion(jresult, 0, (&result)->len, (jbyte *) (&result)->data); + } + return jresult; +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_Message_1frontMessage(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jlong jresult = 0 ; + ppc::protocol::Message *arg1 = (ppc::protocol::Message *) 0 ; + std::shared_ptr< ppc::protocol::Message const > *smartarg1 = 0 ; + ppc::protocol::MessagePayload::Ptr *result = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< const ppc::protocol::Message > **)&jarg1; + arg1 = (ppc::protocol::Message *)(smartarg1 ? smartarg1->get() : 0); + { + try { + result = (ppc::protocol::MessagePayload::Ptr *) &((ppc::protocol::Message const *)arg1)->frontMessage(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + *(ppc::protocol::MessagePayload::Ptr **)&jresult = *result ? new ppc::protocol::MessagePayload::Ptr(*result) : 0; + return jresult; +} + + +SWIGEXPORT jboolean JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_Message_1encode(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2, jobject jarg2_) { + jboolean jresult = 0 ; + ppc::protocol::Message *arg1 = (ppc::protocol::Message *) 0 ; + bcos::bytes *arg2 = 0 ; + std::shared_ptr< ppc::protocol::Message > *smartarg1 = 0 ; + bool result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + (void)jarg2_; + + smartarg1 = *(std::shared_ptr< ppc::protocol::Message > **)&jarg1; + arg1 = (ppc::protocol::Message *)(smartarg1 ? smartarg1->get() : 0); + + arg2 = (bcos::bytes *)((*(std::shared_ptr< bcos::bytes > **)&jarg2) ? (*(std::shared_ptr< bcos::bytes > **)&jarg2)->get() : 0); + if (!arg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "bcos::bytes & reference is null"); + return 0; + } + { + try { + result = (bool)(arg1)->encode(*arg2); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + jresult = (jboolean)result; + return jresult; +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_Message_1decode(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2) { + jlong jresult = 0 ; + ppc::protocol::Message *arg1 = (ppc::protocol::Message *) 0 ; + bcos::bytesConstRef arg2 ; + std::shared_ptr< ppc::protocol::Message > *smartarg1 = 0 ; + bcos::bytesConstRef *argp2 ; + int64_t result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< ppc::protocol::Message > **)&jarg1; + arg1 = (ppc::protocol::Message *)(smartarg1 ? smartarg1->get() : 0); + argp2 = *(bcos::bytesConstRef **)&jarg2; + if (!argp2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "Attempt to dereference null bcos::bytesConstRef"); + return 0; + } + arg2 = *argp2; + { + try { + result = (int64_t)(arg1)->decode(arg2); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + jresult = (jlong)result; + return jresult; +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_Message_1length(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jlong jresult = 0 ; + ppc::protocol::Message *arg1 = (ppc::protocol::Message *) 0 ; + std::shared_ptr< ppc::protocol::Message const > *smartarg1 = 0 ; + uint32_t result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< const ppc::protocol::Message > **)&jarg1; + arg1 = (ppc::protocol::Message *)(smartarg1 ? smartarg1->get() : 0); + { + try { + result = (uint32_t)((ppc::protocol::Message const *)arg1)->length(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + jresult = (jlong)result; + return jresult; +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_Message_1payload(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jlong jresult = 0 ; + ppc::protocol::Message *arg1 = (ppc::protocol::Message *) 0 ; + std::shared_ptr< ppc::protocol::Message const > *smartarg1 = 0 ; + std::shared_ptr< bcos::bytes > result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< const ppc::protocol::Message > **)&jarg1; + arg1 = (ppc::protocol::Message *)(smartarg1 ? smartarg1->get() : 0); + { + try { + result = ((ppc::protocol::Message const *)arg1)->payload(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + *(std::shared_ptr< bcos::bytes > **)&jresult = result ? new std::shared_ptr< bcos::bytes >(result) : 0; + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_Message_1releasePayload(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + ppc::protocol::Message *arg1 = (ppc::protocol::Message *) 0 ; + std::shared_ptr< ppc::protocol::Message > *smartarg1 = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< ppc::protocol::Message > **)&jarg1; + arg1 = (ppc::protocol::Message *)(smartarg1 ? smartarg1->get() : 0); + { + try { + (arg1)->releasePayload(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_delete_1MessageHeaderBuilder(JNIEnv *jenv, jclass jcls, jlong jarg1) { + ppc::protocol::MessageHeaderBuilder *arg1 = (ppc::protocol::MessageHeaderBuilder *) 0 ; + std::shared_ptr< ppc::protocol::MessageHeaderBuilder > *smartarg1 = 0 ; + + (void)jenv; + (void)jcls; + + smartarg1 = *(std::shared_ptr< ppc::protocol::MessageHeaderBuilder > **)&jarg1; + arg1 = (ppc::protocol::MessageHeaderBuilder *)(smartarg1 ? smartarg1->get() : 0); + { + try { + (void)arg1; delete smartarg1; + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_MessageHeaderBuilder_1build_1_1SWIG_10(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2) { + jlong jresult = 0 ; + ppc::protocol::MessageHeaderBuilder *arg1 = (ppc::protocol::MessageHeaderBuilder *) 0 ; + bcos::bytesConstRef arg2 ; + std::shared_ptr< ppc::protocol::MessageHeaderBuilder > *smartarg1 = 0 ; + bcos::bytesConstRef *argp2 ; + ppc::protocol::MessageHeader::Ptr result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< ppc::protocol::MessageHeaderBuilder > **)&jarg1; + arg1 = (ppc::protocol::MessageHeaderBuilder *)(smartarg1 ? smartarg1->get() : 0); + argp2 = *(bcos::bytesConstRef **)&jarg2; + if (!argp2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "Attempt to dereference null bcos::bytesConstRef"); + return 0; + } + arg2 = *argp2; + { + try { + result = (arg1)->build(arg2); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + *(ppc::protocol::MessageHeader::Ptr **)&jresult = result ? new ppc::protocol::MessageHeader::Ptr(result) : 0; + return jresult; +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_MessageHeaderBuilder_1build_1_1SWIG_11(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jlong jresult = 0 ; + ppc::protocol::MessageHeaderBuilder *arg1 = (ppc::protocol::MessageHeaderBuilder *) 0 ; + std::shared_ptr< ppc::protocol::MessageHeaderBuilder > *smartarg1 = 0 ; + ppc::protocol::MessageHeader::Ptr result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< ppc::protocol::MessageHeaderBuilder > **)&jarg1; + arg1 = (ppc::protocol::MessageHeaderBuilder *)(smartarg1 ? smartarg1->get() : 0); + { + try { + result = (arg1)->build(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + *(ppc::protocol::MessageHeader::Ptr **)&jresult = result ? new ppc::protocol::MessageHeader::Ptr(result) : 0; + return jresult; +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_MessageHeaderBuilder_1build_1_1SWIG_12(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2, jobject jarg2_) { + jlong jresult = 0 ; + ppc::protocol::MessageHeaderBuilder *arg1 = (ppc::protocol::MessageHeaderBuilder *) 0 ; + ppc::protocol::MessageOptionalHeader::Ptr *arg2 = 0 ; + std::shared_ptr< ppc::protocol::MessageHeaderBuilder > *smartarg1 = 0 ; + ppc::protocol::MessageOptionalHeader::Ptr tempnull2 ; + ppc::protocol::MessageOptionalHeader::Ptr result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + (void)jarg2_; + + smartarg1 = *(std::shared_ptr< ppc::protocol::MessageHeaderBuilder > **)&jarg1; + arg1 = (ppc::protocol::MessageHeaderBuilder *)(smartarg1 ? smartarg1->get() : 0); + arg2 = jarg2 ? *(ppc::protocol::MessageOptionalHeader::Ptr **)&jarg2 : &tempnull2; + { + try { + result = (arg1)->build((ppc::protocol::MessageOptionalHeader::Ptr const &)*arg2); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + *(ppc::protocol::MessageOptionalHeader::Ptr **)&jresult = result ? new ppc::protocol::MessageOptionalHeader::Ptr(result) : 0; + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_delete_1MessageBuilder(JNIEnv *jenv, jclass jcls, jlong jarg1) { + ppc::protocol::MessageBuilder *arg1 = (ppc::protocol::MessageBuilder *) 0 ; + std::shared_ptr< ppc::protocol::MessageBuilder > *smartarg1 = 0 ; + + (void)jenv; + (void)jcls; + + smartarg1 = *(std::shared_ptr< ppc::protocol::MessageBuilder > **)&jarg1; + arg1 = (ppc::protocol::MessageBuilder *)(smartarg1 ? smartarg1->get() : 0); + { + try { + (void)arg1; delete smartarg1; + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_MessageBuilder_1build_1_1SWIG_10(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jlong jresult = 0 ; + ppc::protocol::MessageBuilder *arg1 = (ppc::protocol::MessageBuilder *) 0 ; + std::shared_ptr< ppc::protocol::MessageBuilder > *smartarg1 = 0 ; + ppc::protocol::Message::Ptr result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< ppc::protocol::MessageBuilder > **)&jarg1; + arg1 = (ppc::protocol::MessageBuilder *)(smartarg1 ? smartarg1->get() : 0); + { + try { + result = (arg1)->build(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + *(ppc::protocol::Message::Ptr **)&jresult = result ? new ppc::protocol::Message::Ptr(result) : 0; + return jresult; +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_MessageBuilder_1build_1_1SWIG_11(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2) { + jlong jresult = 0 ; + ppc::protocol::MessageBuilder *arg1 = (ppc::protocol::MessageBuilder *) 0 ; + bcos::bytesConstRef arg2 ; + std::shared_ptr< ppc::protocol::MessageBuilder > *smartarg1 = 0 ; + bcos::bytesConstRef *argp2 ; + ppc::protocol::Message::Ptr result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< ppc::protocol::MessageBuilder > **)&jarg1; + arg1 = (ppc::protocol::MessageBuilder *)(smartarg1 ? smartarg1->get() : 0); + argp2 = *(bcos::bytesConstRef **)&jarg2; + if (!argp2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "Attempt to dereference null bcos::bytesConstRef"); + return 0; + } + arg2 = *argp2; + { + try { + result = (arg1)->build(arg2); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + *(ppc::protocol::Message::Ptr **)&jresult = result ? new ppc::protocol::Message::Ptr(result) : 0; + return jresult; +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_MessageBuilder_1build_1_1SWIG_12(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2, jlong jarg3, jobject jarg3_, jlong jarg4, jobject jarg4_) { + jlong jresult = 0 ; + ppc::protocol::MessageBuilder *arg1 = (ppc::protocol::MessageBuilder *) 0 ; + ppc::protocol::RouteType arg2 ; + ppc::protocol::MessageOptionalHeader::Ptr *arg3 = 0 ; + bcos::bytes *arg4 = 0 ; + std::shared_ptr< ppc::protocol::MessageBuilder > *smartarg1 = 0 ; + ppc::protocol::RouteType *argp2 ; + ppc::protocol::MessageOptionalHeader::Ptr tempnull3 ; + std::unique_ptr< bcos::bytes > rvrdeleter4 ; + ppc::protocol::Message::Ptr result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + (void)jarg3_; + (void)jarg4_; + + smartarg1 = *(std::shared_ptr< ppc::protocol::MessageBuilder > **)&jarg1; + arg1 = (ppc::protocol::MessageBuilder *)(smartarg1 ? smartarg1->get() : 0); + argp2 = *(ppc::protocol::RouteType **)&jarg2; + if (!argp2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "Attempt to dereference null ppc::protocol::RouteType"); + return 0; + } + arg2 = *argp2; + arg3 = jarg3 ? *(ppc::protocol::MessageOptionalHeader::Ptr **)&jarg3 : &tempnull3; + arg4 = *(bcos::bytes **)&jarg4; + if (!arg4) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "bcos::bytes && is null"); + return 0; + } + rvrdeleter4.reset(arg4); + { + try { + result = (arg1)->build(arg2,(ppc::protocol::MessageOptionalHeader::Ptr const &)*arg3,(bcos::bytes &&)*arg4); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + *(ppc::protocol::Message::Ptr **)&jresult = result ? new ppc::protocol::Message::Ptr(result) : 0; + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_delete_1MessageOptionalHeaderBuilder(JNIEnv *jenv, jclass jcls, jlong jarg1) { + ppc::protocol::MessageOptionalHeaderBuilder *arg1 = (ppc::protocol::MessageOptionalHeaderBuilder *) 0 ; + std::shared_ptr< ppc::protocol::MessageOptionalHeaderBuilder > *smartarg1 = 0 ; + + (void)jenv; + (void)jcls; + + smartarg1 = *(std::shared_ptr< ppc::protocol::MessageOptionalHeaderBuilder > **)&jarg1; + arg1 = (ppc::protocol::MessageOptionalHeaderBuilder *)(smartarg1 ? smartarg1->get() : 0); + { + try { + (void)arg1; delete smartarg1; + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_MessageOptionalHeaderBuilder_1build_1_1SWIG_10(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2, jobject jarg2_) { + jlong jresult = 0 ; + ppc::protocol::MessageOptionalHeaderBuilder *arg1 = (ppc::protocol::MessageOptionalHeaderBuilder *) 0 ; + ppc::protocol::MessageOptionalHeader::Ptr *arg2 = 0 ; + std::shared_ptr< ppc::protocol::MessageOptionalHeaderBuilder > *smartarg1 = 0 ; + ppc::protocol::MessageOptionalHeader::Ptr tempnull2 ; + ppc::protocol::MessageOptionalHeader::Ptr result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + (void)jarg2_; + + smartarg1 = *(std::shared_ptr< ppc::protocol::MessageOptionalHeaderBuilder > **)&jarg1; + arg1 = (ppc::protocol::MessageOptionalHeaderBuilder *)(smartarg1 ? smartarg1->get() : 0); + arg2 = jarg2 ? *(ppc::protocol::MessageOptionalHeader::Ptr **)&jarg2 : &tempnull2; + { + try { + result = (arg1)->build((ppc::protocol::MessageOptionalHeader::Ptr const &)*arg2); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + *(ppc::protocol::MessageOptionalHeader::Ptr **)&jresult = result ? new ppc::protocol::MessageOptionalHeader::Ptr(result) : 0; + return jresult; +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_MessageOptionalHeaderBuilder_1build_1_1SWIG_11(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jlong jresult = 0 ; + ppc::protocol::MessageOptionalHeaderBuilder *arg1 = (ppc::protocol::MessageOptionalHeaderBuilder *) 0 ; + std::shared_ptr< ppc::protocol::MessageOptionalHeaderBuilder > *smartarg1 = 0 ; + ppc::protocol::MessageOptionalHeader::Ptr result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< ppc::protocol::MessageOptionalHeaderBuilder > **)&jarg1; + arg1 = (ppc::protocol::MessageOptionalHeaderBuilder *)(smartarg1 ? smartarg1->get() : 0); + { + try { + result = (arg1)->build(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + *(ppc::protocol::MessageOptionalHeader::Ptr **)&jresult = result ? new ppc::protocol::MessageOptionalHeader::Ptr(result) : 0; + return jresult; +} + + +SWIGEXPORT jstring JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_printOptionalField(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jstring jresult = 0 ; + ppc::protocol::MessageOptionalHeader::Ptr arg1 ; + ppc::protocol::MessageOptionalHeader::Ptr *argp1 ; + std::string result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + argp1 = *(ppc::protocol::MessageOptionalHeader::Ptr **)&jarg1; + if (argp1) arg1 = *argp1; + { + try { + result = ppc::protocol::printOptionalField(SWIG_STD_MOVE(arg1)); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + jresult = jenv->NewStringUTF((&result)->c_str()); + return jresult; +} + + +SWIGEXPORT jstring JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_printMessage(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jstring jresult = 0 ; + ppc::protocol::Message::Ptr *arg1 = 0 ; + ppc::protocol::Message::Ptr tempnull1 ; + std::string result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = jarg1 ? *(ppc::protocol::Message::Ptr **)&jarg1 : &tempnull1; + { + try { + result = ppc::protocol::printMessage((std::shared_ptr< ppc::protocol::Message > const &)*arg1); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + jresult = jenv->NewStringUTF((&result)->c_str()); + return jresult; +} + + +SWIGEXPORT jint JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_FrontMsgExtFlag_1Response_1get(JNIEnv *jenv, jclass jcls) { + jint jresult = 0 ; + ppc::protocol::FrontMsgExtFlag result; + + (void)jenv; + (void)jcls; + { + try { + result = (ppc::protocol::FrontMsgExtFlag)ppc::protocol::FrontMsgExtFlag::Response; + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + jresult = (jint)result; + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_delete_1MessagePayload(JNIEnv *jenv, jclass jcls, jlong jarg1) { + ppc::protocol::MessagePayload *arg1 = (ppc::protocol::MessagePayload *) 0 ; + std::shared_ptr< ppc::protocol::MessagePayload > *smartarg1 = 0 ; + + (void)jenv; + (void)jcls; + + smartarg1 = *(std::shared_ptr< ppc::protocol::MessagePayload > **)&jarg1; + arg1 = (ppc::protocol::MessagePayload *)(smartarg1 ? smartarg1->get() : 0); + { + try { + (void)arg1; delete smartarg1; + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_MessagePayload_1encode(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2, jobject jarg2_) { + jlong jresult = 0 ; + ppc::protocol::MessagePayload *arg1 = (ppc::protocol::MessagePayload *) 0 ; + bcos::bytes *arg2 = 0 ; + std::shared_ptr< ppc::protocol::MessagePayload const > *smartarg1 = 0 ; + int64_t result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + (void)jarg2_; + + smartarg1 = *(std::shared_ptr< const ppc::protocol::MessagePayload > **)&jarg1; + arg1 = (ppc::protocol::MessagePayload *)(smartarg1 ? smartarg1->get() : 0); + + arg2 = (bcos::bytes *)((*(std::shared_ptr< bcos::bytes > **)&jarg2) ? (*(std::shared_ptr< bcos::bytes > **)&jarg2)->get() : 0); + if (!arg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "bcos::bytes & reference is null"); + return 0; + } + { + try { + result = (int64_t)((ppc::protocol::MessagePayload const *)arg1)->encode(*arg2); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + jresult = (jlong)result; + return jresult; +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_MessagePayload_1decode(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2) { + jlong jresult = 0 ; + ppc::protocol::MessagePayload *arg1 = (ppc::protocol::MessagePayload *) 0 ; + bcos::bytesConstRef arg2 ; + std::shared_ptr< ppc::protocol::MessagePayload > *smartarg1 = 0 ; + bcos::bytesConstRef *argp2 ; + int64_t result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< ppc::protocol::MessagePayload > **)&jarg1; + arg1 = (ppc::protocol::MessagePayload *)(smartarg1 ? smartarg1->get() : 0); + argp2 = *(bcos::bytesConstRef **)&jarg2; + if (!argp2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "Attempt to dereference null bcos::bytesConstRef"); + return 0; + } + arg2 = *argp2; + { + try { + result = (int64_t)(arg1)->decode(arg2); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + jresult = (jlong)result; + return jresult; +} + + +SWIGEXPORT jshort JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_MessagePayload_1version(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jshort jresult = 0 ; + ppc::protocol::MessagePayload *arg1 = (ppc::protocol::MessagePayload *) 0 ; + std::shared_ptr< ppc::protocol::MessagePayload const > *smartarg1 = 0 ; + uint8_t result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< const ppc::protocol::MessagePayload > **)&jarg1; + arg1 = (ppc::protocol::MessagePayload *)(smartarg1 ? smartarg1->get() : 0); + { + try { + result = (uint8_t)((ppc::protocol::MessagePayload const *)arg1)->version(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + jresult = (jshort)result; + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_MessagePayload_1setVersion(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jshort jarg2) { + ppc::protocol::MessagePayload *arg1 = (ppc::protocol::MessagePayload *) 0 ; + uint8_t arg2 ; + std::shared_ptr< ppc::protocol::MessagePayload > *smartarg1 = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< ppc::protocol::MessagePayload > **)&jarg1; + arg1 = (ppc::protocol::MessagePayload *)(smartarg1 ? smartarg1->get() : 0); + arg2 = (uint8_t)jarg2; + { + try { + (arg1)->setVersion(arg2); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT jbyteArray JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_MessagePayload_1dataBuffer(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jbyteArray jresult = 0 ; + ppc::protocol::MessagePayload *arg1 = (ppc::protocol::MessagePayload *) 0 ; + std::shared_ptr< ppc::protocol::MessagePayload const > *smartarg1 = 0 ; + OutputBuffer result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< const ppc::protocol::MessagePayload > **)&jarg1; + arg1 = (ppc::protocol::MessagePayload *)(smartarg1 ? smartarg1->get() : 0); + { + try { + result = ((ppc::protocol::MessagePayload const *)arg1)->dataBuffer(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + { + jresult = jenv->NewByteArray((&result)->len); + jenv->SetByteArrayRegion(jresult, 0, (&result)->len, (jbyte *) (&result)->data); + } + return jresult; +} + + +SWIGEXPORT jint JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_MessagePayload_1seq(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jint jresult = 0 ; + ppc::protocol::MessagePayload *arg1 = (ppc::protocol::MessagePayload *) 0 ; + std::shared_ptr< ppc::protocol::MessagePayload const > *smartarg1 = 0 ; + uint16_t result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< const ppc::protocol::MessagePayload > **)&jarg1; + arg1 = (ppc::protocol::MessagePayload *)(smartarg1 ? smartarg1->get() : 0); + { + try { + result = (uint16_t)((ppc::protocol::MessagePayload const *)arg1)->seq(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + jresult = (jint)result; + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_MessagePayload_1setSeq(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jint jarg2) { + ppc::protocol::MessagePayload *arg1 = (ppc::protocol::MessagePayload *) 0 ; + uint16_t arg2 ; + std::shared_ptr< ppc::protocol::MessagePayload > *smartarg1 = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< ppc::protocol::MessagePayload > **)&jarg1; + arg1 = (ppc::protocol::MessagePayload *)(smartarg1 ? smartarg1->get() : 0); + arg2 = (uint16_t)jarg2; + { + try { + (arg1)->setSeq(arg2); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_MessagePayload_1length(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jlong jresult = 0 ; + ppc::protocol::MessagePayload *arg1 = (ppc::protocol::MessagePayload *) 0 ; + std::shared_ptr< ppc::protocol::MessagePayload const > *smartarg1 = 0 ; + int64_t result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< const ppc::protocol::MessagePayload > **)&jarg1; + arg1 = (ppc::protocol::MessagePayload *)(smartarg1 ? smartarg1->get() : 0); + { + try { + result = (int64_t)((ppc::protocol::MessagePayload const *)arg1)->length(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + jresult = (jlong)result; + return jresult; +} + + +SWIGEXPORT jstring JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_MessagePayload_1traceID(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jstring jresult = 0 ; + ppc::protocol::MessagePayload *arg1 = (ppc::protocol::MessagePayload *) 0 ; + std::shared_ptr< ppc::protocol::MessagePayload const > *smartarg1 = 0 ; + std::string *result = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< const ppc::protocol::MessagePayload > **)&jarg1; + arg1 = (ppc::protocol::MessagePayload *)(smartarg1 ? smartarg1->get() : 0); + { + try { + result = (std::string *) &((ppc::protocol::MessagePayload const *)arg1)->traceID(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + jresult = jenv->NewStringUTF(result->c_str()); + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_MessagePayload_1setTraceID(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jstring jarg2) { + ppc::protocol::MessagePayload *arg1 = (ppc::protocol::MessagePayload *) 0 ; + std::string *arg2 = 0 ; + std::shared_ptr< ppc::protocol::MessagePayload > *smartarg1 = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< ppc::protocol::MessagePayload > **)&jarg1; + arg1 = (ppc::protocol::MessagePayload *)(smartarg1 ? smartarg1->get() : 0); + if(!jarg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null string"); + return ; + } + const char *arg2_pstr = (const char *)jenv->GetStringUTFChars(jarg2, 0); + if (!arg2_pstr) return ; + std::string arg2_str(arg2_pstr); + arg2 = &arg2_str; + jenv->ReleaseStringUTFChars(jarg2, arg2_pstr); + { + try { + (arg1)->setTraceID((std::string const &)*arg2); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT jint JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_MessagePayload_1ext(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jint jresult = 0 ; + ppc::protocol::MessagePayload *arg1 = (ppc::protocol::MessagePayload *) 0 ; + std::shared_ptr< ppc::protocol::MessagePayload const > *smartarg1 = 0 ; + uint16_t result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< const ppc::protocol::MessagePayload > **)&jarg1; + arg1 = (ppc::protocol::MessagePayload *)(smartarg1 ? smartarg1->get() : 0); + { + try { + result = (uint16_t)((ppc::protocol::MessagePayload const *)arg1)->ext(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + jresult = (jint)result; + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_MessagePayload_1setExt(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jint jarg2) { + ppc::protocol::MessagePayload *arg1 = (ppc::protocol::MessagePayload *) 0 ; + uint16_t arg2 ; + std::shared_ptr< ppc::protocol::MessagePayload > *smartarg1 = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< ppc::protocol::MessagePayload > **)&jarg1; + arg1 = (ppc::protocol::MessagePayload *)(smartarg1 ? smartarg1->get() : 0); + arg2 = (uint16_t)jarg2; + { + try { + (arg1)->setExt(arg2); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_MessagePayload_1setRespPacket(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + ppc::protocol::MessagePayload *arg1 = (ppc::protocol::MessagePayload *) 0 ; + std::shared_ptr< ppc::protocol::MessagePayload > *smartarg1 = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< ppc::protocol::MessagePayload > **)&jarg1; + arg1 = (ppc::protocol::MessagePayload *)(smartarg1 ? smartarg1->get() : 0); + { + try { + (arg1)->setRespPacket(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT jboolean JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_MessagePayload_1isRespPacket(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jboolean jresult = 0 ; + ppc::protocol::MessagePayload *arg1 = (ppc::protocol::MessagePayload *) 0 ; + std::shared_ptr< ppc::protocol::MessagePayload > *smartarg1 = 0 ; + bool result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< ppc::protocol::MessagePayload > **)&jarg1; + arg1 = (ppc::protocol::MessagePayload *)(smartarg1 ? smartarg1->get() : 0); + { + try { + result = (bool)(arg1)->isRespPacket(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + jresult = (jboolean)result; + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_MessagePayload_1releasePayload(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + ppc::protocol::MessagePayload *arg1 = (ppc::protocol::MessagePayload *) 0 ; + std::shared_ptr< ppc::protocol::MessagePayload > *smartarg1 = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< ppc::protocol::MessagePayload > **)&jarg1; + arg1 = (ppc::protocol::MessagePayload *)(smartarg1 ? smartarg1->get() : 0); + { + try { + (arg1)->releasePayload(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_delete_1MessagePayloadBuilder(JNIEnv *jenv, jclass jcls, jlong jarg1) { + ppc::protocol::MessagePayloadBuilder *arg1 = (ppc::protocol::MessagePayloadBuilder *) 0 ; + std::shared_ptr< ppc::protocol::MessagePayloadBuilder > *smartarg1 = 0 ; + + (void)jenv; + (void)jcls; + + smartarg1 = *(std::shared_ptr< ppc::protocol::MessagePayloadBuilder > **)&jarg1; + arg1 = (ppc::protocol::MessagePayloadBuilder *)(smartarg1 ? smartarg1->get() : 0); + { + try { + (void)arg1; delete smartarg1; + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_MessagePayloadBuilder_1build_1_1SWIG_10(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jlong jresult = 0 ; + ppc::protocol::MessagePayloadBuilder *arg1 = (ppc::protocol::MessagePayloadBuilder *) 0 ; + std::shared_ptr< ppc::protocol::MessagePayloadBuilder > *smartarg1 = 0 ; + ppc::protocol::MessagePayload::Ptr result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< ppc::protocol::MessagePayloadBuilder > **)&jarg1; + arg1 = (ppc::protocol::MessagePayloadBuilder *)(smartarg1 ? smartarg1->get() : 0); + { + try { + result = (arg1)->build(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + *(ppc::protocol::MessagePayload::Ptr **)&jresult = result ? new ppc::protocol::MessagePayload::Ptr(result) : 0; + return jresult; +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_MessagePayloadBuilder_1build_1_1SWIG_11(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2) { + jlong jresult = 0 ; + ppc::protocol::MessagePayloadBuilder *arg1 = (ppc::protocol::MessagePayloadBuilder *) 0 ; + bcos::bytesConstRef arg2 ; + std::shared_ptr< ppc::protocol::MessagePayloadBuilder > *smartarg1 = 0 ; + bcos::bytesConstRef *argp2 ; + ppc::protocol::MessagePayload::Ptr result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< ppc::protocol::MessagePayloadBuilder > **)&jarg1; + arg1 = (ppc::protocol::MessagePayloadBuilder *)(smartarg1 ? smartarg1->get() : 0); + argp2 = *(bcos::bytesConstRef **)&jarg2; + if (!argp2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "Attempt to dereference null bcos::bytesConstRef"); + return 0; + } + arg2 = *argp2; + { + try { + result = (arg1)->build(arg2); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + *(ppc::protocol::MessagePayload::Ptr **)&jresult = result ? new ppc::protocol::MessagePayload::Ptr(result) : 0; + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_delete_1INodeInfo(JNIEnv *jenv, jclass jcls, jlong jarg1) { + ppc::protocol::INodeInfo *arg1 = (ppc::protocol::INodeInfo *) 0 ; + std::shared_ptr< ppc::protocol::INodeInfo > *smartarg1 = 0 ; + + (void)jenv; + (void)jcls; + + smartarg1 = *(std::shared_ptr< ppc::protocol::INodeInfo > **)&jarg1; + arg1 = (ppc::protocol::INodeInfo *)(smartarg1 ? smartarg1->get() : 0); + { + try { + (void)arg1; delete smartarg1; + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT jstring JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_INodeInfo_1endPoint(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jstring jresult = 0 ; + ppc::protocol::INodeInfo *arg1 = (ppc::protocol::INodeInfo *) 0 ; + std::shared_ptr< ppc::protocol::INodeInfo const > *smartarg1 = 0 ; + std::string *result = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< const ppc::protocol::INodeInfo > **)&jarg1; + arg1 = (ppc::protocol::INodeInfo *)(smartarg1 ? smartarg1->get() : 0); + { + try { + result = (std::string *) &((ppc::protocol::INodeInfo const *)arg1)->endPoint(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + jresult = jenv->NewStringUTF(result->c_str()); + return jresult; +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_INodeInfo_1nodeID(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jlong jresult = 0 ; + ppc::protocol::INodeInfo *arg1 = (ppc::protocol::INodeInfo *) 0 ; + std::shared_ptr< ppc::protocol::INodeInfo const > *smartarg1 = 0 ; + bcos::bytesConstRef result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< const ppc::protocol::INodeInfo > **)&jarg1; + arg1 = (ppc::protocol::INodeInfo *)(smartarg1 ? smartarg1->get() : 0); + { + try { + result = ((ppc::protocol::INodeInfo const *)arg1)->nodeID(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + *(bcos::bytesConstRef **)&jresult = new bcos::bytesConstRef(result); + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_INodeInfo_1setNodeID(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2) { + ppc::protocol::INodeInfo *arg1 = (ppc::protocol::INodeInfo *) 0 ; + bcos::bytesConstRef arg2 ; + std::shared_ptr< ppc::protocol::INodeInfo > *smartarg1 = 0 ; + bcos::bytesConstRef *argp2 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< ppc::protocol::INodeInfo > **)&jarg1; + arg1 = (ppc::protocol::INodeInfo *)(smartarg1 ? smartarg1->get() : 0); + argp2 = *(bcos::bytesConstRef **)&jarg2; + if (!argp2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "Attempt to dereference null bcos::bytesConstRef"); + return ; + } + arg2 = *argp2; + { + try { + (arg1)->setNodeID(arg2); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_INodeInfo_1setEndPoint(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jstring jarg2) { + ppc::protocol::INodeInfo *arg1 = (ppc::protocol::INodeInfo *) 0 ; + std::string *arg2 = 0 ; + std::shared_ptr< ppc::protocol::INodeInfo > *smartarg1 = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< ppc::protocol::INodeInfo > **)&jarg1; + arg1 = (ppc::protocol::INodeInfo *)(smartarg1 ? smartarg1->get() : 0); + if(!jarg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null string"); + return ; + } + const char *arg2_pstr = (const char *)jenv->GetStringUTFChars(jarg2, 0); + if (!arg2_pstr) return ; + std::string arg2_str(arg2_pstr); + arg2 = &arg2_str; + jenv->ReleaseStringUTFChars(jarg2, arg2_pstr); + { + try { + (arg1)->setEndPoint((std::string const &)*arg2); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT jboolean JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_INodeInfo_1addComponent(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jstring jarg2) { + jboolean jresult = 0 ; + ppc::protocol::INodeInfo *arg1 = (ppc::protocol::INodeInfo *) 0 ; + std::string *arg2 = 0 ; + std::shared_ptr< ppc::protocol::INodeInfo > *smartarg1 = 0 ; + bool result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< ppc::protocol::INodeInfo > **)&jarg1; + arg1 = (ppc::protocol::INodeInfo *)(smartarg1 ? smartarg1->get() : 0); + if(!jarg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null string"); + return 0; + } + const char *arg2_pstr = (const char *)jenv->GetStringUTFChars(jarg2, 0); + if (!arg2_pstr) return 0; + std::string arg2_str(arg2_pstr); + arg2 = &arg2_str; + jenv->ReleaseStringUTFChars(jarg2, arg2_pstr); + { + try { + result = (bool)(arg1)->addComponent((std::string const &)*arg2); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + jresult = (jboolean)result; + return jresult; +} + + +SWIGEXPORT jboolean JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_INodeInfo_1eraseComponent(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jstring jarg2) { + jboolean jresult = 0 ; + ppc::protocol::INodeInfo *arg1 = (ppc::protocol::INodeInfo *) 0 ; + std::string *arg2 = 0 ; + std::shared_ptr< ppc::protocol::INodeInfo > *smartarg1 = 0 ; + bool result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< ppc::protocol::INodeInfo > **)&jarg1; + arg1 = (ppc::protocol::INodeInfo *)(smartarg1 ? smartarg1->get() : 0); + if(!jarg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null string"); + return 0; + } + const char *arg2_pstr = (const char *)jenv->GetStringUTFChars(jarg2, 0); + if (!arg2_pstr) return 0; + std::string arg2_str(arg2_pstr); + arg2 = &arg2_str; + jenv->ReleaseStringUTFChars(jarg2, arg2_pstr); + { + try { + result = (bool)(arg1)->eraseComponent((std::string const &)*arg2); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + jresult = (jboolean)result; + return jresult; +} + + +SWIGEXPORT jboolean JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_INodeInfo_1componentExist(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jstring jarg2) { + jboolean jresult = 0 ; + ppc::protocol::INodeInfo *arg1 = (ppc::protocol::INodeInfo *) 0 ; + std::string *arg2 = 0 ; + std::shared_ptr< ppc::protocol::INodeInfo const > *smartarg1 = 0 ; + bool result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< const ppc::protocol::INodeInfo > **)&jarg1; + arg1 = (ppc::protocol::INodeInfo *)(smartarg1 ? smartarg1->get() : 0); + if(!jarg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null string"); + return 0; + } + const char *arg2_pstr = (const char *)jenv->GetStringUTFChars(jarg2, 0); + if (!arg2_pstr) return 0; + std::string arg2_str(arg2_pstr); + arg2 = &arg2_str; + jenv->ReleaseStringUTFChars(jarg2, arg2_pstr); + { + try { + result = (bool)((ppc::protocol::INodeInfo const *)arg1)->componentExist((std::string const &)*arg2); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + jresult = (jboolean)result; + return jresult; +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_INodeInfo_1copiedComponents(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jlong jresult = 0 ; + ppc::protocol::INodeInfo *arg1 = (ppc::protocol::INodeInfo *) 0 ; + std::shared_ptr< ppc::protocol::INodeInfo const > *smartarg1 = 0 ; + std::vector< std::string > result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< const ppc::protocol::INodeInfo > **)&jarg1; + arg1 = (ppc::protocol::INodeInfo *)(smartarg1 ? smartarg1->get() : 0); + { + try { + result = ((ppc::protocol::INodeInfo const *)arg1)->copiedComponents(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + *(std::vector< std::string > **)&jresult = new std::vector< std::string >(result); + return jresult; +} + + +SWIGEXPORT jstring JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_INodeInfo_1meta(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jstring jresult = 0 ; + ppc::protocol::INodeInfo *arg1 = (ppc::protocol::INodeInfo *) 0 ; + std::shared_ptr< ppc::protocol::INodeInfo const > *smartarg1 = 0 ; + std::string result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< const ppc::protocol::INodeInfo > **)&jarg1; + arg1 = (ppc::protocol::INodeInfo *)(smartarg1 ? smartarg1->get() : 0); + { + try { + result = ((ppc::protocol::INodeInfo const *)arg1)->meta(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + jresult = jenv->NewStringUTF((&result)->c_str()); + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_INodeInfo_1setMeta(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jstring jarg2) { + ppc::protocol::INodeInfo *arg1 = (ppc::protocol::INodeInfo *) 0 ; + std::string *arg2 = 0 ; + std::shared_ptr< ppc::protocol::INodeInfo > *smartarg1 = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< ppc::protocol::INodeInfo > **)&jarg1; + arg1 = (ppc::protocol::INodeInfo *)(smartarg1 ? smartarg1->get() : 0); + if(!jarg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null string"); + return ; + } + const char *arg2_pstr = (const char *)jenv->GetStringUTFChars(jarg2, 0); + if (!arg2_pstr) return ; + std::string arg2_str(arg2_pstr); + arg2 = &arg2_str; + jenv->ReleaseStringUTFChars(jarg2, arg2_pstr); + { + try { + (arg1)->setMeta((std::string const &)*arg2); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT jstring JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_printNodeInfo(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jstring jresult = 0 ; + ppc::protocol::INodeInfo::Ptr *arg1 = 0 ; + ppc::protocol::INodeInfo::Ptr tempnull1 ; + std::string result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = jarg1 ? *(ppc::protocol::INodeInfo::Ptr **)&jarg1 : &tempnull1; + { + try { + result = ppc::protocol::printNodeInfo((std::shared_ptr< ppc::protocol::INodeInfo > const &)*arg1); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + jresult = jenv->NewStringUTF((&result)->c_str()); + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_delete_1IFrontClient(JNIEnv *jenv, jclass jcls, jlong jarg1) { + ppc::front::IFrontClient *arg1 = (ppc::front::IFrontClient *) 0 ; + std::shared_ptr< ppc::front::IFrontClient > *smartarg1 = 0 ; + + (void)jenv; + (void)jcls; + + smartarg1 = *(std::shared_ptr< ppc::front::IFrontClient > **)&jarg1; + arg1 = (ppc::front::IFrontClient *)(smartarg1 ? smartarg1->get() : 0); + { + try { + (void)arg1; delete smartarg1; + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_IFrontClient_1onReceiveMessage(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2, jobject jarg2_, jlong jarg3) { + ppc::front::IFrontClient *arg1 = (ppc::front::IFrontClient *) 0 ; + ppc::protocol::Message::Ptr *arg2 = 0 ; + SwigValueWrapper< std::function< void (std::shared_ptr< bcos::Error >) > > arg3 ; + std::shared_ptr< ppc::front::IFrontClient > *smartarg1 = 0 ; + ppc::protocol::Message::Ptr tempnull2 ; + ppc::protocol::ReceiveMsgFunc *argp3 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + (void)jarg2_; + + smartarg1 = *(std::shared_ptr< ppc::front::IFrontClient > **)&jarg1; + arg1 = (ppc::front::IFrontClient *)(smartarg1 ? smartarg1->get() : 0); + arg2 = jarg2 ? *(ppc::protocol::Message::Ptr **)&jarg2 : &tempnull2; + argp3 = *(ppc::protocol::ReceiveMsgFunc **)&jarg3; + if (!argp3) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "Attempt to dereference null ppc::protocol::ReceiveMsgFunc"); + return ; + } + arg3 = *argp3; + { + try { + (arg1)->onReceiveMessage((ppc::protocol::Message::Ptr const &)*arg2,arg3); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_new_1ErrorCallback(JNIEnv *jenv, jclass jcls) { + jlong jresult = 0 ; + ppc::front::ErrorCallback *result = 0 ; + + (void)jenv; + (void)jcls; + { + try { + result = (ppc::front::ErrorCallback *)new SwigDirector_ErrorCallback(jenv); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + + *(std::shared_ptr< ppc::front::ErrorCallback > **)&jresult = result ? new std::shared_ptr< ppc::front::ErrorCallback >(result SWIG_NO_NULL_DELETER_1) : 0; + + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_delete_1ErrorCallback(JNIEnv *jenv, jclass jcls, jlong jarg1) { + ppc::front::ErrorCallback *arg1 = (ppc::front::ErrorCallback *) 0 ; + std::shared_ptr< ppc::front::ErrorCallback > *smartarg1 = 0 ; + + (void)jenv; + (void)jcls; + + smartarg1 = *(std::shared_ptr< ppc::front::ErrorCallback > **)&jarg1; + arg1 = (ppc::front::ErrorCallback *)(smartarg1 ? smartarg1->get() : 0); + { + try { + (void)arg1; delete smartarg1; + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_ErrorCallback_1onError(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2, jobject jarg2_) { + ppc::front::ErrorCallback *arg1 = (ppc::front::ErrorCallback *) 0 ; + bcos::Error::Ptr arg2 ; + std::shared_ptr< ppc::front::ErrorCallback > *smartarg1 = 0 ; + bcos::Error::Ptr *argp2 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + (void)jarg2_; + + smartarg1 = *(std::shared_ptr< ppc::front::ErrorCallback > **)&jarg1; + arg1 = (ppc::front::ErrorCallback *)(smartarg1 ? smartarg1->get() : 0); + argp2 = *(bcos::Error::Ptr **)&jarg2; + if (argp2) arg2 = *argp2; + { + try { + (arg1)->onError(arg2); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_ErrorCallback_1director_1connect(JNIEnv *jenv, jclass jcls, jobject jself, jlong objarg, jboolean jswig_mem_own, jboolean jweak_global) { + std::shared_ptr< ppc::front::ErrorCallback > *obj = *((std::shared_ptr< ppc::front::ErrorCallback > **)&objarg); + (void)jcls; + // Keep a local instance of the smart pointer around while we are using the raw pointer + // Avoids using smart pointer specific API. + SwigDirector_ErrorCallback *director = static_cast(obj->operator->()); + director->swig_connect_director(jenv, jself, jenv->GetObjectClass(jself), (jswig_mem_own == JNI_TRUE), (jweak_global == JNI_TRUE)); +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_ErrorCallback_1change_1ownership(JNIEnv *jenv, jclass jcls, jobject jself, jlong objarg, jboolean jtake_or_release) { + std::shared_ptr< ppc::front::ErrorCallback > *obj = *((std::shared_ptr< ppc::front::ErrorCallback > **)&objarg); + // Keep a local instance of the smart pointer around while we are using the raw pointer + // Avoids using smart pointer specific API. + SwigDirector_ErrorCallback *director = dynamic_cast(obj->operator->()); + (void)jcls; + if (director) { + director->swig_java_change_ownership(jenv, jself, jtake_or_release ? true : false); + } +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_new_1MessageDispatcherHandler(JNIEnv *jenv, jclass jcls) { + jlong jresult = 0 ; + ppc::front::MessageDispatcherHandler *result = 0 ; + + (void)jenv; + (void)jcls; + { + try { + result = (ppc::front::MessageDispatcherHandler *)new SwigDirector_MessageDispatcherHandler(jenv); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + + *(std::shared_ptr< ppc::front::MessageDispatcherHandler > **)&jresult = result ? new std::shared_ptr< ppc::front::MessageDispatcherHandler >(result SWIG_NO_NULL_DELETER_1) : 0; + + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_delete_1MessageDispatcherHandler(JNIEnv *jenv, jclass jcls, jlong jarg1) { + ppc::front::MessageDispatcherHandler *arg1 = (ppc::front::MessageDispatcherHandler *) 0 ; + std::shared_ptr< ppc::front::MessageDispatcherHandler > *smartarg1 = 0 ; + + (void)jenv; + (void)jcls; + + smartarg1 = *(std::shared_ptr< ppc::front::MessageDispatcherHandler > **)&jarg1; + arg1 = (ppc::front::MessageDispatcherHandler *)(smartarg1 ? smartarg1->get() : 0); + { + try { + (void)arg1; delete smartarg1; + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_MessageDispatcherHandler_1onMessage(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2, jobject jarg2_) { + ppc::front::MessageDispatcherHandler *arg1 = (ppc::front::MessageDispatcherHandler *) 0 ; + ppc::protocol::Message::Ptr arg2 ; + std::shared_ptr< ppc::front::MessageDispatcherHandler > *smartarg1 = 0 ; + ppc::protocol::Message::Ptr *argp2 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + (void)jarg2_; + + smartarg1 = *(std::shared_ptr< ppc::front::MessageDispatcherHandler > **)&jarg1; + arg1 = (ppc::front::MessageDispatcherHandler *)(smartarg1 ? smartarg1->get() : 0); + argp2 = *(ppc::protocol::Message::Ptr **)&jarg2; + if (argp2) arg2 = *argp2; + { + try { + (arg1)->onMessage(arg2); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_MessageDispatcherHandler_1director_1connect(JNIEnv *jenv, jclass jcls, jobject jself, jlong objarg, jboolean jswig_mem_own, jboolean jweak_global) { + std::shared_ptr< ppc::front::MessageDispatcherHandler > *obj = *((std::shared_ptr< ppc::front::MessageDispatcherHandler > **)&objarg); + (void)jcls; + // Keep a local instance of the smart pointer around while we are using the raw pointer + // Avoids using smart pointer specific API. + SwigDirector_MessageDispatcherHandler *director = static_cast(obj->operator->()); + director->swig_connect_director(jenv, jself, jenv->GetObjectClass(jself), (jswig_mem_own == JNI_TRUE), (jweak_global == JNI_TRUE)); +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_MessageDispatcherHandler_1change_1ownership(JNIEnv *jenv, jclass jcls, jobject jself, jlong objarg, jboolean jtake_or_release) { + std::shared_ptr< ppc::front::MessageDispatcherHandler > *obj = *((std::shared_ptr< ppc::front::MessageDispatcherHandler > **)&objarg); + // Keep a local instance of the smart pointer around while we are using the raw pointer + // Avoids using smart pointer specific API. + SwigDirector_MessageDispatcherHandler *director = dynamic_cast(obj->operator->()); + (void)jcls; + if (director) { + director->swig_java_change_ownership(jenv, jself, jtake_or_release ? true : false); + } +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_new_1SendResponseHandler(JNIEnv *jenv, jclass jcls, jlong jarg1) { + jlong jresult = 0 ; + SwigValueWrapper< std::function< void (std::shared_ptr< bcos::bytes > &&) > > arg1 ; + ppc::protocol::SendResponseFunction *argp1 ; + ppc::front::SendResponseHandler *result = 0 ; + + (void)jenv; + (void)jcls; + argp1 = *(ppc::protocol::SendResponseFunction **)&jarg1; + if (!argp1) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "Attempt to dereference null ppc::protocol::SendResponseFunction"); + return 0; + } + arg1 = *argp1; + { + try { + result = (ppc::front::SendResponseHandler *)new ppc::front::SendResponseHandler(arg1); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + *(ppc::front::SendResponseHandler **)&jresult = result; + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_delete_1SendResponseHandler(JNIEnv *jenv, jclass jcls, jlong jarg1) { + ppc::front::SendResponseHandler *arg1 = (ppc::front::SendResponseHandler *) 0 ; + + (void)jenv; + (void)jcls; + arg1 = *(ppc::front::SendResponseHandler **)&jarg1; + { + try { + delete arg1; + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_SendResponseHandler_1sendResponse(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2) { + ppc::front::SendResponseHandler *arg1 = (ppc::front::SendResponseHandler *) 0 ; + std::shared_ptr< bcos::bytes > *arg2 = 0 ; + std::unique_ptr< std::shared_ptr< bcos::bytes > > rvrdeleter2 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(ppc::front::SendResponseHandler **)&jarg1; + arg2 = *(std::shared_ptr< bcos::bytes > **)&jarg2; + if (!arg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "std::shared_ptr< bcos::bytes > && is null"); + return ; + } + rvrdeleter2.reset(arg2); + { + try { + (arg1)->sendResponse((std::shared_ptr< bcos::bytes > &&)*arg2); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_new_1IMessageHandler(JNIEnv *jenv, jclass jcls) { + jlong jresult = 0 ; + ppc::front::IMessageHandler *result = 0 ; + + (void)jenv; + (void)jcls; + { + try { + result = (ppc::front::IMessageHandler *)new SwigDirector_IMessageHandler(jenv); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + + *(std::shared_ptr< ppc::front::IMessageHandler > **)&jresult = result ? new std::shared_ptr< ppc::front::IMessageHandler >(result SWIG_NO_NULL_DELETER_1) : 0; + + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_delete_1IMessageHandler(JNIEnv *jenv, jclass jcls, jlong jarg1) { + ppc::front::IMessageHandler *arg1 = (ppc::front::IMessageHandler *) 0 ; + std::shared_ptr< ppc::front::IMessageHandler > *smartarg1 = 0 ; + + (void)jenv; + (void)jcls; + + smartarg1 = *(std::shared_ptr< ppc::front::IMessageHandler > **)&jarg1; + arg1 = (ppc::front::IMessageHandler *)(smartarg1 ? smartarg1->get() : 0); + { + try { + (void)arg1; delete smartarg1; + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_IMessageHandler_1onMessage(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2, jobject jarg2_, jlong jarg3, jobject jarg3_, jlong jarg4, jobject jarg4_) { + ppc::front::IMessageHandler *arg1 = (ppc::front::IMessageHandler *) 0 ; + bcos::Error::Ptr arg2 ; + ppc::protocol::Message::Ptr arg3 ; + SwigValueWrapper< ppc::front::SendResponseHandler > arg4 ; + std::shared_ptr< ppc::front::IMessageHandler > *smartarg1 = 0 ; + bcos::Error::Ptr *argp2 ; + ppc::protocol::Message::Ptr *argp3 ; + ppc::front::SendResponseHandler *argp4 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + (void)jarg2_; + (void)jarg3_; + (void)jarg4_; + + smartarg1 = *(std::shared_ptr< ppc::front::IMessageHandler > **)&jarg1; + arg1 = (ppc::front::IMessageHandler *)(smartarg1 ? smartarg1->get() : 0); + argp2 = *(bcos::Error::Ptr **)&jarg2; + if (argp2) arg2 = *argp2; + argp3 = *(ppc::protocol::Message::Ptr **)&jarg3; + if (argp3) arg3 = *argp3; + argp4 = *(ppc::front::SendResponseHandler **)&jarg4; + if (!argp4) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "Attempt to dereference null ppc::front::SendResponseHandler"); + return ; + } + arg4 = *argp4; + { + try { + (arg1)->onMessage(arg2,arg3,arg4); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_IMessageHandler_1director_1connect(JNIEnv *jenv, jclass jcls, jobject jself, jlong objarg, jboolean jswig_mem_own, jboolean jweak_global) { + std::shared_ptr< ppc::front::IMessageHandler > *obj = *((std::shared_ptr< ppc::front::IMessageHandler > **)&objarg); + (void)jcls; + // Keep a local instance of the smart pointer around while we are using the raw pointer + // Avoids using smart pointer specific API. + SwigDirector_IMessageHandler *director = static_cast(obj->operator->()); + director->swig_connect_director(jenv, jself, jenv->GetObjectClass(jself), (jswig_mem_own == JNI_TRUE), (jweak_global == JNI_TRUE)); +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_IMessageHandler_1change_1ownership(JNIEnv *jenv, jclass jcls, jobject jself, jlong objarg, jboolean jtake_or_release) { + std::shared_ptr< ppc::front::IMessageHandler > *obj = *((std::shared_ptr< ppc::front::IMessageHandler > **)&objarg); + // Keep a local instance of the smart pointer around while we are using the raw pointer + // Avoids using smart pointer specific API. + SwigDirector_IMessageHandler *director = dynamic_cast(obj->operator->()); + (void)jcls; + if (director) { + director->swig_java_change_ownership(jenv, jself, jtake_or_release ? true : false); + } +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_new_1GetPeersInfoHandler(JNIEnv *jenv, jclass jcls) { + jlong jresult = 0 ; + ppc::front::GetPeersInfoHandler *result = 0 ; + + (void)jenv; + (void)jcls; + { + try { + result = (ppc::front::GetPeersInfoHandler *)new SwigDirector_GetPeersInfoHandler(jenv); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + + *(std::shared_ptr< ppc::front::GetPeersInfoHandler > **)&jresult = result ? new std::shared_ptr< ppc::front::GetPeersInfoHandler >(result SWIG_NO_NULL_DELETER_1) : 0; + + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_delete_1GetPeersInfoHandler(JNIEnv *jenv, jclass jcls, jlong jarg1) { + ppc::front::GetPeersInfoHandler *arg1 = (ppc::front::GetPeersInfoHandler *) 0 ; + std::shared_ptr< ppc::front::GetPeersInfoHandler > *smartarg1 = 0 ; + + (void)jenv; + (void)jcls; + + smartarg1 = *(std::shared_ptr< ppc::front::GetPeersInfoHandler > **)&jarg1; + arg1 = (ppc::front::GetPeersInfoHandler *)(smartarg1 ? smartarg1->get() : 0); + { + try { + (void)arg1; delete smartarg1; + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_GetPeersInfoHandler_1onPeersInfo(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2, jobject jarg2_, jstring jarg3) { + ppc::front::GetPeersInfoHandler *arg1 = (ppc::front::GetPeersInfoHandler *) 0 ; + bcos::Error::Ptr arg2 ; + std::string *arg3 = 0 ; + std::shared_ptr< ppc::front::GetPeersInfoHandler > *smartarg1 = 0 ; + bcos::Error::Ptr *argp2 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + (void)jarg2_; + + smartarg1 = *(std::shared_ptr< ppc::front::GetPeersInfoHandler > **)&jarg1; + arg1 = (ppc::front::GetPeersInfoHandler *)(smartarg1 ? smartarg1->get() : 0); + argp2 = *(bcos::Error::Ptr **)&jarg2; + if (argp2) arg2 = *argp2; + if(!jarg3) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null string"); + return ; + } + const char *arg3_pstr = (const char *)jenv->GetStringUTFChars(jarg3, 0); + if (!arg3_pstr) return ; + std::string arg3_str(arg3_pstr); + arg3 = &arg3_str; + jenv->ReleaseStringUTFChars(jarg3, arg3_pstr); + { + try { + (arg1)->onPeersInfo(arg2,(std::string const &)*arg3); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_GetPeersInfoHandler_1director_1connect(JNIEnv *jenv, jclass jcls, jobject jself, jlong objarg, jboolean jswig_mem_own, jboolean jweak_global) { + std::shared_ptr< ppc::front::GetPeersInfoHandler > *obj = *((std::shared_ptr< ppc::front::GetPeersInfoHandler > **)&objarg); + (void)jcls; + // Keep a local instance of the smart pointer around while we are using the raw pointer + // Avoids using smart pointer specific API. + SwigDirector_GetPeersInfoHandler *director = static_cast(obj->operator->()); + director->swig_connect_director(jenv, jself, jenv->GetObjectClass(jself), (jswig_mem_own == JNI_TRUE), (jweak_global == JNI_TRUE)); +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_GetPeersInfoHandler_1change_1ownership(JNIEnv *jenv, jclass jcls, jobject jself, jlong objarg, jboolean jtake_or_release) { + std::shared_ptr< ppc::front::GetPeersInfoHandler > *obj = *((std::shared_ptr< ppc::front::GetPeersInfoHandler > **)&objarg); + // Keep a local instance of the smart pointer around while we are using the raw pointer + // Avoids using smart pointer specific API. + SwigDirector_GetPeersInfoHandler *director = dynamic_cast(obj->operator->()); + (void)jcls; + if (director) { + director->swig_java_change_ownership(jenv, jself, jtake_or_release ? true : false); + } +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_delete_1IFront(JNIEnv *jenv, jclass jcls, jlong jarg1) { + ppc::front::IFront *arg1 = (ppc::front::IFront *) 0 ; + std::shared_ptr< ppc::front::IFront > *smartarg1 = 0 ; + + (void)jenv; + (void)jcls; + + smartarg1 = *(std::shared_ptr< ppc::front::IFront > **)&jarg1; + arg1 = (ppc::front::IFront *)(smartarg1 ? smartarg1->get() : 0); + { + try { + (void)arg1; delete smartarg1; + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_IFront_1start(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + ppc::front::IFront *arg1 = (ppc::front::IFront *) 0 ; + std::shared_ptr< ppc::front::IFront > *smartarg1 = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< ppc::front::IFront > **)&jarg1; + arg1 = (ppc::front::IFront *)(smartarg1 ? smartarg1->get() : 0); + { + try { + (arg1)->start(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_IFront_1stop(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + ppc::front::IFront *arg1 = (ppc::front::IFront *) 0 ; + std::shared_ptr< ppc::front::IFront > *smartarg1 = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< ppc::front::IFront > **)&jarg1; + arg1 = (ppc::front::IFront *)(smartarg1 ? smartarg1->get() : 0); + { + try { + (arg1)->stop(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_IFront_1register_1topic_1handler(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jstring jarg2, jlong jarg3, jobject jarg3_) { + ppc::front::IFront *arg1 = (ppc::front::IFront *) 0 ; + std::string *arg2 = 0 ; + ppc::front::MessageDispatcherHandler::Ptr arg3 ; + std::shared_ptr< ppc::front::IFront > *smartarg1 = 0 ; + ppc::front::MessageDispatcherHandler::Ptr *argp3 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + (void)jarg3_; + + smartarg1 = *(std::shared_ptr< ppc::front::IFront > **)&jarg1; + arg1 = (ppc::front::IFront *)(smartarg1 ? smartarg1->get() : 0); + if(!jarg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null string"); + return ; + } + const char *arg2_pstr = (const char *)jenv->GetStringUTFChars(jarg2, 0); + if (!arg2_pstr) return ; + std::string arg2_str(arg2_pstr); + arg2 = &arg2_str; + jenv->ReleaseStringUTFChars(jarg2, arg2_pstr); + argp3 = *(ppc::front::MessageDispatcherHandler::Ptr **)&jarg3; + if (argp3) arg3 = *argp3; + { + try { + (arg1)->register_topic_handler((std::string const &)*arg2,arg3); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_IFront_1register_1msg_1handler(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jstring jarg2, jlong jarg3, jobject jarg3_) { + ppc::front::IFront *arg1 = (ppc::front::IFront *) 0 ; + std::string *arg2 = 0 ; + ppc::front::MessageDispatcherHandler::Ptr arg3 ; + std::shared_ptr< ppc::front::IFront > *smartarg1 = 0 ; + ppc::front::MessageDispatcherHandler::Ptr *argp3 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + (void)jarg3_; + + smartarg1 = *(std::shared_ptr< ppc::front::IFront > **)&jarg1; + arg1 = (ppc::front::IFront *)(smartarg1 ? smartarg1->get() : 0); + if(!jarg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null string"); + return ; + } + const char *arg2_pstr = (const char *)jenv->GetStringUTFChars(jarg2, 0); + if (!arg2_pstr) return ; + std::string arg2_str(arg2_pstr); + arg2 = &arg2_str; + jenv->ReleaseStringUTFChars(jarg2, arg2_pstr); + argp3 = *(ppc::front::MessageDispatcherHandler::Ptr **)&jarg3; + if (argp3) arg3 = *argp3; + { + try { + (arg1)->register_msg_handler((std::string const &)*arg2,arg3); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_IFront_1async_1send_1message(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jint jarg2, jlong jarg3, jobject jarg3_, jbyteArray jarg4, jobject jarg5, jint jarg6, jint jarg7, jlong jarg8, jobject jarg8_, jlong jarg9, jobject jarg9_) { + ppc::front::IFront *arg1 = (ppc::front::IFront *) 0 ; + uint16_t arg2 ; + ppc::protocol::MessageOptionalHeader::Ptr *arg3 = 0 ; + char *arg4 = (char *) 0 ; + uint64_t arg5 ; + int arg6 ; + long arg7 ; + ppc::front::ErrorCallback::Ptr arg8 ; + ppc::front::IMessageHandler::Ptr arg9 ; + std::shared_ptr< ppc::front::IFront > *smartarg1 = 0 ; + ppc::protocol::MessageOptionalHeader::Ptr tempnull3 ; + ppc::front::ErrorCallback::Ptr *argp8 ; + ppc::front::IMessageHandler::Ptr *argp9 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + (void)jarg3_; + (void)jarg8_; + (void)jarg9_; + + smartarg1 = *(std::shared_ptr< ppc::front::IFront > **)&jarg1; + arg1 = (ppc::front::IFront *)(smartarg1 ? smartarg1->get() : 0); + arg2 = (uint16_t)jarg2; + arg3 = jarg3 ? *(ppc::protocol::MessageOptionalHeader::Ptr **)&jarg3 : &tempnull3; + { + arg4 = (char *) jenv->GetByteArrayElements(jarg4, 0); + } + { + jclass clazz; + jmethodID mid; + jbyteArray ba; + jbyte* bae; + jsize sz; + int i; + + if (!jarg5) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "BigInteger null"); + return ; + } + clazz = jenv->GetObjectClass(jarg5); + mid = jenv->GetMethodID(clazz, "toByteArray", "()[B"); + ba = (jbyteArray)jenv->CallObjectMethod(jarg5, mid); + bae = jenv->GetByteArrayElements(ba, 0); + sz = jenv->GetArrayLength(ba); + arg5 = 0; + if (sz > 0) { + arg5 = (uint64_t)(signed char)bae[0]; + for(i=1; iReleaseByteArrayElements(ba, bae, 0); + } + arg6 = (int)jarg6; + arg7 = (long)jarg7; + argp8 = *(ppc::front::ErrorCallback::Ptr **)&jarg8; + if (argp8) arg8 = *argp8; + argp9 = *(ppc::front::IMessageHandler::Ptr **)&jarg9; + if (argp9) arg9 = *argp9; + { + try { + (arg1)->async_send_message(arg2,(ppc::protocol::MessageOptionalHeader::Ptr const &)*arg3,arg4,arg5,arg6,arg7,arg8,arg9); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } + { + jenv->ReleaseByteArrayElements(jarg4, (jbyte *) arg4, 0); + } + +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_IFront_1async_1send_1response(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jbyteArray jarg2, jobject jarg3, jstring jarg4, jbyteArray jarg5, jobject jarg6, jint jarg7, jlong jarg8, jobject jarg8_) { + ppc::front::IFront *arg1 = (ppc::front::IFront *) 0 ; + char *arg2 = (char *) 0 ; + uint64_t arg3 ; + std::string *arg4 = 0 ; + char *arg5 = (char *) 0 ; + uint64_t arg6 ; + int arg7 ; + ppc::front::ErrorCallback::Ptr arg8 ; + std::shared_ptr< ppc::front::IFront > *smartarg1 = 0 ; + ppc::front::ErrorCallback::Ptr *argp8 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + (void)jarg8_; + + smartarg1 = *(std::shared_ptr< ppc::front::IFront > **)&jarg1; + arg1 = (ppc::front::IFront *)(smartarg1 ? smartarg1->get() : 0); + { + arg2 = (char *) jenv->GetByteArrayElements(jarg2, 0); + } + { + jclass clazz; + jmethodID mid; + jbyteArray ba; + jbyte* bae; + jsize sz; + int i; + + if (!jarg3) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "BigInteger null"); + return ; + } + clazz = jenv->GetObjectClass(jarg3); + mid = jenv->GetMethodID(clazz, "toByteArray", "()[B"); + ba = (jbyteArray)jenv->CallObjectMethod(jarg3, mid); + bae = jenv->GetByteArrayElements(ba, 0); + sz = jenv->GetArrayLength(ba); + arg3 = 0; + if (sz > 0) { + arg3 = (uint64_t)(signed char)bae[0]; + for(i=1; iReleaseByteArrayElements(ba, bae, 0); + } + if(!jarg4) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null string"); + return ; + } + const char *arg4_pstr = (const char *)jenv->GetStringUTFChars(jarg4, 0); + if (!arg4_pstr) return ; + std::string arg4_str(arg4_pstr); + arg4 = &arg4_str; + jenv->ReleaseStringUTFChars(jarg4, arg4_pstr); + { + arg5 = (char *) jenv->GetByteArrayElements(jarg5, 0); + } + { + jclass clazz; + jmethodID mid; + jbyteArray ba; + jbyte* bae; + jsize sz; + int i; + + if (!jarg6) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "BigInteger null"); + return ; + } + clazz = jenv->GetObjectClass(jarg6); + mid = jenv->GetMethodID(clazz, "toByteArray", "()[B"); + ba = (jbyteArray)jenv->CallObjectMethod(jarg6, mid); + bae = jenv->GetByteArrayElements(ba, 0); + sz = jenv->GetArrayLength(ba); + arg6 = 0; + if (sz > 0) { + arg6 = (uint64_t)(signed char)bae[0]; + for(i=1; iReleaseByteArrayElements(ba, bae, 0); + } + arg7 = (int)jarg7; + argp8 = *(ppc::front::ErrorCallback::Ptr **)&jarg8; + if (argp8) arg8 = *argp8; + { + try { + (arg1)->async_send_response(arg2,arg3,(std::string const &)*arg4,arg5,arg6,arg7,arg8); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } + { + jenv->ReleaseByteArrayElements(jarg2, (jbyte *) arg2, 0); + } + { + jenv->ReleaseByteArrayElements(jarg5, (jbyte *) arg5, 0); + } + + +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_IFront_1push_1msg(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jint jarg2, jlong jarg3, jobject jarg3_, jbyteArray jarg4, jobject jarg5, jint jarg6, jint jarg7) { + jlong jresult = 0 ; + ppc::front::IFront *arg1 = (ppc::front::IFront *) 0 ; + uint16_t arg2 ; + ppc::protocol::MessageOptionalHeader::Ptr *arg3 = 0 ; + char *arg4 = (char *) 0 ; + uint64_t arg5 ; + int arg6 ; + long arg7 ; + std::shared_ptr< ppc::front::IFront > *smartarg1 = 0 ; + ppc::protocol::MessageOptionalHeader::Ptr tempnull3 ; + bcos::Error::Ptr result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + (void)jarg3_; + + smartarg1 = *(std::shared_ptr< ppc::front::IFront > **)&jarg1; + arg1 = (ppc::front::IFront *)(smartarg1 ? smartarg1->get() : 0); + arg2 = (uint16_t)jarg2; + arg3 = jarg3 ? *(ppc::protocol::MessageOptionalHeader::Ptr **)&jarg3 : &tempnull3; + { + arg4 = (char *) jenv->GetByteArrayElements(jarg4, 0); + } + { + jclass clazz; + jmethodID mid; + jbyteArray ba; + jbyte* bae; + jsize sz; + int i; + + if (!jarg5) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "BigInteger null"); + return 0; + } + clazz = jenv->GetObjectClass(jarg5); + mid = jenv->GetMethodID(clazz, "toByteArray", "()[B"); + ba = (jbyteArray)jenv->CallObjectMethod(jarg5, mid); + bae = jenv->GetByteArrayElements(ba, 0); + sz = jenv->GetArrayLength(ba); + arg5 = 0; + if (sz > 0) { + arg5 = (uint64_t)(signed char)bae[0]; + for(i=1; iReleaseByteArrayElements(ba, bae, 0); + } + arg6 = (int)jarg6; + arg7 = (long)jarg7; + { + try { + result = (arg1)->push_msg(arg2,(ppc::protocol::MessageOptionalHeader::Ptr const &)*arg3,arg4,arg5,arg6,arg7); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + *(bcos::Error::Ptr **)&jresult = result ? new bcos::Error::Ptr(result) : 0; + { + jenv->ReleaseByteArrayElements(jarg4, (jbyte *) arg4, 0); + } + + return jresult; +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_IFront_1pop(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jstring jarg2, jint jarg3) { + jlong jresult = 0 ; + ppc::front::IFront *arg1 = (ppc::front::IFront *) 0 ; + std::string *arg2 = 0 ; + long arg3 ; + std::shared_ptr< ppc::front::IFront > *smartarg1 = 0 ; + ppc::protocol::Message::Ptr result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< ppc::front::IFront > **)&jarg1; + arg1 = (ppc::front::IFront *)(smartarg1 ? smartarg1->get() : 0); + if(!jarg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null string"); + return 0; + } + const char *arg2_pstr = (const char *)jenv->GetStringUTFChars(jarg2, 0); + if (!arg2_pstr) return 0; + std::string arg2_str(arg2_pstr); + arg2 = &arg2_str; + jenv->ReleaseStringUTFChars(jarg2, arg2_pstr); + arg3 = (long)jarg3; + { + try { + result = (arg1)->pop((std::string const &)*arg2,arg3); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + *(ppc::protocol::Message::Ptr **)&jresult = result ? new ppc::protocol::Message::Ptr(result) : 0; + return jresult; +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_IFront_1peek(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jstring jarg2) { + jlong jresult = 0 ; + ppc::front::IFront *arg1 = (ppc::front::IFront *) 0 ; + std::string *arg2 = 0 ; + std::shared_ptr< ppc::front::IFront > *smartarg1 = 0 ; + ppc::protocol::Message::Ptr result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< ppc::front::IFront > **)&jarg1; + arg1 = (ppc::front::IFront *)(smartarg1 ? smartarg1->get() : 0); + if(!jarg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null string"); + return 0; + } + const char *arg2_pstr = (const char *)jenv->GetStringUTFChars(jarg2, 0); + if (!arg2_pstr) return 0; + std::string arg2_str(arg2_pstr); + arg2 = &arg2_str; + jenv->ReleaseStringUTFChars(jarg2, arg2_pstr); + { + try { + result = (arg1)->peek((std::string const &)*arg2); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + *(ppc::protocol::Message::Ptr **)&jresult = result ? new ppc::protocol::Message::Ptr(result) : 0; + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_IFront_1asyncGetPeers(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2, jobject jarg2_) { + ppc::front::IFront *arg1 = (ppc::front::IFront *) 0 ; + ppc::front::GetPeersInfoHandler::Ptr arg2 ; + std::shared_ptr< ppc::front::IFront > *smartarg1 = 0 ; + ppc::front::GetPeersInfoHandler::Ptr *argp2 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + (void)jarg2_; + + smartarg1 = *(std::shared_ptr< ppc::front::IFront > **)&jarg1; + arg1 = (ppc::front::IFront *)(smartarg1 ? smartarg1->get() : 0); + argp2 = *(ppc::front::GetPeersInfoHandler::Ptr **)&jarg2; + if (argp2) arg2 = *argp2; + { + try { + (arg1)->asyncGetPeers(arg2); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_IFront_1nodeInfo(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jlong jresult = 0 ; + ppc::front::IFront *arg1 = (ppc::front::IFront *) 0 ; + std::shared_ptr< ppc::front::IFront > *smartarg1 = 0 ; + ppc::protocol::INodeInfo::Ptr *result = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< ppc::front::IFront > **)&jarg1; + arg1 = (ppc::front::IFront *)(smartarg1 ? smartarg1->get() : 0); + { + try { + result = (ppc::protocol::INodeInfo::Ptr *) &(arg1)->nodeInfo(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + *(ppc::protocol::INodeInfo::Ptr **)&jresult = *result ? new ppc::protocol::INodeInfo::Ptr(*result) : 0; + return jresult; +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_IFront_1registerTopic(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jstring jarg2) { + jlong jresult = 0 ; + ppc::front::IFront *arg1 = (ppc::front::IFront *) 0 ; + std::string *arg2 = 0 ; + std::shared_ptr< ppc::front::IFront > *smartarg1 = 0 ; + bcos::Error::Ptr result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< ppc::front::IFront > **)&jarg1; + arg1 = (ppc::front::IFront *)(smartarg1 ? smartarg1->get() : 0); + if(!jarg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null string"); + return 0; + } + const char *arg2_pstr = (const char *)jenv->GetStringUTFChars(jarg2, 0); + if (!arg2_pstr) return 0; + std::string arg2_str(arg2_pstr); + arg2 = &arg2_str; + jenv->ReleaseStringUTFChars(jarg2, arg2_pstr); + { + try { + result = (arg1)->registerTopic((std::string const &)*arg2); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + *(bcos::Error::Ptr **)&jresult = result ? new bcos::Error::Ptr(result) : 0; + return jresult; +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_IFront_1unRegisterTopic(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jstring jarg2) { + jlong jresult = 0 ; + ppc::front::IFront *arg1 = (ppc::front::IFront *) 0 ; + std::string *arg2 = 0 ; + std::shared_ptr< ppc::front::IFront > *smartarg1 = 0 ; + bcos::Error::Ptr result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< ppc::front::IFront > **)&jarg1; + arg1 = (ppc::front::IFront *)(smartarg1 ? smartarg1->get() : 0); + if(!jarg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null string"); + return 0; + } + const char *arg2_pstr = (const char *)jenv->GetStringUTFChars(jarg2, 0); + if (!arg2_pstr) return 0; + std::string arg2_str(arg2_pstr); + arg2 = &arg2_str; + jenv->ReleaseStringUTFChars(jarg2, arg2_pstr); + { + try { + result = (arg1)->unRegisterTopic((std::string const &)*arg2); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + *(bcos::Error::Ptr **)&jresult = result ? new bcos::Error::Ptr(result) : 0; + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_IFront_1registerComponent(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jstring jarg2) { + ppc::front::IFront *arg1 = (ppc::front::IFront *) 0 ; + std::string *arg2 = 0 ; + std::shared_ptr< ppc::front::IFront > *smartarg1 = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< ppc::front::IFront > **)&jarg1; + arg1 = (ppc::front::IFront *)(smartarg1 ? smartarg1->get() : 0); + if(!jarg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null string"); + return ; + } + const char *arg2_pstr = (const char *)jenv->GetStringUTFChars(jarg2, 0); + if (!arg2_pstr) return ; + std::string arg2_str(arg2_pstr); + arg2 = &arg2_str; + jenv->ReleaseStringUTFChars(jarg2, arg2_pstr); + { + try { + (arg1)->registerComponent((std::string const &)*arg2); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_IFront_1unRegisterComponent(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jstring jarg2) { + ppc::front::IFront *arg1 = (ppc::front::IFront *) 0 ; + std::string *arg2 = 0 ; + std::shared_ptr< ppc::front::IFront > *smartarg1 = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< ppc::front::IFront > **)&jarg1; + arg1 = (ppc::front::IFront *)(smartarg1 ? smartarg1->get() : 0); + if(!jarg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null string"); + return ; + } + const char *arg2_pstr = (const char *)jenv->GetStringUTFChars(jarg2, 0); + if (!arg2_pstr) return ; + std::string arg2_str(arg2_pstr); + arg2 = &arg2_str; + jenv->ReleaseStringUTFChars(jarg2, arg2_pstr); + { + try { + (arg1)->unRegisterComponent((std::string const &)*arg2); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_IFront_1updateMetaInfo(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jstring jarg2) { + ppc::front::IFront *arg1 = (ppc::front::IFront *) 0 ; + std::string *arg2 = 0 ; + std::shared_ptr< ppc::front::IFront > *smartarg1 = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< ppc::front::IFront > **)&jarg1; + arg1 = (ppc::front::IFront *)(smartarg1 ? smartarg1->get() : 0); + if(!jarg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null string"); + return ; + } + const char *arg2_pstr = (const char *)jenv->GetStringUTFChars(jarg2, 0); + if (!arg2_pstr) return ; + std::string arg2_str(arg2_pstr); + arg2 = &arg2_str; + jenv->ReleaseStringUTFChars(jarg2, arg2_pstr); + { + try { + (arg1)->updateMetaInfo((std::string const &)*arg2); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_IFront_1selectNodesByRoutePolicy(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jshort jarg2, jlong jarg3, jobject jarg3_) { + jlong jresult = 0 ; + ppc::front::IFront *arg1 = (ppc::front::IFront *) 0 ; + int16_t arg2 ; + ppc::protocol::MessageOptionalHeader::Ptr *arg3 = 0 ; + std::shared_ptr< ppc::front::IFront > *smartarg1 = 0 ; + ppc::protocol::MessageOptionalHeader::Ptr tempnull3 ; + std::vector< std::string > result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + (void)jarg3_; + + smartarg1 = *(std::shared_ptr< ppc::front::IFront > **)&jarg1; + arg1 = (ppc::front::IFront *)(smartarg1 ? smartarg1->get() : 0); + arg2 = (int16_t)jarg2; + arg3 = jarg3 ? *(ppc::protocol::MessageOptionalHeader::Ptr **)&jarg3 : &tempnull3; + { + try { + result = (arg1)->selectNodesByRoutePolicy(arg2,(ppc::protocol::MessageOptionalHeader::Ptr const &)*arg3); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + *(std::vector< std::string > **)&jresult = new std::vector< std::string >(result); + return jresult; +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_IFront_1getNodeDiscovery(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jlong jresult = 0 ; + ppc::front::IFront *arg1 = (ppc::front::IFront *) 0 ; + std::shared_ptr< ppc::front::IFront > *smartarg1 = 0 ; + ppc::front::INodeDiscovery::Ptr result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< ppc::front::IFront > **)&jarg1; + arg1 = (ppc::front::IFront *)(smartarg1 ? smartarg1->get() : 0); + { + try { + result = (arg1)->getNodeDiscovery(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + *(ppc::front::INodeDiscovery::Ptr **)&jresult = result ? new ppc::front::INodeDiscovery::Ptr(result) : 0; + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_delete_1IFrontBuilder(JNIEnv *jenv, jclass jcls, jlong jarg1) { + ppc::front::IFrontBuilder *arg1 = (ppc::front::IFrontBuilder *) 0 ; + + (void)jenv; + (void)jcls; + arg1 = *(ppc::front::IFrontBuilder **)&jarg1; + { + try { + delete arg1; + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_IFrontBuilder_1buildClient(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jstring jarg2, jlong jarg3, jboolean jarg4) { + jlong jresult = 0 ; + ppc::front::IFrontBuilder *arg1 = (ppc::front::IFrontBuilder *) 0 ; + std::string arg2 ; + std::function< void () > arg3 ; + bool arg4 ; + std::function< void () > *argp3 ; + ppc::front::IFrontClient::Ptr result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(ppc::front::IFrontBuilder **)&jarg1; + if(!jarg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null string"); + return 0; + } + const char *arg2_pstr = (const char *)jenv->GetStringUTFChars(jarg2, 0); + if (!arg2_pstr) return 0; + (&arg2)->assign(arg2_pstr); + jenv->ReleaseStringUTFChars(jarg2, arg2_pstr); + argp3 = *(std::function< void () > **)&jarg3; + if (!argp3) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "Attempt to dereference null std::function< void () >"); + return 0; + } + arg3 = *argp3; + arg4 = jarg4 ? true : false; + { + try { + result = ((ppc::front::IFrontBuilder const *)arg1)->buildClient(arg2,arg3,arg4); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + *(ppc::front::IFrontClient::Ptr **)&jresult = result ? new ppc::front::IFrontClient::Ptr(result) : 0; + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_delete_1INodeDiscovery(JNIEnv *jenv, jclass jcls, jlong jarg1) { + ppc::front::INodeDiscovery *arg1 = (ppc::front::INodeDiscovery *) 0 ; + std::shared_ptr< ppc::front::INodeDiscovery > *smartarg1 = 0 ; + + (void)jenv; + (void)jcls; + + smartarg1 = *(std::shared_ptr< ppc::front::INodeDiscovery > **)&jarg1; + arg1 = (ppc::front::INodeDiscovery *)(smartarg1 ? smartarg1->get() : 0); + { + try { + (void)arg1; delete smartarg1; + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_INodeDiscovery_1getAliveNodeList(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jlong jresult = 0 ; + ppc::front::INodeDiscovery *arg1 = (ppc::front::INodeDiscovery *) 0 ; + std::shared_ptr< ppc::front::INodeDiscovery const > *smartarg1 = 0 ; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< const ppc::front::INodeDiscovery > **)&jarg1; + arg1 = (ppc::front::INodeDiscovery *)(smartarg1 ? smartarg1->get() : 0); + { + try { + result = ((ppc::front::INodeDiscovery const *)arg1)->getAliveNodeList(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + *(std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > **)&jresult = new std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >(result); + return jresult; +} + + +SWIGEXPORT jint JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_SDKMode_1AIR_1get(JNIEnv *jenv, jclass jcls) { + jint jresult = 0 ; + ppc::sdk::SDKMode result; + + (void)jenv; + (void)jcls; + { + try { + result = (ppc::sdk::SDKMode)ppc::sdk::SDKMode::AIR; + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + jresult = (jint)result; + return jresult; +} + + +SWIGEXPORT jint JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_SDKMode_1PRO_1get(JNIEnv *jenv, jclass jcls) { + jint jresult = 0 ; + ppc::sdk::SDKMode result; + + (void)jenv; + (void)jcls; + { + try { + result = (ppc::sdk::SDKMode)ppc::sdk::SDKMode::PRO; + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + jresult = (jint)result; + return jresult; +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_new_1TransportBuilder(JNIEnv *jenv, jclass jcls) { + jlong jresult = 0 ; + ppc::sdk::TransportBuilder *result = 0 ; + + (void)jenv; + (void)jcls; + { + try { + result = (ppc::sdk::TransportBuilder *)new ppc::sdk::TransportBuilder(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + *(ppc::sdk::TransportBuilder **)&jresult = result; + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_delete_1TransportBuilder(JNIEnv *jenv, jclass jcls, jlong jarg1) { + ppc::sdk::TransportBuilder *arg1 = (ppc::sdk::TransportBuilder *) 0 ; + + (void)jenv; + (void)jcls; + arg1 = *(ppc::sdk::TransportBuilder **)&jarg1; + { + try { + delete arg1; + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_TransportBuilder_1buildProTransport(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2, jobject jarg2_) { + jlong jresult = 0 ; + ppc::sdk::TransportBuilder *arg1 = (ppc::sdk::TransportBuilder *) 0 ; + ppc::front::FrontConfig::Ptr arg2 ; + ppc::front::FrontConfig::Ptr *argp2 ; + ppc::sdk::Transport::Ptr result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + (void)jarg2_; + arg1 = *(ppc::sdk::TransportBuilder **)&jarg1; + argp2 = *(ppc::front::FrontConfig::Ptr **)&jarg2; + if (argp2) arg2 = *argp2; + { + try { + result = (arg1)->buildProTransport(arg2); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + *(ppc::sdk::Transport::Ptr **)&jresult = result ? new ppc::sdk::Transport::Ptr(result) : 0; + return jresult; +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_TransportBuilder_1buildConfig(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jint jarg2, jstring jarg3) { + jlong jresult = 0 ; + ppc::sdk::TransportBuilder *arg1 = (ppc::sdk::TransportBuilder *) 0 ; + int arg2 ; + std::string arg3 ; + ppc::front::FrontConfig::Ptr result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(ppc::sdk::TransportBuilder **)&jarg1; + arg2 = (int)jarg2; + if(!jarg3) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null string"); + return 0; + } + const char *arg3_pstr = (const char *)jenv->GetStringUTFChars(jarg3, 0); + if (!arg3_pstr) return 0; + (&arg3)->assign(arg3_pstr); + jenv->ReleaseStringUTFChars(jarg3, arg3_pstr); + { + try { + result = (arg1)->buildConfig(arg2,arg3); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + *(ppc::front::FrontConfig::Ptr **)&jresult = result ? new ppc::front::FrontConfig::Ptr(result) : 0; + return jresult; +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_TransportBuilder_1frontConfigBuilder(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jlong jresult = 0 ; + ppc::sdk::TransportBuilder *arg1 = (ppc::sdk::TransportBuilder *) 0 ; + ppc::front::FrontConfigBuilder::Ptr *result = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(ppc::sdk::TransportBuilder **)&jarg1; + { + try { + result = (ppc::front::FrontConfigBuilder::Ptr *) &(arg1)->frontConfigBuilder(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + *(ppc::front::FrontConfigBuilder::Ptr **)&jresult = result; + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_TransportBuilder_1initLog(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jstring jarg2) { + ppc::sdk::TransportBuilder *arg1 = (ppc::sdk::TransportBuilder *) 0 ; + std::string *arg2 = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(ppc::sdk::TransportBuilder **)&jarg1; + if(!jarg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null string"); + return ; + } + const char *arg2_pstr = (const char *)jenv->GetStringUTFChars(jarg2, 0); + if (!arg2_pstr) return ; + std::string arg2_str(arg2_pstr); + arg2 = &arg2_str; + jenv->ReleaseStringUTFChars(jarg2, arg2_pstr); + { + try { + (arg1)->initLog((std::string const &)*arg2); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_new_1Transport(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jlong jresult = 0 ; + ppc::front::FrontConfig::Ptr arg1 ; + ppc::front::FrontConfig::Ptr *argp1 ; + ppc::sdk::Transport *result = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + argp1 = *(ppc::front::FrontConfig::Ptr **)&jarg1; + if (argp1) arg1 = *argp1; + { + try { + result = (ppc::sdk::Transport *)new ppc::sdk::Transport(arg1); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + + *(std::shared_ptr< ppc::sdk::Transport > **)&jresult = result ? new std::shared_ptr< ppc::sdk::Transport >(result SWIG_NO_NULL_DELETER_1) : 0; + + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_delete_1Transport(JNIEnv *jenv, jclass jcls, jlong jarg1) { + ppc::sdk::Transport *arg1 = (ppc::sdk::Transport *) 0 ; + std::shared_ptr< ppc::sdk::Transport > *smartarg1 = 0 ; + + (void)jenv; + (void)jcls; + + smartarg1 = *(std::shared_ptr< ppc::sdk::Transport > **)&jarg1; + arg1 = (ppc::sdk::Transport *)(smartarg1 ? smartarg1->get() : 0); + { + try { + (void)arg1; delete smartarg1; + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_Transport_1start(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + ppc::sdk::Transport *arg1 = (ppc::sdk::Transport *) 0 ; + std::shared_ptr< ppc::sdk::Transport > *smartarg1 = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< ppc::sdk::Transport > **)&jarg1; + arg1 = (ppc::sdk::Transport *)(smartarg1 ? smartarg1->get() : 0); + { + try { + (arg1)->start(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_Transport_1stop(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + ppc::sdk::Transport *arg1 = (ppc::sdk::Transport *) 0 ; + std::shared_ptr< ppc::sdk::Transport > *smartarg1 = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< ppc::sdk::Transport > **)&jarg1; + arg1 = (ppc::sdk::Transport *)(smartarg1 ? smartarg1->get() : 0); + { + try { + (arg1)->stop(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return ; + } + } +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_Transport_1getFront(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jlong jresult = 0 ; + ppc::sdk::Transport *arg1 = (ppc::sdk::Transport *) 0 ; + std::shared_ptr< ppc::sdk::Transport const > *smartarg1 = 0 ; + ppc::front::IFront::Ptr *result = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< const ppc::sdk::Transport > **)&jarg1; + arg1 = (ppc::sdk::Transport *)(smartarg1 ? smartarg1->get() : 0); + { + try { + result = (ppc::front::IFront::Ptr *) &((ppc::sdk::Transport const *)arg1)->getFront(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + *(ppc::front::IFront::Ptr **)&jresult = *result ? new ppc::front::IFront::Ptr(*result) : 0; + return jresult; +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_Transport_1gateway(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jlong jresult = 0 ; + ppc::sdk::Transport *arg1 = (ppc::sdk::Transport *) 0 ; + std::shared_ptr< ppc::sdk::Transport const > *smartarg1 = 0 ; + ppc::gateway::IGateway::Ptr *result = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< const ppc::sdk::Transport > **)&jarg1; + arg1 = (ppc::sdk::Transport *)(smartarg1 ? smartarg1->get() : 0); + { + try { + result = (ppc::gateway::IGateway::Ptr *) &((ppc::sdk::Transport const *)arg1)->gateway(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + *(ppc::gateway::IGateway::Ptr **)&jresult = result; + return jresult; +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_Transport_1msgPayloadBuilder(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jlong jresult = 0 ; + ppc::sdk::Transport *arg1 = (ppc::sdk::Transport *) 0 ; + std::shared_ptr< ppc::sdk::Transport const > *smartarg1 = 0 ; + ppc::protocol::MessagePayloadBuilder::Ptr *result = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< const ppc::sdk::Transport > **)&jarg1; + arg1 = (ppc::sdk::Transport *)(smartarg1 ? smartarg1->get() : 0); + { + try { + result = (ppc::protocol::MessagePayloadBuilder::Ptr *) &((ppc::sdk::Transport const *)arg1)->msgPayloadBuilder(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + *(ppc::protocol::MessagePayloadBuilder::Ptr **)&jresult = *result ? new ppc::protocol::MessagePayloadBuilder::Ptr(*result) : 0; + return jresult; +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_Transport_1msgBuilder(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jlong jresult = 0 ; + ppc::sdk::Transport *arg1 = (ppc::sdk::Transport *) 0 ; + std::shared_ptr< ppc::sdk::Transport const > *smartarg1 = 0 ; + ppc::protocol::MessageBuilder::Ptr *result = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< const ppc::sdk::Transport > **)&jarg1; + arg1 = (ppc::sdk::Transport *)(smartarg1 ? smartarg1->get() : 0); + { + try { + result = (ppc::protocol::MessageBuilder::Ptr *) &((ppc::sdk::Transport const *)arg1)->msgBuilder(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + *(ppc::protocol::MessageBuilder::Ptr **)&jresult = *result ? new ppc::protocol::MessageBuilder::Ptr(*result) : 0; + return jresult; +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_Transport_1msgHeaderBuilder(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jlong jresult = 0 ; + ppc::sdk::Transport *arg1 = (ppc::sdk::Transport *) 0 ; + std::shared_ptr< ppc::sdk::Transport const > *smartarg1 = 0 ; + ppc::protocol::MessageHeaderBuilder::Ptr *result = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< const ppc::sdk::Transport > **)&jarg1; + arg1 = (ppc::sdk::Transport *)(smartarg1 ? smartarg1->get() : 0); + { + try { + result = (ppc::protocol::MessageHeaderBuilder::Ptr *) &((ppc::sdk::Transport const *)arg1)->msgHeaderBuilder(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + *(ppc::protocol::MessageHeaderBuilder::Ptr **)&jresult = *result ? new ppc::protocol::MessageHeaderBuilder::Ptr(*result) : 0; + return jresult; +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_Transport_1routeInfoBuilder(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jlong jresult = 0 ; + ppc::sdk::Transport *arg1 = (ppc::sdk::Transport *) 0 ; + std::shared_ptr< ppc::sdk::Transport const > *smartarg1 = 0 ; + ppc::protocol::MessageOptionalHeaderBuilder::Ptr *result = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< const ppc::sdk::Transport > **)&jarg1; + arg1 = (ppc::sdk::Transport *)(smartarg1 ? smartarg1->get() : 0); + { + try { + result = (ppc::protocol::MessageOptionalHeaderBuilder::Ptr *) &((ppc::sdk::Transport const *)arg1)->routeInfoBuilder(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + *(ppc::protocol::MessageOptionalHeaderBuilder::Ptr **)&jresult = *result ? new ppc::protocol::MessageOptionalHeaderBuilder::Ptr(*result) : 0; + return jresult; +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_Transport_1getConfig(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jlong jresult = 0 ; + ppc::sdk::Transport *arg1 = (ppc::sdk::Transport *) 0 ; + std::shared_ptr< ppc::sdk::Transport const > *smartarg1 = 0 ; + ppc::front::FrontConfig::Ptr *result = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + + smartarg1 = *(std::shared_ptr< const ppc::sdk::Transport > **)&jarg1; + arg1 = (ppc::sdk::Transport *)(smartarg1 ? smartarg1->get() : 0); + { + try { + result = (ppc::front::FrontConfig::Ptr *) &((ppc::sdk::Transport const *)arg1)->getConfig(); + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return 0; + } + } + *(ppc::front::FrontConfig::Ptr **)&jresult = *result ? new ppc::front::FrontConfig::Ptr(*result) : 0; + return jresult; +} + + +SWIGEXPORT jlong JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_IFront_1SWIGSmartPtrUpcast(JNIEnv *jenv, jclass jcls, jlong jarg1) { + jlong baseptr = 0; + std::shared_ptr< ppc::front::IFront > *argp1; + (void)jenv; + (void)jcls; + argp1 = *(std::shared_ptr< ppc::front::IFront > **)&jarg1; + *(std::shared_ptr< ppc::front::IFrontClient > **)&baseptr = argp1 ? new std::shared_ptr< ppc::front::IFrontClient >(*argp1) : 0; + return baseptr; +} + +SWIGEXPORT void JNICALL Java_com_webank_wedpr_sdk_jni_generated_wedpr_1java_1transportJNI_swig_1module_1init(JNIEnv *jenv, jclass jcls) { + int i; + + static struct { + const char *method; + const char *signature; + } methods[4] = { + { + "SwigDirector_ErrorCallback_onError", "(Lcom/webank/wedpr/sdk/jni/generated/ErrorCallback;J)V" + }, + { + "SwigDirector_MessageDispatcherHandler_onMessage", "(Lcom/webank/wedpr/sdk/jni/generated/MessageDispatcherHandler;J)V" + }, + { + "SwigDirector_IMessageHandler_onMessage", "(Lcom/webank/wedpr/sdk/jni/generated/IMessageHandler;JJJ)V" + }, + { + "SwigDirector_GetPeersInfoHandler_onPeersInfo", "(Lcom/webank/wedpr/sdk/jni/generated/GetPeersInfoHandler;JLjava/lang/String;)V" + } + }; + Swig::jclass_wedpr_java_transportJNI = (jclass) jenv->NewGlobalRef(jcls); + if (!Swig::jclass_wedpr_java_transportJNI) return; + for (i = 0; i < (int) (sizeof(methods)/sizeof(methods[0])); ++i) { + Swig::director_method_ids[i] = jenv->GetStaticMethodID(jcls, methods[i].method, methods[i].signature); + if (!Swig::director_method_ids[i]) return; + } +} + + +#ifdef __cplusplus +} +#endif + diff --git a/cpp/wedpr-transport/sdk-wrapper/java/src/wedpr_java_transportJAVA_wrap.h b/cpp/wedpr-transport/sdk-wrapper/java/src/wedpr_java_transportJAVA_wrap.h new file mode 100644 index 00000000..2a61714c --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/src/wedpr_java_transportJAVA_wrap.h @@ -0,0 +1,73 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (https://www.swig.org). + * Version 4.2.1 + * + * Do not make changes to this file unless you know what you are doing - modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +#ifndef SWIG_wedpr_java_transport_WRAP_H_ +#define SWIG_wedpr_java_transport_WRAP_H_ + +class SwigDirector_ErrorCallback : public ppc::front::ErrorCallback, public Swig::Director { + +public: + void swig_connect_director(JNIEnv *jenv, jobject jself, jclass jcls, bool swig_mem_own, bool weak_global); + SwigDirector_ErrorCallback(JNIEnv *jenv); + virtual ~SwigDirector_ErrorCallback(); + virtual void onError(bcos::Error::Ptr error); +public: + bool swig_overrides(int n) { + return (n < 1 ? swig_override[n] : false); + } +protected: + Swig::BoolArray<1> swig_override; +}; + +class SwigDirector_MessageDispatcherHandler : public ppc::front::MessageDispatcherHandler, public Swig::Director { + +public: + void swig_connect_director(JNIEnv *jenv, jobject jself, jclass jcls, bool swig_mem_own, bool weak_global); + SwigDirector_MessageDispatcherHandler(JNIEnv *jenv); + virtual ~SwigDirector_MessageDispatcherHandler(); + virtual void onMessage(ppc::protocol::Message::Ptr msg); +public: + bool swig_overrides(int n) { + return (n < 1 ? swig_override[n] : false); + } +protected: + Swig::BoolArray<1> swig_override; +}; + +class SwigDirector_IMessageHandler : public ppc::front::IMessageHandler, public Swig::Director { + +public: + void swig_connect_director(JNIEnv *jenv, jobject jself, jclass jcls, bool swig_mem_own, bool weak_global); + SwigDirector_IMessageHandler(JNIEnv *jenv); + virtual ~SwigDirector_IMessageHandler(); + virtual void onMessage(bcos::Error::Ptr e,ppc::protocol::Message::Ptr msg,ppc::front::SendResponseHandler sendResponseHandler); +public: + bool swig_overrides(int n) { + return (n < 1 ? swig_override[n] : false); + } +protected: + Swig::BoolArray<1> swig_override; +}; + +class SwigDirector_GetPeersInfoHandler : public ppc::front::GetPeersInfoHandler, public Swig::Director { + +public: + void swig_connect_director(JNIEnv *jenv, jobject jself, jclass jcls, bool swig_mem_own, bool weak_global); + SwigDirector_GetPeersInfoHandler(JNIEnv *jenv); + virtual ~SwigDirector_GetPeersInfoHandler(); + virtual void onPeersInfo(bcos::Error::Ptr e,std::string const &peersInfo); +public: + bool swig_overrides(int n) { + return (n < 1 ? swig_override[n] : false); + } +protected: + Swig::BoolArray<1> swig_override; +}; + + +#endif diff --git a/cpp/wedpr-transport/sdk-wrapper/java/swig/wedpr_java_transport.i b/cpp/wedpr-transport/sdk-wrapper/java/swig/wedpr_java_transport.i new file mode 100644 index 00000000..879134e6 --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/java/swig/wedpr_java_transport.i @@ -0,0 +1,292 @@ +%module(directors="1") wedpr_java_transport + +%include "stdint.i" +%include "typemaps.i" + +#if defined(SWIGJAVA) +#if defined(SWIGWORDSIZE64) +// By default SWIG map C++ long int (i.e. int64_t) to C# int +// But we want to map it to C# long so we reuse the typemap for C++ long long. +// ref: https://github.com/swig/swig/blob/master/Lib/java/typemaps.i +// ref: https://docs.oracle.com/en/java/javase/14/docs/api/java.base/java/lang/Long.html +%define PRIMITIVE_TYPEMAP(NEW_TYPE, TYPE) +%clear NEW_TYPE; +%clear NEW_TYPE *; +%clear NEW_TYPE &; +%clear const NEW_TYPE &; +%apply TYPE { NEW_TYPE }; +%apply TYPE * { NEW_TYPE * }; +%apply TYPE & { NEW_TYPE & }; +%apply const TYPE & { const NEW_TYPE & }; +%enddef // PRIMITIVE_TYPEMAP +PRIMITIVE_TYPEMAP(long int, long long); +PRIMITIVE_TYPEMAP(unsigned long int, long long); +#undef PRIMITIVE_TYPEMAP +#endif // defined(SWIGWORDSIZE64) +#endif // defined(SWIGJAVA) + + +%include +%include +%include +%include +%include +%include + +// shared_ptr definition +%shared_ptr(ppc::front::FrontConfig); +%shared_ptr(ppc::front::INodeDiscovery); +%shared_ptr(ppc::protocol::INodeInfo); +%shared_ptr(ppc::front::IFront); +%shared_ptr(ppc::front::IFrontClient); +// the callbacks +%shared_ptr(ppc::front::ErrorCallback); +%shared_ptr(ppc::front::MessageDispatcherHandler); +%shared_ptr(ppc::front::IMessageHandler); +%shared_ptr(ppc::front::GetPeersInfoHandler); + +%shared_ptr(ppc::gateway::IGateway); +%shared_ptr(bcos::Error); +%shared_ptr(bcos::bytes); +%shared_ptr(ppc::protocol::Message); +%shared_ptr(ppc::protocol::MessageOptionalHeader); +%shared_ptr(ppc::protocol::MessageHeader); +%shared_ptr(ppc::protocol::MessagePayload); +%shared_ptr(ppc::protocol::MessageBuilder); +%shared_ptr(ppc::protocol::MessageHeaderBuilder); +%shared_ptr(ppc::protocol::MessagePayloadBuilder); +%shared_ptr(ppc::protocol::MessageOptionalHeaderBuilder); +%shared_ptr(ppc::protocol::GrpcConfig); +%shared_ptr(ppc::sdk::Transport); + + +%{ +#define SWIG_FILE_WITH_INIT +#include +#include +#include +#include "wedpr-transport/sdk/src/TransportBuilder.h" +#include "wedpr-transport/sdk/src/Transport.h" +#include "ppc-framework/libwrapper/Buffer.h" +#include "ppc-framework/front/IFront.h" +#include "ppc-framework/protocol/INodeInfo.h" +#include "ppc-framework/front/INodeDiscovery.h" +#include "ppc-framework/protocol/RouteType.h" +#include "ppc-framework/front/FrontConfig.h" +#include "ppc-framework/protocol/GrpcConfig.h" +#include +#include "ppc-framework/protocol/EndPoint.h" +#include "ppc-framework/protocol/Message.h" +#include "ppc-framework/protocol/MessagePayload.h" +%} + +namespace ppc::sdk{ + class Transport; + class TransportBuilder; +} + +namespace ppc::gateway{ + class IGateway; +} + +namespace ppc::protocol{ + class Message; + class MessageHeader; + class MessagePayload; + class MessageOptionalHeader; + class MessageBuilder; + class MessageHeaderBuilder; + class MessagePayloadBuilder; + class MessageOptionalHeaderBuilder; + class EndPoint; + class GrpcConfig; + class RouteType; + class INodeInfo; +} + +namespace ppc::front{ + class FrontConfig; + class IFront; + class INodeDiscovery; + class IFrontClient; + class FrontImpl; + class FrontBuilderImpl; + class GatewayEndPoint; + class ErrorCallback; + class MessageDispatcherHandler; + class IMessageHandler; + class SendResponseHandler; +} + +namespace std{ + class vector; + class string; +} + +namespace bcos{ + using byte = uint8_t; + using bytes = std::vector; + class Error; +} + +// define shared_ptr objects +%template(SharedBcosError) std::shared_ptr; + +%template(SharedFrontConfig) std::shared_ptr; +%template(SharedGrpcConfig) std::shared_ptr; + +%template(SharedFront) std::shared_ptr; +%template(SharedNodeDiscovery) std::shared_ptr; + +%template(SharedFrontClient) std::shared_ptr; + +%template(SharedErrorCallback) std::shared_ptr; +%template(SharedMessageDispatcherHandler) std::shared_ptr; +%template(SharedIMessageHandler) std::shared_ptr; +%template(SharedGetPeersInfoHandler) std::shared_ptr; + +%template(SharedGateway) std::shared_ptr; + +%template(SharedMessage) std::shared_ptr; +%template(SharedMessageHeader) std::shared_ptr; +%template(SharedMessagePayload) std::shared_ptr; +%template(SharedRouteInfo) std::shared_ptr; + +%template(SharedMessageBuilder) std::shared_ptr; +%template(SharedMessageHeaderBuilder) std::shared_ptr; +%template(SharedMessagePayloadBuilder) std::shared_ptr; +%template(SharedRouteInfoBuilder) std::shared_ptr; +%template(SharedNodeInfo) std::shared_ptr; + +%template(ubytes) std::vector; +%template(ibytes) std::vector; +%template(StringVec) std::vector; +%template(NodeInfoVec) std::vector>; + +/// callbacks +%feature("director") ppc::front::ErrorCallback; +%feature("director") ppc::front::MessageDispatcherHandler; +%feature("director") ppc::front::IMessageHandler; +%feature("director") ppc::front::GetPeersInfoHandler; + +// Note: the field data should equal to the fieldMap of class or the function +%include various.i +// this means convert all (char*) to byte[] +%apply char *BYTE {char * }; + + +%typemap(jni) OutputBuffer "jbyteArray" +%typemap(jtype) OutputBuffer "byte[]" +%typemap(jstype) OutputBuffer "byte[]" +%typemap(in) OutputBuffer { + $1.data = (unsigned char *) JCALL2(GetByteArrayElements, jenv, $input, 0); + $1.len = JCALL1(GetArrayLength, jenv, $input); +} +%typemap(argout) OutputBuffer { + JCALL3(ReleaseByteArrayElements, jenv, $input, (jbyte *) $1.data, 0); +} +// Note: will cause copy here +%typemap(out) OutputBuffer { + $result = JCALL1(NewByteArray, jenv, $1.len); + JCALL4(SetByteArrayRegion, jenv, $result, 0, $1.len, (jbyte *) $1.data); +} +%typemap(javain) OutputBuffer "$javainput" +%typemap(javaout) OutputBuffer { return $jnicall; } + + + +// refer to: https://stackoverflow.com/questions/12103206/is-it-possible-to-add-text-to-an-existing-typemap-in-swig +%define WRAP(CLASS) +%extend CLASS { +%proxycode %{ + public void disOwnMemory() { + swigSetCMemOwn(false); + } +%} +} +%enddef + +// Note: these object is created from cpp, and maintained with shared_ptr, +// the java code should disOwnMemory in case of released multiple times +WRAP(ppc::front::FrontConfig) +WRAP(ppc::protocol::Message) +WRAP(ppc::protocol::MessageOptionalHeader) +WRAP(ppc::protocol::MessageHeader) +WRAP(ppc::protocol::MessagePayload) +WRAP(ppc::protocol::MessageBuilder) +WRAP(ppc::protocol::MessageHeaderBuilder) +WRAP(ppc::protocol::MessagePayloadBuilder) +WRAP(ppc::protocol::MessageOptionalHeaderBuilder) +WRAP(ppc::sdk::Transport) + +// the method no need to wrapper +%ignore ppc::sdk::TransportBuilder::build; +%ignore ppc::front::IFront::onReceiveMessage; +%ignore ppc::front::IFront::asyncSendMessage; +%ignore ppc::front::IFront::asyncGetAgencies; +%ignore ppc::front::IFront::registerTopicHandler; +%ignore ppc::front::IFront::registerMessageHandler; +%ignore ppc::front::IFront::asyncSendResponse; +%ignore ppc::front::IFront::populateErrorCallback; +%ignore ppc::front::IFront::populateMessageDispatcherCallback; +%ignore ppc::front::IFront::populateMsgCallback; +%ignore ppc::front::IFront::push; +%ignore ppc::front::IFront::registerNodeInfo; +%ignore ppc::front::IFront::unRegisterNodeInfo; +%ignore ppc::protocol::MessageOptionalHeader::srcNode; +%ignore ppc::protocol::MessageOptionalHeader::dstNode; +%ignore ppc::protocol::MessageOptionalHeader::setDstNode; +%ignore ppc::protocol::MessageOptionalHeader::setSrcNode; +%ignore ppc::protocol::MessagePayload::data; +%ignore ppc::protocol::MessagePayload::setData; +%ignore ppc::protocol::MessagePayload::setDataPtr; +%ignore ppc::protocol::MessagePayload::dataPtr; +%ignore ppc::front::INodeDiscovery::start; +%ignore ppc::front::INodeDiscovery::stop; +%ignore ppc::protocol::INodeInfo::INodeInfo; +%ignore ppc::protocol::INodeInfo::setFront; +%ignore ppc::protocol::INodeInfo::getFront; +%ignore ppc::protocol::INodeInfo::components; +%ignore ppc::protocol::INodeInfo::encode; +%ignore ppc::protocol::INodeInfo::decode; +%ignore ppc::protocol::INodeInfo::equal; +%ignore ppc::protocol::INodeInfo::toJson; +%ignore ppc::protocol::INodeInfo::setComponents; +%ignore ppc::protocol::INodeInfoFactory; +%ignore ppc::protocol::Message::setFrontMessage; +%ignore ppc::protocol::GrpcConfig::~GrpcConfig; +%ignore ppc::protocol::GrpcServerConfig::~GrpcServerConfig; + +%include "exception.i" +%exception { + try { + $action + } + catch (const std::exception& e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string(boost::diagnostic_information(e)).c_str()); + return $null; + } +} + +/* +///// tests /// +%inline { +} +///// tests /// +*/ + +// define the interface should been exposed +%include "bcos-utilities/Error.h" +%include "ppc-framework/libwrapper/Buffer.h" +%include "ppc-framework/front/FrontConfig.h" +%include "ppc-framework/protocol/EndPoint.h" +%include "ppc-framework/protocol/GrpcConfig.h" +%include "ppc-framework/protocol/Message.h" +%include "ppc-framework/protocol/MessagePayload.h" +%include "ppc-framework/protocol/INodeInfo.h" + +%include "ppc-framework/front/IFront.h" +%include "ppc-framework/front/INodeDiscovery.h" + +%include "wedpr-transport/sdk/src/TransportBuilder.h" +%include "wedpr-transport/sdk/src/Transport.h" \ No newline at end of file diff --git a/cpp/wedpr-transport/sdk-wrapper/python/CMakeLists.txt b/cpp/wedpr-transport/sdk-wrapper/python/CMakeLists.txt new file mode 100644 index 00000000..dffb7cdf --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/python/CMakeLists.txt @@ -0,0 +1,51 @@ +option(AUTO_GENERATE "Auto generate the targes" OFF) +# Note: use SWIG Version 4.2.1 +if(AUTO_GENERATE) + file(GLOB_RECURSE SRCS *.i) + set_source_files_properties(${SRCS} PROPERTIES CPLUSPLUS ON) + + file(MAKE_DIRECTORY ${WEDPR_PYTHON_TRANSPORT_DIR}) + file(MAKE_DIRECTORY ${WEDPR_PYTHON_TRANSPORT_LIB_DIR}) + + swig_add_library( + ${WEDPR_PYTHON_TRANSPORT} + TYPE MODULE + LANGUAGE python + OUTPUT_DIR ${WEDPR_PYTHON_TRANSPORT_DIR} + SOURCES ${SRCS} + ) + set_property(TARGET ${WEDPR_PYTHON_TRANSPORT} PROPERTY SWIG_USE_TARGET_INCLUDE_DIRECTORIES ON) +else() + file(GLOB_RECURSE SRCS src/*.cxx) + add_library(${WEDPR_PYTHON_TRANSPORT} SHARED ${SRCS}) +endif() + +target_include_directories(${WEDPR_PYTHON_TRANSPORT} PRIVATE ${Python_INCLUDE_DIRS}) + +# note: macOS is APPLE and also UNIX ! +if(APPLE) + set_property(TARGET ${WEDPR_PYTHON_TRANSPORT} APPEND PROPERTY + LINK_FLAGS "-flat_namespace -undefined suppress" + ) + set_target_properties(${WEDPR_PYTHON_TRANSPORT} PROPERTIES + INSTALL_RPATH "@loader_path;@loader_path/../../${WEDPR_PYTHON_TRANSPORT}/.libs" + ) +elseif(UNIX) + set_target_properties(${WEDPR_PYTHON_TRANSPORT} PROPERTIES + INSTALL_RPATH "$ORIGIN:$ORIGIN/../../${WEDPR_PYTHON_TRANSPORT}/.libs" + ) +endif() +# Variable PYTHON_LIBRARIES can contains keyword `optimized` +# which won't be interpreted inside a generator expression. +# i.e. we can't use: $<$:${PYTHON_LIBRARIES}> +# see: https://cmake.org/cmake/help/git-stage/command/target_link_libraries.html#command:target_link_libraries +#if(MSVC) +# message("## Python3_LIBRARIES: ${Python3_LIBRARIES}") +# target_link_libraries(${WEDPR_PYTHON_TRANSPORT} PRIVATE ${WEDPR_TRANSPORT_SDK_TARGET} ${Python3_LIBRARIES}) +#else() +target_link_libraries(${WEDPR_PYTHON_TRANSPORT} PRIVATE ${WEDPR_TRANSPORT_SDK_TARGET}) +#endif() +SET(LIBRARY_OUTPUT_PATH ${WEDPR_PYTHON_TRANSPORT_LIB_DIR}) + +message(STATUS "CMAKE_INSTALL_INCLUDEDIR => ${CMAKE_INSTALL_INCLUDEDIR}") +message(STATUS "CMAKE_CURRENT_SOURCE_DIR => ${CMAKE_CURRENT_SOURCE_DIR}") \ No newline at end of file diff --git a/cpp/wedpr-transport/sdk-wrapper/python/bindings/CHANGELOG.md b/cpp/wedpr-transport/sdk-wrapper/python/bindings/CHANGELOG.md new file mode 100644 index 00000000..e69de29b diff --git a/cpp/wedpr-transport/sdk-wrapper/python/bindings/MANIFEST.in b/cpp/wedpr-transport/sdk-wrapper/python/bindings/MANIFEST.in new file mode 100644 index 00000000..98b18675 --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/python/bindings/MANIFEST.in @@ -0,0 +1,3 @@ +include CHANGELOG.md +include *requirements.txt +include ./wedpr_python_gateway_sdk/libs/libwedpr_python_transport* diff --git a/cpp/wedpr-transport/sdk-wrapper/python/bindings/demo/__init__.py b/cpp/wedpr-transport/sdk-wrapper/python/bindings/demo/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/cpp/wedpr-transport/sdk-wrapper/python/bindings/demo/transport_demo.py b/cpp/wedpr-transport/sdk-wrapper/python/bindings/demo/transport_demo.py new file mode 100644 index 00000000..061b7a24 --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/python/bindings/demo/transport_demo.py @@ -0,0 +1,109 @@ +# -*- coding: utf-8 -*- +import sys +import os +# Note: here can't be refactored by autopep +root_path = os.path.abspath(os.path.dirname(__file__)) +sys.path.append(os.path.join(root_path, "../")) +# Note: here can't be refactored by autopep + +import time +from wedpr_python_gateway_sdk.transport.impl.transport_loader import TransportLoader +from wedpr_python_gateway_sdk.transport.impl.transport_config import TransportConfig +from wedpr_python_gateway_sdk.transport.impl.transport import Transport +from wedpr_python_gateway_sdk.transport.impl.transport import RouteType +import traceback +import argparse + + +def parse_args(): + parser = argparse.ArgumentParser(prog=sys.argv[0]) + parser.add_argument("-t", '--threadpool_size', + help='the threadpool size', default=4, required=True) + parser.add_argument('--dst_inst', + help='the dist inst', default=None, required=True) + parser.add_argument("-n", '--node_id', + help='the nodeID', required=False) + parser.add_argument("-g", '--gateway_targets', + help='the gateway targets, e.g: ipv4:127.0.0.1:40620,127.0.0.1:40621', required=True) + parser.add_argument("-i", '--host_ip', + help='the host ip, e.g.: 127.0.0.1', required=True) + parser.add_argument("-p", "--listen_port", + help="the listen port", required=True) + parser.add_argument("-d", "--dst_node", + help="the dst node", required=True) + args = parser.parse_args() + return args + + +def message_event_loop(args): + transport_config = TransportConfig( + int(args.threadpool_size), args.node_id, args.gateway_targets) + transport_config.set_self_endpoint( + args.host_ip, int(args.listen_port), "0.0.0.0") + # def register_service_info(self, service, entrypoint): + service_name = "python_service_demo" + entrypoint = f"{args.host_ip}:{args.listen_port}" + transport_config.register_service_info(service_name, entrypoint) + service_name2 = "python_service_demo2" + transport_config.register_service_info(service_name2, entrypoint) + + transport = TransportLoader.load(transport_config) + print(f"Create transport success, config: {transport_config.desc()}") + transport.start() + component = "WEDPR_COMPONENT_TEST" + transport.register_component(component) + print(f"Start transport success") + test_topic = "sync_message_event_loop_test" + # register service after start + service_name3 = "python_service_demo3" + transport.register_service_info(service_name3, entrypoint) + while Transport.should_exit is False: + try: + # fetch the alive entrypoints + alive_endpoint = transport.get_alive_entrypoints(service_name) + print(f"##### alive_endpoint: {alive_endpoint}") + alive_endpoint2 = transport.get_alive_entrypoints(service_name2) + print(f"##### alive_endpoint2: {alive_endpoint2}") + alive_endpoint3 = transport.get_alive_entrypoints(service_name3) + print(f"##### alive_endpoint3: {alive_endpoint3}") + payload = b"test" + transport.push_by_nodeid(topic=test_topic, dstNode=bytes(args.dst_node, encoding="utf-8"), + seq=0, payload=payload, timeout=6000) + msg = transport.pop(test_topic, timeout_ms=6000) + if msg is None: + print("Receive message timeout") + continue + print( + f"Receive message: {msg.detail()}, buffer: {str(msg.get_payload())}") + + node_list = transport.select_node_list_by_route_policy(route_type=RouteType.ROUTE_THROUGH_COMPONENT, + dst_inst=args.dst_inst, + dst_component=component) + if node_list is None: + print( + f"####select_node_list_by_route_policy: not find component: {component}") + continue + for node in node_list: + print( + f"##### select_node_list_by_route_policy result: {node}, component: {component}") + + selected_node = transport.select_node_by_route_policy(route_type=RouteType.ROUTE_THROUGH_COMPONENT, + dst_inst=args.dst_inst, + dst_component=component) + if selected_node is None: + print( + f"####select_node_by_route_policy: not find component: {component}") + print( + f"##### select_node_by_route_policy, selected_node: {selected_node}, component: {component}") + except Exception as e: + traceback.print_exc() + print(f"exception: {e}") + time.sleep(2) + print(f"stop the transport") + transport.stop() + print(f"stop the transport successfully") + + +if __name__ == "__main__": + args = parse_args() + message_event_loop(args) diff --git a/cpp/wedpr-transport/sdk-wrapper/python/bindings/requirements.txt b/cpp/wedpr-transport/sdk-wrapper/python/bindings/requirements.txt new file mode 100644 index 00000000..e69de29b diff --git a/cpp/wedpr-transport/sdk-wrapper/python/bindings/setup.py b/cpp/wedpr-transport/sdk-wrapper/python/bindings/setup.py new file mode 100644 index 00000000..55d37361 --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/python/bindings/setup.py @@ -0,0 +1,65 @@ +import sys + +from setuptools import find_packages, setup +from setuptools.command.bdist_egg import bdist_egg + + +class bdist_egg_disabled(bdist_egg): + """Disabled version of bdist_egg + + Prevents setup.py install from performing setuptools' default easy_install, + which it should never ever do. + """ + + def run(self): + sys.exit( + "Aborting implicit building of eggs. Use `pip install .` to install from source." + ) + + +setup_args = dict( + name='wedpr-python-gateway-sdk', + packages=find_packages(), + version="1.0.0-rc1-20241018", + description="wedpr-python-gateway-sdk: The gateway sdk for WeDPR", + long_description_content_type="text/markdown", + author="WeDPR Development Team", + author_email="wedpr@webank.com", + url="https://github.com/WeBankBlockchain/WeDPR-Component", + license="Apache-2.0", + platforms="Linux, Mac OS X", + keywords=['Interactive', 'Interpreter', 'Shell', 'Web'], + python_requires=">=3.8", + include_package_data=True, + package_data={ + # the library setting + '': ['wedpr_python_gateway_sdk/libs/libwedpr_python_transport.*'], + }, + classifiers=[ + 'Intended Audience :: Developers', + 'Intended Audience :: System Administrators', + 'Intended Audience :: Science/Research', + 'Programming Language :: Python', + 'Programming Language :: Python :: 3', + ], +) + +setup_args['cmdclass'] = { + 'bdist_egg': bdist_egg if 'bdist_egg' in sys.argv else bdist_egg_disabled, +} + +setup_args['install_requires'] = install_requires = [] +with open('requirements.txt') as f: + for line in f.readlines(): + req = line.strip() + if not req or req.startswith(('-e', '#')): + continue + install_requires.append(req) + + +def main(): + setup(**setup_args) + + +if __name__ == '__main__': + main() diff --git a/cpp/wedpr-transport/sdk-wrapper/python/bindings/wedpr_python_gateway_sdk/__init__.py b/cpp/wedpr-transport/sdk-wrapper/python/bindings/wedpr_python_gateway_sdk/__init__.py new file mode 100644 index 00000000..5becc17c --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/python/bindings/wedpr_python_gateway_sdk/__init__.py @@ -0,0 +1 @@ +__version__ = "1.0.0" diff --git a/cpp/wedpr-transport/sdk-wrapper/python/bindings/wedpr_python_gateway_sdk/libs/__init__.py b/cpp/wedpr-transport/sdk-wrapper/python/bindings/wedpr_python_gateway_sdk/libs/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/cpp/wedpr-transport/sdk-wrapper/python/bindings/wedpr_python_gateway_sdk/libs/_wedpr_python_transport.py b/cpp/wedpr-transport/sdk-wrapper/python/bindings/wedpr_python_gateway_sdk/libs/_wedpr_python_transport.py new file mode 100644 index 00000000..fb07b92a --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/python/bindings/wedpr_python_gateway_sdk/libs/_wedpr_python_transport.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +import shutil +import pkg_resources +from wedpr_python_gateway_sdk.utils.lib_loader import LibLoader + + +def __bootstrap__(): + global __bootstrap__, __loader__, __file__ + import sys + import pkg_resources + import imp + __file__ = pkg_resources.resource_filename( + __name__, LibLoader.get_lib_name()) + __loader__ = None + del __bootstrap__, __loader__ + imp.load_dynamic(__name__, __file__) + + +__bootstrap__() diff --git a/cpp/wedpr-transport/sdk-wrapper/python/bindings/wedpr_python_gateway_sdk/transport/__init__.py b/cpp/wedpr-transport/sdk-wrapper/python/bindings/wedpr_python_gateway_sdk/transport/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/cpp/wedpr-transport/sdk-wrapper/python/bindings/wedpr_python_gateway_sdk/transport/api/__init__.py b/cpp/wedpr-transport/sdk-wrapper/python/bindings/wedpr_python_gateway_sdk/transport/api/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/cpp/wedpr-transport/sdk-wrapper/python/bindings/wedpr_python_gateway_sdk/transport/api/message_api.py b/cpp/wedpr-transport/sdk-wrapper/python/bindings/wedpr_python_gateway_sdk/transport/api/message_api.py new file mode 100644 index 00000000..036c0069 --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/python/bindings/wedpr_python_gateway_sdk/transport/api/message_api.py @@ -0,0 +1,84 @@ +# -*- coding: utf-8 -*- + +from abc import ABC, abstractmethod + + +class MessageHeaderAPI(ABC): + @abstractmethod + def get_version(self) -> str: + pass + + @abstractmethod + def get_trace_id(self) -> str: + pass + + @abstractmethod + def get_src_gw_node(self) -> str: + pass + + @abstractmethod + def get_dst_gw_node(self) -> str: + pass + + @abstractmethod + def get_packet_type(self) -> int: + pass + + @abstractmethod + def get_ttl(self) -> int: + pass + + @abstractmethod + def get_ext(self) -> int: + pass + + @abstractmethod + def is_resp_packet(self) -> bool: + pass + + @abstractmethod + def get_route_type(self) -> int: + pass + + @abstractmethod + def get_component_type(self) -> str: + pass + + @abstractmethod + def get_src_node(self) -> bytes: + pass + + @abstractmethod + def get_dst_node(self) -> bytes: + pass + + @abstractmethod + def get_dst_inst(self) -> str: + pass + + @abstractmethod + def get_src_inst(self) -> str: + pass + + @abstractmethod + def get_topic(self) -> str: + pass + + +class MessageAPI(ABC): + + @abstractmethod + def get_header(self) -> MessageHeaderAPI: + pass + + @abstractmethod + def get_seq(self) -> int: + pass + + @abstractmethod + def get_payload(self) -> bytes: + pass + + @abstractmethod + def get_length(self) -> int: + pass diff --git a/cpp/wedpr-transport/sdk-wrapper/python/bindings/wedpr_python_gateway_sdk/transport/api/transport_api.py b/cpp/wedpr-transport/sdk-wrapper/python/bindings/wedpr_python_gateway_sdk/transport/api/transport_api.py new file mode 100644 index 00000000..949ae351 --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/python/bindings/wedpr_python_gateway_sdk/transport/api/transport_api.py @@ -0,0 +1,115 @@ +# -*- coding: utf-8 -*- + +from abc import ABC, abstractmethod +import json +from wedpr_python_gateway_sdk.transport.api.message_api import MessageAPI +from wedpr_python_gateway_sdk.utils.base_object import BaseObject + + +class EntryPointInfo(BaseObject): + def __init__(self, service_name: str = None, entrypoint: str = None): + self.serviceName = service_name + self.entryPoint = entrypoint + + def __repr__(self): + return f"serviceName: {self.serviceName}, entryPoint: {self.entryPoint}" + + +class ServiceMeta(BaseObject): + SERVICE_INFOS_KEY = "serviceInfos" + + def __init__(self, entrypoints_info: [EntryPointInfo]): + self.serviceInfos = entrypoints_info + + def encode(self) -> str: + service_meta_dict = {} + if self.serviceInfos is None: + return "" + service_info_list = [] + for service_info in self.serviceInfos: + service_info_list.append(service_info.as_dict()) + service_meta_dict.update( + {ServiceMeta.SERVICE_INFOS_KEY: service_info_list}) + return json.dumps(service_meta_dict) + + @staticmethod + def decode(json_str): + if json_str is None or len(json_str) == 0: + return None + service_meta = ServiceMeta([]) + service_meta_dict = json.loads(json_str) + if ServiceMeta.SERVICE_INFOS_KEY in service_meta_dict.keys(): + service_info_list = service_meta_dict.get( + ServiceMeta.SERVICE_INFOS_KEY) + for service_info in service_info_list: + entrypoint_info = EntryPointInfo() + entrypoint_info.set_params(**service_info) + service_meta.serviceInfos.append(entrypoint_info) + return service_meta + + def __repr__(self): + repr_str = "{" + if self.serviceInfos is None: + return repr_str + for service_info in self.serviceInfos: + repr_str = f"{repr_str}, [{service_info}]" + repr_str = f"{repr_str}" + "}" + return repr_str + + +class TransportAPI(ABC): + @abstractmethod + def start(self): + pass + + @abstractmethod + def stop(self): + pass + + @abstractmethod + def push_by_nodeid(self, topic: str, dstNode: bytes, seq: int, payload: bytes, timeout: int): + pass + + @abstractmethod + def push_by_inst(self, topic: str, dstInst: str, seq: int, payload: bytes, timeout: int): + pass + + @abstractmethod + def push_by_component(self, topic: str, dstInst: str, component: str, seq: int, payload: bytes, timeout: int): + pass + + @abstractmethod + def push_by_topic(self, topic: str, dstInst: str, seq: int, payload: bytes, timeout: int): + pass + + @abstractmethod + def pop(self, topic, timeoutMs) -> MessageAPI: + pass + + @abstractmethod + def peek(self, topic) -> MessageAPI: + pass + + @abstractmethod + def register_topic(self, topic): + pass + + @abstractmethod + def unregister_topic(self, topic): + pass + + @abstractmethod + def register_component(self, component): + pass + + @abstractmethod + def unregister_component(self, component): + pass + + @abstractmethod + def get_alive_entrypoints(self, service_name: str) -> [EntryPointInfo]: + pass + + @abstractmethod + def register_service_info(self, service, entrypoint): + pass diff --git a/cpp/wedpr-transport/sdk-wrapper/python/bindings/wedpr_python_gateway_sdk/transport/generated/__init__.py b/cpp/wedpr-transport/sdk-wrapper/python/bindings/wedpr_python_gateway_sdk/transport/generated/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/cpp/wedpr-transport/sdk-wrapper/python/bindings/wedpr_python_gateway_sdk/transport/generated/wedpr_python_transport.py b/cpp/wedpr-transport/sdk-wrapper/python/bindings/wedpr_python_gateway_sdk/transport/generated/wedpr_python_transport.py new file mode 100644 index 00000000..17190df1 --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/python/bindings/wedpr_python_gateway_sdk/transport/generated/wedpr_python_transport.py @@ -0,0 +1,1928 @@ +# This file was automatically generated by SWIG (https://www.swig.org). +# Version 4.2.1 +# +# Do not make changes to this file unless you know what you are doing - modify +# the SWIG interface file instead. + +import weakref +from sys import version_info as _swig_python_version_info + +# Import the low-level C/C++ module +from wedpr_python_gateway_sdk.libs import _wedpr_python_transport + + +try: + import builtins as __builtin__ +except ImportError: + import __builtin__ + + +def _swig_repr(self): + try: + strthis = "proxy of " + self.this.__repr__() + except __builtin__.Exception: + strthis = "" + return "<%s.%s; %s >" % (self.__class__.__module__, self.__class__.__name__, strthis,) + + +def _swig_setattr_nondynamic_instance_variable(set): + def set_instance_attr(self, name, value): + if name == "this": + set(self, name, value) + elif name == "thisown": + self.this.own(value) + elif hasattr(self, name) and isinstance(getattr(type(self), name), property): + set(self, name, value) + else: + raise AttributeError( + "You cannot add instance attributes to %s" % self) + return set_instance_attr + + +def _swig_setattr_nondynamic_class_variable(set): + def set_class_attr(cls, name, value): + if hasattr(cls, name) and not isinstance(getattr(cls, name), property): + set(cls, name, value) + else: + raise AttributeError("You cannot add class attributes to %s" % cls) + return set_class_attr + + +def _swig_add_metaclass(metaclass): + """Class decorator for adding a metaclass to a SWIG wrapped class - a slimmed down version of six.add_metaclass""" + def wrapper(cls): + return metaclass(cls.__name__, cls.__bases__, cls.__dict__.copy()) + return wrapper + + +class _SwigNonDynamicMeta(type): + """Meta class to enforce nondynamic attributes (no new attributes) for a class""" + __setattr__ = _swig_setattr_nondynamic_class_variable(type.__setattr__) + + +class SwigPyIterator(object): + thisown = property(lambda x: x.this.own(), lambda x, + v: x.this.own(v), doc="The membership flag") + + def __init__(self, *args, **kwargs): + raise AttributeError("No constructor defined - class is abstract") + __repr__ = _swig_repr + __swig_destroy__ = _wedpr_python_transport.delete_SwigPyIterator + + def value(self): + return _wedpr_python_transport.SwigPyIterator_value(self) + + def incr(self, n=1): + return _wedpr_python_transport.SwigPyIterator_incr(self, n) + + def decr(self, n=1): + return _wedpr_python_transport.SwigPyIterator_decr(self, n) + + def distance(self, x): + return _wedpr_python_transport.SwigPyIterator_distance(self, x) + + def equal(self, x): + return _wedpr_python_transport.SwigPyIterator_equal(self, x) + + def copy(self): + return _wedpr_python_transport.SwigPyIterator_copy(self) + + def next(self): + return _wedpr_python_transport.SwigPyIterator_next(self) + + def __next__(self): + return _wedpr_python_transport.SwigPyIterator___next__(self) + + def previous(self): + return _wedpr_python_transport.SwigPyIterator_previous(self) + + def advance(self, n): + return _wedpr_python_transport.SwigPyIterator_advance(self, n) + + def __eq__(self, x): + return _wedpr_python_transport.SwigPyIterator___eq__(self, x) + + def __ne__(self, x): + return _wedpr_python_transport.SwigPyIterator___ne__(self, x) + + def __iadd__(self, n): + return _wedpr_python_transport.SwigPyIterator___iadd__(self, n) + + def __isub__(self, n): + return _wedpr_python_transport.SwigPyIterator___isub__(self, n) + + def __add__(self, n): + return _wedpr_python_transport.SwigPyIterator___add__(self, n) + + def __sub__(self, *args): + return _wedpr_python_transport.SwigPyIterator___sub__(self, *args) + + def __iter__(self): + return self + + +# Register SwigPyIterator in _wedpr_python_transport: +_wedpr_python_transport.SwigPyIterator_swigregister(SwigPyIterator) +SHARED_PTR_DISOWN = _wedpr_python_transport.SHARED_PTR_DISOWN + + +class SharedBcosError(object): + thisown = property(lambda x: x.this.own(), lambda x, + v: x.this.own(v), doc="The membership flag") + __repr__ = _swig_repr + + def __init__(self): + _wedpr_python_transport.SharedBcosError_swiginit( + self, _wedpr_python_transport.new_SharedBcosError()) + __swig_destroy__ = _wedpr_python_transport.delete_SharedBcosError + + +# Register SharedBcosError in _wedpr_python_transport: +_wedpr_python_transport.SharedBcosError_swigregister(SharedBcosError) + + +class SharedFrontConfig(object): + thisown = property(lambda x: x.this.own(), lambda x, + v: x.this.own(v), doc="The membership flag") + __repr__ = _swig_repr + + def __init__(self): + _wedpr_python_transport.SharedFrontConfig_swiginit( + self, _wedpr_python_transport.new_SharedFrontConfig()) + __swig_destroy__ = _wedpr_python_transport.delete_SharedFrontConfig + + +# Register SharedFrontConfig in _wedpr_python_transport: +_wedpr_python_transport.SharedFrontConfig_swigregister(SharedFrontConfig) + + +class SharedGrpcConfig(object): + thisown = property(lambda x: x.this.own(), lambda x, + v: x.this.own(v), doc="The membership flag") + __repr__ = _swig_repr + + def __init__(self): + _wedpr_python_transport.SharedGrpcConfig_swiginit( + self, _wedpr_python_transport.new_SharedGrpcConfig()) + __swig_destroy__ = _wedpr_python_transport.delete_SharedGrpcConfig + + +# Register SharedGrpcConfig in _wedpr_python_transport: +_wedpr_python_transport.SharedGrpcConfig_swigregister(SharedGrpcConfig) + + +class SharedFront(object): + thisown = property(lambda x: x.this.own(), lambda x, + v: x.this.own(v), doc="The membership flag") + __repr__ = _swig_repr + + def __init__(self): + _wedpr_python_transport.SharedFront_swiginit( + self, _wedpr_python_transport.new_SharedFront()) + __swig_destroy__ = _wedpr_python_transport.delete_SharedFront + + +# Register SharedFront in _wedpr_python_transport: +_wedpr_python_transport.SharedFront_swigregister(SharedFront) + + +class SharedNodeDiscovery(object): + thisown = property(lambda x: x.this.own(), lambda x, + v: x.this.own(v), doc="The membership flag") + __repr__ = _swig_repr + + def __init__(self): + _wedpr_python_transport.SharedNodeDiscovery_swiginit( + self, _wedpr_python_transport.new_SharedNodeDiscovery()) + __swig_destroy__ = _wedpr_python_transport.delete_SharedNodeDiscovery + + +# Register SharedNodeDiscovery in _wedpr_python_transport: +_wedpr_python_transport.SharedNodeDiscovery_swigregister(SharedNodeDiscovery) + + +class SharedNodeInfo(object): + thisown = property(lambda x: x.this.own(), lambda x, + v: x.this.own(v), doc="The membership flag") + __repr__ = _swig_repr + + def __init__(self): + _wedpr_python_transport.SharedNodeInfo_swiginit( + self, _wedpr_python_transport.new_SharedNodeInfo()) + __swig_destroy__ = _wedpr_python_transport.delete_SharedNodeInfo + + +# Register SharedNodeInfo in _wedpr_python_transport: +_wedpr_python_transport.SharedNodeInfo_swigregister(SharedNodeInfo) + + +class SharedFrontClient(object): + thisown = property(lambda x: x.this.own(), lambda x, + v: x.this.own(v), doc="The membership flag") + __repr__ = _swig_repr + + def __init__(self): + _wedpr_python_transport.SharedFrontClient_swiginit( + self, _wedpr_python_transport.new_SharedFrontClient()) + __swig_destroy__ = _wedpr_python_transport.delete_SharedFrontClient + + +# Register SharedFrontClient in _wedpr_python_transport: +_wedpr_python_transport.SharedFrontClient_swigregister(SharedFrontClient) + + +class SharedErrorCallback(object): + thisown = property(lambda x: x.this.own(), lambda x, + v: x.this.own(v), doc="The membership flag") + __repr__ = _swig_repr + + def __init__(self): + _wedpr_python_transport.SharedErrorCallback_swiginit( + self, _wedpr_python_transport.new_SharedErrorCallback()) + __swig_destroy__ = _wedpr_python_transport.delete_SharedErrorCallback + + +# Register SharedErrorCallback in _wedpr_python_transport: +_wedpr_python_transport.SharedErrorCallback_swigregister(SharedErrorCallback) + + +class SharedMessageDispatcherHandler(object): + thisown = property(lambda x: x.this.own(), lambda x, + v: x.this.own(v), doc="The membership flag") + __repr__ = _swig_repr + + def __init__(self): + _wedpr_python_transport.SharedMessageDispatcherHandler_swiginit( + self, _wedpr_python_transport.new_SharedMessageDispatcherHandler()) + __swig_destroy__ = _wedpr_python_transport.delete_SharedMessageDispatcherHandler + + +# Register SharedMessageDispatcherHandler in _wedpr_python_transport: +_wedpr_python_transport.SharedMessageDispatcherHandler_swigregister( + SharedMessageDispatcherHandler) + + +class SharedIMessageHandler(object): + thisown = property(lambda x: x.this.own(), lambda x, + v: x.this.own(v), doc="The membership flag") + __repr__ = _swig_repr + + def __init__(self): + _wedpr_python_transport.SharedIMessageHandler_swiginit( + self, _wedpr_python_transport.new_SharedIMessageHandler()) + __swig_destroy__ = _wedpr_python_transport.delete_SharedIMessageHandler + + +# Register SharedIMessageHandler in _wedpr_python_transport: +_wedpr_python_transport.SharedIMessageHandler_swigregister( + SharedIMessageHandler) + + +class SharedGetPeersInfoHandler(object): + thisown = property(lambda x: x.this.own(), lambda x, + v: x.this.own(v), doc="The membership flag") + __repr__ = _swig_repr + + def __init__(self): + _wedpr_python_transport.SharedGetPeersInfoHandler_swiginit( + self, _wedpr_python_transport.new_SharedGetPeersInfoHandler()) + __swig_destroy__ = _wedpr_python_transport.delete_SharedGetPeersInfoHandler + + +# Register SharedGetPeersInfoHandler in _wedpr_python_transport: +_wedpr_python_transport.SharedGetPeersInfoHandler_swigregister( + SharedGetPeersInfoHandler) + + +class SharedGateway(object): + thisown = property(lambda x: x.this.own(), lambda x, + v: x.this.own(v), doc="The membership flag") + __repr__ = _swig_repr + + def __init__(self): + _wedpr_python_transport.SharedGateway_swiginit( + self, _wedpr_python_transport.new_SharedGateway()) + __swig_destroy__ = _wedpr_python_transport.delete_SharedGateway + + +# Register SharedGateway in _wedpr_python_transport: +_wedpr_python_transport.SharedGateway_swigregister(SharedGateway) + + +class SharedMessage(object): + thisown = property(lambda x: x.this.own(), lambda x, + v: x.this.own(v), doc="The membership flag") + __repr__ = _swig_repr + + def __init__(self): + _wedpr_python_transport.SharedMessage_swiginit( + self, _wedpr_python_transport.new_SharedMessage()) + __swig_destroy__ = _wedpr_python_transport.delete_SharedMessage + + +# Register SharedMessage in _wedpr_python_transport: +_wedpr_python_transport.SharedMessage_swigregister(SharedMessage) + + +class SharedMessageHeader(object): + thisown = property(lambda x: x.this.own(), lambda x, + v: x.this.own(v), doc="The membership flag") + __repr__ = _swig_repr + + def __init__(self): + _wedpr_python_transport.SharedMessageHeader_swiginit( + self, _wedpr_python_transport.new_SharedMessageHeader()) + __swig_destroy__ = _wedpr_python_transport.delete_SharedMessageHeader + + +# Register SharedMessageHeader in _wedpr_python_transport: +_wedpr_python_transport.SharedMessageHeader_swigregister(SharedMessageHeader) + + +class SharedMessagePayload(object): + thisown = property(lambda x: x.this.own(), lambda x, + v: x.this.own(v), doc="The membership flag") + __repr__ = _swig_repr + + def __init__(self): + _wedpr_python_transport.SharedMessagePayload_swiginit( + self, _wedpr_python_transport.new_SharedMessagePayload()) + __swig_destroy__ = _wedpr_python_transport.delete_SharedMessagePayload + + +# Register SharedMessagePayload in _wedpr_python_transport: +_wedpr_python_transport.SharedMessagePayload_swigregister(SharedMessagePayload) + + +class SharedRouteInfo(object): + thisown = property(lambda x: x.this.own(), lambda x, + v: x.this.own(v), doc="The membership flag") + __repr__ = _swig_repr + + def __init__(self): + _wedpr_python_transport.SharedRouteInfo_swiginit( + self, _wedpr_python_transport.new_SharedRouteInfo()) + __swig_destroy__ = _wedpr_python_transport.delete_SharedRouteInfo + + +# Register SharedRouteInfo in _wedpr_python_transport: +_wedpr_python_transport.SharedRouteInfo_swigregister(SharedRouteInfo) + + +class SharedMessageBuilder(object): + thisown = property(lambda x: x.this.own(), lambda x, + v: x.this.own(v), doc="The membership flag") + __repr__ = _swig_repr + + def __init__(self): + _wedpr_python_transport.SharedMessageBuilder_swiginit( + self, _wedpr_python_transport.new_SharedMessageBuilder()) + __swig_destroy__ = _wedpr_python_transport.delete_SharedMessageBuilder + + +# Register SharedMessageBuilder in _wedpr_python_transport: +_wedpr_python_transport.SharedMessageBuilder_swigregister(SharedMessageBuilder) + + +class SharedMessageHeaderBuilder(object): + thisown = property(lambda x: x.this.own(), lambda x, + v: x.this.own(v), doc="The membership flag") + __repr__ = _swig_repr + + def __init__(self): + _wedpr_python_transport.SharedMessageHeaderBuilder_swiginit( + self, _wedpr_python_transport.new_SharedMessageHeaderBuilder()) + __swig_destroy__ = _wedpr_python_transport.delete_SharedMessageHeaderBuilder + + +# Register SharedMessageHeaderBuilder in _wedpr_python_transport: +_wedpr_python_transport.SharedMessageHeaderBuilder_swigregister( + SharedMessageHeaderBuilder) + + +class SharedMessagePayloadBuilder(object): + thisown = property(lambda x: x.this.own(), lambda x, + v: x.this.own(v), doc="The membership flag") + __repr__ = _swig_repr + + def __init__(self): + _wedpr_python_transport.SharedMessagePayloadBuilder_swiginit( + self, _wedpr_python_transport.new_SharedMessagePayloadBuilder()) + __swig_destroy__ = _wedpr_python_transport.delete_SharedMessagePayloadBuilder + + +# Register SharedMessagePayloadBuilder in _wedpr_python_transport: +_wedpr_python_transport.SharedMessagePayloadBuilder_swigregister( + SharedMessagePayloadBuilder) + + +class SharedRouteInfoBuilder(object): + thisown = property(lambda x: x.this.own(), lambda x, + v: x.this.own(v), doc="The membership flag") + __repr__ = _swig_repr + + def __init__(self): + _wedpr_python_transport.SharedRouteInfoBuilder_swiginit( + self, _wedpr_python_transport.new_SharedRouteInfoBuilder()) + __swig_destroy__ = _wedpr_python_transport.delete_SharedRouteInfoBuilder + + +# Register SharedRouteInfoBuilder in _wedpr_python_transport: +_wedpr_python_transport.SharedRouteInfoBuilder_swigregister( + SharedRouteInfoBuilder) + + +class ubytes(object): + thisown = property(lambda x: x.this.own(), lambda x, + v: x.this.own(v), doc="The membership flag") + __repr__ = _swig_repr + + def iterator(self): + return _wedpr_python_transport.ubytes_iterator(self) + + def __iter__(self): + return self.iterator() + + def __nonzero__(self): + return _wedpr_python_transport.ubytes___nonzero__(self) + + def __bool__(self): + return _wedpr_python_transport.ubytes___bool__(self) + + def __len__(self): + return _wedpr_python_transport.ubytes___len__(self) + + def __getslice__(self, i, j): + return _wedpr_python_transport.ubytes___getslice__(self, i, j) + + def __setslice__(self, *args): + return _wedpr_python_transport.ubytes___setslice__(self, *args) + + def __delslice__(self, i, j): + return _wedpr_python_transport.ubytes___delslice__(self, i, j) + + def __delitem__(self, *args): + return _wedpr_python_transport.ubytes___delitem__(self, *args) + + def __getitem__(self, *args): + return _wedpr_python_transport.ubytes___getitem__(self, *args) + + def __setitem__(self, *args): + return _wedpr_python_transport.ubytes___setitem__(self, *args) + + def pop(self): + return _wedpr_python_transport.ubytes_pop(self) + + def append(self, x): + return _wedpr_python_transport.ubytes_append(self, x) + + def empty(self): + return _wedpr_python_transport.ubytes_empty(self) + + def size(self): + return _wedpr_python_transport.ubytes_size(self) + + def swap(self, v): + return _wedpr_python_transport.ubytes_swap(self, v) + + def begin(self): + return _wedpr_python_transport.ubytes_begin(self) + + def end(self): + return _wedpr_python_transport.ubytes_end(self) + + def rbegin(self): + return _wedpr_python_transport.ubytes_rbegin(self) + + def rend(self): + return _wedpr_python_transport.ubytes_rend(self) + + def clear(self): + return _wedpr_python_transport.ubytes_clear(self) + + def get_allocator(self): + return _wedpr_python_transport.ubytes_get_allocator(self) + + def pop_back(self): + return _wedpr_python_transport.ubytes_pop_back(self) + + def erase(self, *args): + return _wedpr_python_transport.ubytes_erase(self, *args) + + def __init__(self, *args): + _wedpr_python_transport.ubytes_swiginit( + self, _wedpr_python_transport.new_ubytes(*args)) + + def push_back(self, x): + return _wedpr_python_transport.ubytes_push_back(self, x) + + def front(self): + return _wedpr_python_transport.ubytes_front(self) + + def back(self): + return _wedpr_python_transport.ubytes_back(self) + + def assign(self, n, x): + return _wedpr_python_transport.ubytes_assign(self, n, x) + + def resize(self, *args): + return _wedpr_python_transport.ubytes_resize(self, *args) + + def insert(self, *args): + return _wedpr_python_transport.ubytes_insert(self, *args) + + def reserve(self, n): + return _wedpr_python_transport.ubytes_reserve(self, n) + + def capacity(self): + return _wedpr_python_transport.ubytes_capacity(self) + __swig_destroy__ = _wedpr_python_transport.delete_ubytes + + +# Register ubytes in _wedpr_python_transport: +_wedpr_python_transport.ubytes_swigregister(ubytes) + + +class ibytes(object): + thisown = property(lambda x: x.this.own(), lambda x, + v: x.this.own(v), doc="The membership flag") + __repr__ = _swig_repr + + def iterator(self): + return _wedpr_python_transport.ibytes_iterator(self) + + def __iter__(self): + return self.iterator() + + def __nonzero__(self): + return _wedpr_python_transport.ibytes___nonzero__(self) + + def __bool__(self): + return _wedpr_python_transport.ibytes___bool__(self) + + def __len__(self): + return _wedpr_python_transport.ibytes___len__(self) + + def __getslice__(self, i, j): + return _wedpr_python_transport.ibytes___getslice__(self, i, j) + + def __setslice__(self, *args): + return _wedpr_python_transport.ibytes___setslice__(self, *args) + + def __delslice__(self, i, j): + return _wedpr_python_transport.ibytes___delslice__(self, i, j) + + def __delitem__(self, *args): + return _wedpr_python_transport.ibytes___delitem__(self, *args) + + def __getitem__(self, *args): + return _wedpr_python_transport.ibytes___getitem__(self, *args) + + def __setitem__(self, *args): + return _wedpr_python_transport.ibytes___setitem__(self, *args) + + def pop(self): + return _wedpr_python_transport.ibytes_pop(self) + + def append(self, x): + return _wedpr_python_transport.ibytes_append(self, x) + + def empty(self): + return _wedpr_python_transport.ibytes_empty(self) + + def size(self): + return _wedpr_python_transport.ibytes_size(self) + + def swap(self, v): + return _wedpr_python_transport.ibytes_swap(self, v) + + def begin(self): + return _wedpr_python_transport.ibytes_begin(self) + + def end(self): + return _wedpr_python_transport.ibytes_end(self) + + def rbegin(self): + return _wedpr_python_transport.ibytes_rbegin(self) + + def rend(self): + return _wedpr_python_transport.ibytes_rend(self) + + def clear(self): + return _wedpr_python_transport.ibytes_clear(self) + + def get_allocator(self): + return _wedpr_python_transport.ibytes_get_allocator(self) + + def pop_back(self): + return _wedpr_python_transport.ibytes_pop_back(self) + + def erase(self, *args): + return _wedpr_python_transport.ibytes_erase(self, *args) + + def __init__(self, *args): + _wedpr_python_transport.ibytes_swiginit( + self, _wedpr_python_transport.new_ibytes(*args)) + + def push_back(self, x): + return _wedpr_python_transport.ibytes_push_back(self, x) + + def front(self): + return _wedpr_python_transport.ibytes_front(self) + + def back(self): + return _wedpr_python_transport.ibytes_back(self) + + def assign(self, n, x): + return _wedpr_python_transport.ibytes_assign(self, n, x) + + def resize(self, *args): + return _wedpr_python_transport.ibytes_resize(self, *args) + + def insert(self, *args): + return _wedpr_python_transport.ibytes_insert(self, *args) + + def reserve(self, n): + return _wedpr_python_transport.ibytes_reserve(self, n) + + def capacity(self): + return _wedpr_python_transport.ibytes_capacity(self) + __swig_destroy__ = _wedpr_python_transport.delete_ibytes + + +# Register ibytes in _wedpr_python_transport: +_wedpr_python_transport.ibytes_swigregister(ibytes) + + +class StringVec(object): + thisown = property(lambda x: x.this.own(), lambda x, + v: x.this.own(v), doc="The membership flag") + __repr__ = _swig_repr + + def iterator(self): + return _wedpr_python_transport.StringVec_iterator(self) + + def __iter__(self): + return self.iterator() + + def __nonzero__(self): + return _wedpr_python_transport.StringVec___nonzero__(self) + + def __bool__(self): + return _wedpr_python_transport.StringVec___bool__(self) + + def __len__(self): + return _wedpr_python_transport.StringVec___len__(self) + + def __getslice__(self, i, j): + return _wedpr_python_transport.StringVec___getslice__(self, i, j) + + def __setslice__(self, *args): + return _wedpr_python_transport.StringVec___setslice__(self, *args) + + def __delslice__(self, i, j): + return _wedpr_python_transport.StringVec___delslice__(self, i, j) + + def __delitem__(self, *args): + return _wedpr_python_transport.StringVec___delitem__(self, *args) + + def __getitem__(self, *args): + return _wedpr_python_transport.StringVec___getitem__(self, *args) + + def __setitem__(self, *args): + return _wedpr_python_transport.StringVec___setitem__(self, *args) + + def pop(self): + return _wedpr_python_transport.StringVec_pop(self) + + def append(self, x): + return _wedpr_python_transport.StringVec_append(self, x) + + def empty(self): + return _wedpr_python_transport.StringVec_empty(self) + + def size(self): + return _wedpr_python_transport.StringVec_size(self) + + def swap(self, v): + return _wedpr_python_transport.StringVec_swap(self, v) + + def begin(self): + return _wedpr_python_transport.StringVec_begin(self) + + def end(self): + return _wedpr_python_transport.StringVec_end(self) + + def rbegin(self): + return _wedpr_python_transport.StringVec_rbegin(self) + + def rend(self): + return _wedpr_python_transport.StringVec_rend(self) + + def clear(self): + return _wedpr_python_transport.StringVec_clear(self) + + def get_allocator(self): + return _wedpr_python_transport.StringVec_get_allocator(self) + + def pop_back(self): + return _wedpr_python_transport.StringVec_pop_back(self) + + def erase(self, *args): + return _wedpr_python_transport.StringVec_erase(self, *args) + + def __init__(self, *args): + _wedpr_python_transport.StringVec_swiginit( + self, _wedpr_python_transport.new_StringVec(*args)) + + def push_back(self, x): + return _wedpr_python_transport.StringVec_push_back(self, x) + + def front(self): + return _wedpr_python_transport.StringVec_front(self) + + def back(self): + return _wedpr_python_transport.StringVec_back(self) + + def assign(self, n, x): + return _wedpr_python_transport.StringVec_assign(self, n, x) + + def resize(self, *args): + return _wedpr_python_transport.StringVec_resize(self, *args) + + def insert(self, *args): + return _wedpr_python_transport.StringVec_insert(self, *args) + + def reserve(self, n): + return _wedpr_python_transport.StringVec_reserve(self, n) + + def capacity(self): + return _wedpr_python_transport.StringVec_capacity(self) + __swig_destroy__ = _wedpr_python_transport.delete_StringVec + + +# Register StringVec in _wedpr_python_transport: +_wedpr_python_transport.StringVec_swigregister(StringVec) + + +class NodeInfoVec(object): + thisown = property(lambda x: x.this.own(), lambda x, + v: x.this.own(v), doc="The membership flag") + __repr__ = _swig_repr + + def iterator(self): + return _wedpr_python_transport.NodeInfoVec_iterator(self) + + def __iter__(self): + return self.iterator() + + def __nonzero__(self): + return _wedpr_python_transport.NodeInfoVec___nonzero__(self) + + def __bool__(self): + return _wedpr_python_transport.NodeInfoVec___bool__(self) + + def __len__(self): + return _wedpr_python_transport.NodeInfoVec___len__(self) + + def __getslice__(self, i, j): + return _wedpr_python_transport.NodeInfoVec___getslice__(self, i, j) + + def __setslice__(self, *args): + return _wedpr_python_transport.NodeInfoVec___setslice__(self, *args) + + def __delslice__(self, i, j): + return _wedpr_python_transport.NodeInfoVec___delslice__(self, i, j) + + def __delitem__(self, *args): + return _wedpr_python_transport.NodeInfoVec___delitem__(self, *args) + + def __getitem__(self, *args): + return _wedpr_python_transport.NodeInfoVec___getitem__(self, *args) + + def __setitem__(self, *args): + return _wedpr_python_transport.NodeInfoVec___setitem__(self, *args) + + def pop(self): + return _wedpr_python_transport.NodeInfoVec_pop(self) + + def append(self, x): + return _wedpr_python_transport.NodeInfoVec_append(self, x) + + def empty(self): + return _wedpr_python_transport.NodeInfoVec_empty(self) + + def size(self): + return _wedpr_python_transport.NodeInfoVec_size(self) + + def swap(self, v): + return _wedpr_python_transport.NodeInfoVec_swap(self, v) + + def begin(self): + return _wedpr_python_transport.NodeInfoVec_begin(self) + + def end(self): + return _wedpr_python_transport.NodeInfoVec_end(self) + + def rbegin(self): + return _wedpr_python_transport.NodeInfoVec_rbegin(self) + + def rend(self): + return _wedpr_python_transport.NodeInfoVec_rend(self) + + def clear(self): + return _wedpr_python_transport.NodeInfoVec_clear(self) + + def get_allocator(self): + return _wedpr_python_transport.NodeInfoVec_get_allocator(self) + + def pop_back(self): + return _wedpr_python_transport.NodeInfoVec_pop_back(self) + + def erase(self, *args): + return _wedpr_python_transport.NodeInfoVec_erase(self, *args) + + def __init__(self, *args): + _wedpr_python_transport.NodeInfoVec_swiginit( + self, _wedpr_python_transport.new_NodeInfoVec(*args)) + + def push_back(self, x): + return _wedpr_python_transport.NodeInfoVec_push_back(self, x) + + def front(self): + return _wedpr_python_transport.NodeInfoVec_front(self) + + def back(self): + return _wedpr_python_transport.NodeInfoVec_back(self) + + def assign(self, n, x): + return _wedpr_python_transport.NodeInfoVec_assign(self, n, x) + + def resize(self, *args): + return _wedpr_python_transport.NodeInfoVec_resize(self, *args) + + def insert(self, *args): + return _wedpr_python_transport.NodeInfoVec_insert(self, *args) + + def reserve(self, n): + return _wedpr_python_transport.NodeInfoVec_reserve(self, n) + + def capacity(self): + return _wedpr_python_transport.NodeInfoVec_capacity(self) + __swig_destroy__ = _wedpr_python_transport.delete_NodeInfoVec + + +# Register NodeInfoVec in _wedpr_python_transport: +_wedpr_python_transport.NodeInfoVec_swigregister(NodeInfoVec) + + +class Error(object): + thisown = property(lambda x: x.this.own(), lambda x, + v: x.this.own(v), doc="The membership flag") + __repr__ = _swig_repr + + @staticmethod + def buildError(*args): + return _wedpr_python_transport.Error_buildError(*args) + + def __init__(self, *args): + _wedpr_python_transport.Error_swiginit( + self, _wedpr_python_transport.new_Error(*args)) + __swig_destroy__ = _wedpr_python_transport.delete_Error + + def errorCode(self): + return _wedpr_python_transport.Error_errorCode(self) + + def errorMessage(self): + return _wedpr_python_transport.Error_errorMessage(self) + + def setErrorCode(self, _errorCode): + return _wedpr_python_transport.Error_setErrorCode(self, _errorCode) + + def setErrorMessage(self, _errorMessage): + return _wedpr_python_transport.Error_setErrorMessage(self, _errorMessage) + + +# Register Error in _wedpr_python_transport: +_wedpr_python_transport.Error_swigregister(Error) + + +class InputBuffer(object): + thisown = property(lambda x: x.this.own(), lambda x, + v: x.this.own(v), doc="The membership flag") + __repr__ = _swig_repr + data = property(_wedpr_python_transport.InputBuffer_data_get, + _wedpr_python_transport.InputBuffer_data_set) + len = property(_wedpr_python_transport.InputBuffer_len_get, + _wedpr_python_transport.InputBuffer_len_set) + + def __init__(self): + _wedpr_python_transport.InputBuffer_swiginit( + self, _wedpr_python_transport.new_InputBuffer()) + __swig_destroy__ = _wedpr_python_transport.delete_InputBuffer + + +# Register InputBuffer in _wedpr_python_transport: +_wedpr_python_transport.InputBuffer_swigregister(InputBuffer) + + +class OutputBuffer(object): + thisown = property(lambda x: x.this.own(), lambda x, + v: x.this.own(v), doc="The membership flag") + __repr__ = _swig_repr + data = property(_wedpr_python_transport.OutputBuffer_data_get, + _wedpr_python_transport.OutputBuffer_data_set) + len = property(_wedpr_python_transport.OutputBuffer_len_get, + _wedpr_python_transport.OutputBuffer_len_set) + + def __init__(self): + _wedpr_python_transport.OutputBuffer_swiginit( + self, _wedpr_python_transport.new_OutputBuffer()) + __swig_destroy__ = _wedpr_python_transport.delete_OutputBuffer + + +# Register OutputBuffer in _wedpr_python_transport: +_wedpr_python_transport.OutputBuffer_swigregister(OutputBuffer) + + +class FrontConfig(object): + thisown = property(lambda x: x.this.own(), lambda x, + v: x.this.own(v), doc="The membership flag") + + def __init__(self, *args, **kwargs): + raise AttributeError("No constructor defined - class is abstract") + __repr__ = _swig_repr + __swig_destroy__ = _wedpr_python_transport.delete_FrontConfig + + def threadPoolSize(self): + return _wedpr_python_transport.FrontConfig_threadPoolSize(self) + + def setThreadPoolSize(self, threadPoolSize): + return _wedpr_python_transport.FrontConfig_setThreadPoolSize(self, threadPoolSize) + + def nodeID(self): + return _wedpr_python_transport.FrontConfig_nodeID(self) + + def setNodeID(self, nodeID): + return _wedpr_python_transport.FrontConfig_setNodeID(self, nodeID) + + def selfEndPoint(self): + return _wedpr_python_transport.FrontConfig_selfEndPoint(self) + + def mutableSelfEndPoint(self): + return _wedpr_python_transport.FrontConfig_mutableSelfEndPoint(self) + + def setSelfEndPoint(self, endPoint): + return _wedpr_python_transport.FrontConfig_setSelfEndPoint(self, endPoint) + + def setGatewayGrpcTarget(self, gatewayGrpcTarget): + return _wedpr_python_transport.FrontConfig_setGatewayGrpcTarget(self, gatewayGrpcTarget) + + def gatewayGrpcTarget(self): + return _wedpr_python_transport.FrontConfig_gatewayGrpcTarget(self) + + def setGrpcConfig(self, grpcConfig): + return _wedpr_python_transport.FrontConfig_setGrpcConfig(self, grpcConfig) + + def grpcConfig(self): + return _wedpr_python_transport.FrontConfig_grpcConfig(self) + + def generateNodeInfo(self): + return _wedpr_python_transport.FrontConfig_generateNodeInfo(self) + + def getComponents(self): + return _wedpr_python_transport.FrontConfig_getComponents(self) + + def setComponents(self, components): + return _wedpr_python_transport.FrontConfig_setComponents(self, components) + + def addComponent(self, component): + return _wedpr_python_transport.FrontConfig_addComponent(self, component) + + def mutableComponents(self): + return _wedpr_python_transport.FrontConfig_mutableComponents(self) + + def meta(self): + return _wedpr_python_transport.FrontConfig_meta(self) + + def setMeta(self, meta): + return _wedpr_python_transport.FrontConfig_setMeta(self, meta) + + +# Register FrontConfig in _wedpr_python_transport: +_wedpr_python_transport.FrontConfig_swigregister(FrontConfig) + + +class FrontConfigBuilder(object): + thisown = property(lambda x: x.this.own(), lambda x, + v: x.this.own(v), doc="The membership flag") + + def __init__(self, *args, **kwargs): + raise AttributeError("No constructor defined - class is abstract") + __repr__ = _swig_repr + __swig_destroy__ = _wedpr_python_transport.delete_FrontConfigBuilder + + def build(self, *args): + return _wedpr_python_transport.FrontConfigBuilder_build(self, *args) + + +# Register FrontConfigBuilder in _wedpr_python_transport: +_wedpr_python_transport.FrontConfigBuilder_swigregister(FrontConfigBuilder) + + +def printFrontDesc(config): + return _wedpr_python_transport.printFrontDesc(config) + + +class EndPoint(object): + r"""the endpoint""" + + thisown = property(lambda x: x.this.own(), lambda x, + v: x.this.own(v), doc="The membership flag") + __repr__ = _swig_repr + + def __init__(self, *args): + _wedpr_python_transport.EndPoint_swiginit( + self, _wedpr_python_transport.new_EndPoint(*args)) + __swig_destroy__ = _wedpr_python_transport.delete_EndPoint + + def host(self): + return _wedpr_python_transport.EndPoint_host(self) + + def port(self): + return _wedpr_python_transport.EndPoint_port(self) + + def setHost(self, host): + return _wedpr_python_transport.EndPoint_setHost(self, host) + + def setPort(self, port): + return _wedpr_python_transport.EndPoint_setPort(self, port) + + def setListenIp(self, listenIp): + return _wedpr_python_transport.EndPoint_setListenIp(self, listenIp) + + def entryPoint(self): + return _wedpr_python_transport.EndPoint_entryPoint(self) + + def listenEndPoint(self): + return _wedpr_python_transport.EndPoint_listenEndPoint(self) + + def listenIp(self): + return _wedpr_python_transport.EndPoint_listenIp(self) + + +# Register EndPoint in _wedpr_python_transport: +_wedpr_python_transport.EndPoint_swigregister(EndPoint) + + +class GrpcConfig(object): + thisown = property(lambda x: x.this.own(), lambda x, + v: x.this.own(v), doc="The membership flag") + __repr__ = _swig_repr + + def __init__(self): + _wedpr_python_transport.GrpcConfig_swiginit( + self, _wedpr_python_transport.new_GrpcConfig()) + + def loadBalancePolicy(self): + return _wedpr_python_transport.GrpcConfig_loadBalancePolicy(self) + + def setLoadBalancePolicy(self, loadBalancePolicy): + return _wedpr_python_transport.GrpcConfig_setLoadBalancePolicy(self, loadBalancePolicy) + + def enableHealthCheck(self): + return _wedpr_python_transport.GrpcConfig_enableHealthCheck(self) + + def setEnableHealthCheck(self, enableHealthCheck): + return _wedpr_python_transport.GrpcConfig_setEnableHealthCheck(self, enableHealthCheck) + + def setEnableDnslookup(self, enableDnslookup): + return _wedpr_python_transport.GrpcConfig_setEnableDnslookup(self, enableDnslookup) + + def enableDnslookup(self): + return _wedpr_python_transport.GrpcConfig_enableDnslookup(self) + + def maxSendMessageSize(self): + return _wedpr_python_transport.GrpcConfig_maxSendMessageSize(self) + + def maxReceivedMessageSize(self): + return _wedpr_python_transport.GrpcConfig_maxReceivedMessageSize(self) + + def setMaxSendMessageSize(self, maxSendMessageSize): + return _wedpr_python_transport.GrpcConfig_setMaxSendMessageSize(self, maxSendMessageSize) + + def setMaxReceivedMessageSize(self, maxReceivedMessageSize): + return _wedpr_python_transport.GrpcConfig_setMaxReceivedMessageSize(self, maxReceivedMessageSize) + + def compressAlgorithm(self): + return _wedpr_python_transport.GrpcConfig_compressAlgorithm(self) + + def setCompressAlgorithm(self, compressAlgorithm): + return _wedpr_python_transport.GrpcConfig_setCompressAlgorithm(self, compressAlgorithm) + + def maxMsgSize(self): + return _wedpr_python_transport.GrpcConfig_maxMsgSize(self) + + def setMaxMsgSize(self, maxMsgSize): + return _wedpr_python_transport.GrpcConfig_setMaxMsgSize(self, maxMsgSize) + + +# Register GrpcConfig in _wedpr_python_transport: +_wedpr_python_transport.GrpcConfig_swigregister(GrpcConfig) + + +class GrpcServerConfig(object): + thisown = property(lambda x: x.this.own(), lambda x, + v: x.this.own(v), doc="The membership flag") + __repr__ = _swig_repr + + def __init__(self, *args): + _wedpr_python_transport.GrpcServerConfig_swiginit( + self, _wedpr_python_transport.new_GrpcServerConfig(*args)) + + def listenEndPoint(self): + return _wedpr_python_transport.GrpcServerConfig_listenEndPoint(self) + + def setEndPoint(self, endPoint): + return _wedpr_python_transport.GrpcServerConfig_setEndPoint(self, endPoint) + + def setEnableHealthCheck(self, enableHealthCheck): + return _wedpr_python_transport.GrpcServerConfig_setEnableHealthCheck(self, enableHealthCheck) + + def endPoint(self): + return _wedpr_python_transport.GrpcServerConfig_endPoint(self) + + def mutableEndPoint(self): + return _wedpr_python_transport.GrpcServerConfig_mutableEndPoint(self) + + def enableHealthCheck(self): + return _wedpr_python_transport.GrpcServerConfig_enableHealthCheck(self) + + def grpcConfig(self): + return _wedpr_python_transport.GrpcServerConfig_grpcConfig(self) + + +# Register GrpcServerConfig in _wedpr_python_transport: +_wedpr_python_transport.GrpcServerConfig_swigregister(GrpcServerConfig) + + +def printGrpcConfig(grpcConfig): + return _wedpr_python_transport.printGrpcConfig(grpcConfig) + + +class MessageOptionalHeader(object): + thisown = property(lambda x: x.this.own(), lambda x, + v: x.this.own(v), doc="The membership flag") + + def __init__(self, *args, **kwargs): + raise AttributeError("No constructor defined - class is abstract") + __repr__ = _swig_repr + __swig_destroy__ = _wedpr_python_transport.delete_MessageOptionalHeader + + def encode(self, buffer): + return _wedpr_python_transport.MessageOptionalHeader_encode(self, buffer) + + def decode(self, data, _offset): + return _wedpr_python_transport.MessageOptionalHeader_decode(self, data, _offset) + + def componentType(self): + return _wedpr_python_transport.MessageOptionalHeader_componentType(self) + + def setComponentType(self, componentType): + return _wedpr_python_transport.MessageOptionalHeader_setComponentType(self, componentType) + + def srcNodeBuffer(self): + r""" for swig-wrapper(pass the binary data)""" + return _wedpr_python_transport.MessageOptionalHeader_srcNodeBuffer(self) + + def setSrcNodeBuffer(self, data): + return _wedpr_python_transport.MessageOptionalHeader_setSrcNodeBuffer(self, data) + + def dstNodeBuffer(self): + return _wedpr_python_transport.MessageOptionalHeader_dstNodeBuffer(self) + + def setDstNodeBuffer(self, data): + return _wedpr_python_transport.MessageOptionalHeader_setDstNodeBuffer(self, data) + + def dstInst(self): + return _wedpr_python_transport.MessageOptionalHeader_dstInst(self) + + def setDstInst(self, dstInst): + return _wedpr_python_transport.MessageOptionalHeader_setDstInst(self, dstInst) + + def topic(self): + return _wedpr_python_transport.MessageOptionalHeader_topic(self) + + def setTopic(self, *args): + return _wedpr_python_transport.MessageOptionalHeader_setTopic(self, *args) + + def srcInst(self): + return _wedpr_python_transport.MessageOptionalHeader_srcInst(self) + + def setSrcInst(self, srcInst): + return _wedpr_python_transport.MessageOptionalHeader_setSrcInst(self, srcInst) + + +# Register MessageOptionalHeader in _wedpr_python_transport: +_wedpr_python_transport.MessageOptionalHeader_swigregister( + MessageOptionalHeader) + + +class MessageHeader(object): + thisown = property(lambda x: x.this.own(), lambda x, + v: x.this.own(v), doc="The membership flag") + + def __init__(self, *args, **kwargs): + raise AttributeError("No constructor defined - class is abstract") + __repr__ = _swig_repr + __swig_destroy__ = _wedpr_python_transport.delete_MessageHeader + + def encode(self, buffer): + return _wedpr_python_transport.MessageHeader_encode(self, buffer) + + def decode(self, data): + return _wedpr_python_transport.MessageHeader_decode(self, data) + + def version(self): + return _wedpr_python_transport.MessageHeader_version(self) + + def setVersion(self, version): + return _wedpr_python_transport.MessageHeader_setVersion(self, version) + + def traceID(self): + return _wedpr_python_transport.MessageHeader_traceID(self) + + def setTraceID(self, traceID): + return _wedpr_python_transport.MessageHeader_setTraceID(self, traceID) + + def srcGwNode(self): + return _wedpr_python_transport.MessageHeader_srcGwNode(self) + + def setSrcGwNode(self, srcGwNode): + return _wedpr_python_transport.MessageHeader_setSrcGwNode(self, srcGwNode) + + def dstGwNode(self): + return _wedpr_python_transport.MessageHeader_dstGwNode(self) + + def setDstGwNode(self, dstGwNode): + return _wedpr_python_transport.MessageHeader_setDstGwNode(self, dstGwNode) + + def packetType(self): + return _wedpr_python_transport.MessageHeader_packetType(self) + + def setPacketType(self, packetType): + return _wedpr_python_transport.MessageHeader_setPacketType(self, packetType) + + def ttl(self): + return _wedpr_python_transport.MessageHeader_ttl(self) + + def setTTL(self, ttl): + return _wedpr_python_transport.MessageHeader_setTTL(self, ttl) + + def ext(self): + return _wedpr_python_transport.MessageHeader_ext(self) + + def setExt(self, ext): + return _wedpr_python_transport.MessageHeader_setExt(self, ext) + + def optionalField(self): + return _wedpr_python_transport.MessageHeader_optionalField(self) + + def setOptionalField(self, optionalField): + return _wedpr_python_transport.MessageHeader_setOptionalField(self, optionalField) + + def length(self): + return _wedpr_python_transport.MessageHeader_length(self) + + def isRespPacket(self): + return _wedpr_python_transport.MessageHeader_isRespPacket(self) + + def setRespPacket(self): + return _wedpr_python_transport.MessageHeader_setRespPacket(self) + + def srcP2PNodeIDView(self): + return _wedpr_python_transport.MessageHeader_srcP2PNodeIDView(self) + + def dstP2PNodeIDView(self): + return _wedpr_python_transport.MessageHeader_dstP2PNodeIDView(self) + + def routeType(self): + return _wedpr_python_transport.MessageHeader_routeType(self) + + def setRouteType(self, type): + return _wedpr_python_transport.MessageHeader_setRouteType(self, type) + + def hasOptionalField(self): + return _wedpr_python_transport.MessageHeader_hasOptionalField(self) + + +# Register MessageHeader in _wedpr_python_transport: +_wedpr_python_transport.MessageHeader_swigregister(MessageHeader) + + +class Message(object): + thisown = property(lambda x: x.this.own(), lambda x, + v: x.this.own(v), doc="The membership flag") + + def __init__(self, *args, **kwargs): + raise AttributeError("No constructor defined - class is abstract") + __repr__ = _swig_repr + __swig_destroy__ = _wedpr_python_transport.delete_Message + + def header(self): + return _wedpr_python_transport.Message_header(self) + + def setHeader(self, header): + return _wedpr_python_transport.Message_setHeader(self, header) + + def version(self): + r""" the overloaed implementation ===""" + return _wedpr_python_transport.Message_version(self) + + def setVersion(self, version): + return _wedpr_python_transport.Message_setVersion(self, version) + + def packetType(self): + return _wedpr_python_transport.Message_packetType(self) + + def setPacketType(self, packetType): + return _wedpr_python_transport.Message_setPacketType(self, packetType) + + def seq(self): + return _wedpr_python_transport.Message_seq(self) + + def setSeq(self, traceID): + return _wedpr_python_transport.Message_setSeq(self, traceID) + + def ext(self): + return _wedpr_python_transport.Message_ext(self) + + def setExt(self, ext): + return _wedpr_python_transport.Message_setExt(self, ext) + + def isRespPacket(self): + return _wedpr_python_transport.Message_isRespPacket(self) + + def setRespPacket(self): + return _wedpr_python_transport.Message_setRespPacket(self) + + def setPayload(self, _payload): + return _wedpr_python_transport.Message_setPayload(self, _payload) + + def payloadBuffer(self): + return _wedpr_python_transport.Message_payloadBuffer(self) + + def frontMessage(self): + return _wedpr_python_transport.Message_frontMessage(self) + + def encode(self, _buffer): + return _wedpr_python_transport.Message_encode(self, _buffer) + + def decode(self, _buffer): + return _wedpr_python_transport.Message_decode(self, _buffer) + + def length(self): + return _wedpr_python_transport.Message_length(self) + + def payload(self): + return _wedpr_python_transport.Message_payload(self) + + def releasePayload(self): + return _wedpr_python_transport.Message_releasePayload(self) + + +# Register Message in _wedpr_python_transport: +_wedpr_python_transport.Message_swigregister(Message) + + +class MessageHeaderBuilder(object): + thisown = property(lambda x: x.this.own(), lambda x, + v: x.this.own(v), doc="The membership flag") + + def __init__(self, *args, **kwargs): + raise AttributeError("No constructor defined - class is abstract") + __repr__ = _swig_repr + __swig_destroy__ = _wedpr_python_transport.delete_MessageHeaderBuilder + + def build(self, *args): + return _wedpr_python_transport.MessageHeaderBuilder_build(self, *args) + + +# Register MessageHeaderBuilder in _wedpr_python_transport: +_wedpr_python_transport.MessageHeaderBuilder_swigregister(MessageHeaderBuilder) + + +class MessageBuilder(object): + thisown = property(lambda x: x.this.own(), lambda x, + v: x.this.own(v), doc="The membership flag") + + def __init__(self, *args, **kwargs): + raise AttributeError("No constructor defined - class is abstract") + __repr__ = _swig_repr + __swig_destroy__ = _wedpr_python_transport.delete_MessageBuilder + + def build(self, *args): + return _wedpr_python_transport.MessageBuilder_build(self, *args) + + +# Register MessageBuilder in _wedpr_python_transport: +_wedpr_python_transport.MessageBuilder_swigregister(MessageBuilder) + + +class MessageOptionalHeaderBuilder(object): + thisown = property(lambda x: x.this.own(), lambda x, + v: x.this.own(v), doc="The membership flag") + + def __init__(self, *args, **kwargs): + raise AttributeError("No constructor defined - class is abstract") + __repr__ = _swig_repr + __swig_destroy__ = _wedpr_python_transport.delete_MessageOptionalHeaderBuilder + + def build(self, *args): + return _wedpr_python_transport.MessageOptionalHeaderBuilder_build(self, *args) + + +# Register MessageOptionalHeaderBuilder in _wedpr_python_transport: +_wedpr_python_transport.MessageOptionalHeaderBuilder_swigregister( + MessageOptionalHeaderBuilder) + + +def printOptionalField(optionalHeader): + return _wedpr_python_transport.printOptionalField(optionalHeader) + + +def printMessage(_msg): + return _wedpr_python_transport.printMessage(_msg) + + +FrontMsgExtFlag_Response = _wedpr_python_transport.FrontMsgExtFlag_Response + + +class MessagePayload(object): + thisown = property(lambda x: x.this.own(), lambda x, + v: x.this.own(v), doc="The membership flag") + + def __init__(self, *args, **kwargs): + raise AttributeError("No constructor defined - class is abstract") + __repr__ = _swig_repr + __swig_destroy__ = _wedpr_python_transport.delete_MessagePayload + + def encode(self, buffer): + return _wedpr_python_transport.MessagePayload_encode(self, buffer) + + def decode(self, data): + return _wedpr_python_transport.MessagePayload_decode(self, data) + + def version(self): + return _wedpr_python_transport.MessagePayload_version(self) + + def setVersion(self, version): + return _wedpr_python_transport.MessagePayload_setVersion(self, version) + + def dataBuffer(self): + return _wedpr_python_transport.MessagePayload_dataBuffer(self) + + def seq(self): + return _wedpr_python_transport.MessagePayload_seq(self) + + def setSeq(self, seq): + return _wedpr_python_transport.MessagePayload_setSeq(self, seq) + + def length(self): + return _wedpr_python_transport.MessagePayload_length(self) + + def traceID(self): + return _wedpr_python_transport.MessagePayload_traceID(self) + + def setTraceID(self, traceID): + return _wedpr_python_transport.MessagePayload_setTraceID(self, traceID) + + def ext(self): + return _wedpr_python_transport.MessagePayload_ext(self) + + def setExt(self, ext): + return _wedpr_python_transport.MessagePayload_setExt(self, ext) + + def setRespPacket(self): + return _wedpr_python_transport.MessagePayload_setRespPacket(self) + + def isRespPacket(self): + return _wedpr_python_transport.MessagePayload_isRespPacket(self) + + def releasePayload(self): + return _wedpr_python_transport.MessagePayload_releasePayload(self) + + +# Register MessagePayload in _wedpr_python_transport: +_wedpr_python_transport.MessagePayload_swigregister(MessagePayload) + + +class MessagePayloadBuilder(object): + thisown = property(lambda x: x.this.own(), lambda x, + v: x.this.own(v), doc="The membership flag") + + def __init__(self, *args, **kwargs): + raise AttributeError("No constructor defined - class is abstract") + __repr__ = _swig_repr + __swig_destroy__ = _wedpr_python_transport.delete_MessagePayloadBuilder + + def build(self, *args): + return _wedpr_python_transport.MessagePayloadBuilder_build(self, *args) + + +# Register MessagePayloadBuilder in _wedpr_python_transport: +_wedpr_python_transport.MessagePayloadBuilder_swigregister( + MessagePayloadBuilder) + + +class IFrontClient(object): + thisown = property(lambda x: x.this.own(), lambda x, + v: x.this.own(v), doc="The membership flag") + + def __init__(self, *args, **kwargs): + raise AttributeError("No constructor defined - class is abstract") + __repr__ = _swig_repr + __swig_destroy__ = _wedpr_python_transport.delete_IFrontClient + + def onReceiveMessage(self, _msg, _callback): + r""" + : receive message from gateway, call by gateway + :param _message:: received ppc message + :rtype: void + :return: void + """ + return _wedpr_python_transport.IFrontClient_onReceiveMessage(self, _msg, _callback) + + +# Register IFrontClient in _wedpr_python_transport: +_wedpr_python_transport.IFrontClient_swigregister(IFrontClient) + + +class ErrorCallback(object): + thisown = property(lambda x: x.this.own(), lambda x, + v: x.this.own(v), doc="The membership flag") + __repr__ = _swig_repr + + def __init__(self): + if self.__class__ == ErrorCallback: + _self = None + else: + _self = self + _wedpr_python_transport.ErrorCallback_swiginit( + self, _wedpr_python_transport.new_ErrorCallback(_self, )) + __swig_destroy__ = _wedpr_python_transport.delete_ErrorCallback + + def onError(self, error): + return _wedpr_python_transport.ErrorCallback_onError(self, error) + + def __disown__(self): + self.this.disown() + _wedpr_python_transport.disown_ErrorCallback(self) + return weakref.proxy(self) + + +# Register ErrorCallback in _wedpr_python_transport: +_wedpr_python_transport.ErrorCallback_swigregister(ErrorCallback) + + +class MessageDispatcherHandler(object): + thisown = property(lambda x: x.this.own(), lambda x, + v: x.this.own(v), doc="The membership flag") + __repr__ = _swig_repr + + def __init__(self): + if self.__class__ == MessageDispatcherHandler: + _self = None + else: + _self = self + _wedpr_python_transport.MessageDispatcherHandler_swiginit( + self, _wedpr_python_transport.new_MessageDispatcherHandler(_self, )) + __swig_destroy__ = _wedpr_python_transport.delete_MessageDispatcherHandler + + def onMessage(self, msg): + return _wedpr_python_transport.MessageDispatcherHandler_onMessage(self, msg) + + def __disown__(self): + self.this.disown() + _wedpr_python_transport.disown_MessageDispatcherHandler(self) + return weakref.proxy(self) + + +# Register MessageDispatcherHandler in _wedpr_python_transport: +_wedpr_python_transport.MessageDispatcherHandler_swigregister( + MessageDispatcherHandler) + + +class SendResponseHandler(object): + thisown = property(lambda x: x.this.own(), lambda x, + v: x.this.own(v), doc="The membership flag") + __repr__ = _swig_repr + + def __init__(self, responseFunc): + _wedpr_python_transport.SendResponseHandler_swiginit( + self, _wedpr_python_transport.new_SendResponseHandler(responseFunc)) + __swig_destroy__ = _wedpr_python_transport.delete_SendResponseHandler + + def sendResponse(self, payload): + return _wedpr_python_transport.SendResponseHandler_sendResponse(self, payload) + + +# Register SendResponseHandler in _wedpr_python_transport: +_wedpr_python_transport.SendResponseHandler_swigregister(SendResponseHandler) + + +class IMessageHandler(object): + thisown = property(lambda x: x.this.own(), lambda x, + v: x.this.own(v), doc="The membership flag") + __repr__ = _swig_repr + + def __init__(self): + if self.__class__ == IMessageHandler: + _self = None + else: + _self = self + _wedpr_python_transport.IMessageHandler_swiginit( + self, _wedpr_python_transport.new_IMessageHandler(_self, )) + __swig_destroy__ = _wedpr_python_transport.delete_IMessageHandler + + def onMessage(self, e, msg, sendResponseHandler): + return _wedpr_python_transport.IMessageHandler_onMessage(self, e, msg, sendResponseHandler) + + def __disown__(self): + self.this.disown() + _wedpr_python_transport.disown_IMessageHandler(self) + return weakref.proxy(self) + + +# Register IMessageHandler in _wedpr_python_transport: +_wedpr_python_transport.IMessageHandler_swigregister(IMessageHandler) + + +class GetPeersInfoHandler(object): + thisown = property(lambda x: x.this.own(), lambda x, + v: x.this.own(v), doc="The membership flag") + __repr__ = _swig_repr + + def __init__(self): + if self.__class__ == GetPeersInfoHandler: + _self = None + else: + _self = self + _wedpr_python_transport.GetPeersInfoHandler_swiginit( + self, _wedpr_python_transport.new_GetPeersInfoHandler(_self, )) + __swig_destroy__ = _wedpr_python_transport.delete_GetPeersInfoHandler + + def onPeersInfo(self, e, peersInfo): + return _wedpr_python_transport.GetPeersInfoHandler_onPeersInfo(self, e, peersInfo) + + def __disown__(self): + self.this.disown() + _wedpr_python_transport.disown_GetPeersInfoHandler(self) + return weakref.proxy(self) + + +# Register GetPeersInfoHandler in _wedpr_python_transport: +_wedpr_python_transport.GetPeersInfoHandler_swigregister(GetPeersInfoHandler) + + +class IFront(IFrontClient): + thisown = property(lambda x: x.this.own(), lambda x, + v: x.this.own(v), doc="The membership flag") + + def __init__(self, *args, **kwargs): + raise AttributeError("No constructor defined - class is abstract") + __repr__ = _swig_repr + __swig_destroy__ = _wedpr_python_transport.delete_IFront + + def start(self): + r""" + start the IFront + + :param front: the IFront to start + """ + return _wedpr_python_transport.IFront_start(self) + + def stop(self): + r""" + stop the IFront + + :param front: the IFront to stop + """ + return _wedpr_python_transport.IFront_stop(self) + + def register_topic_handler(self, topic, callback): + return _wedpr_python_transport.IFront_register_topic_handler(self, topic, callback) + + def register_msg_handler(self, componentType, callback): + return _wedpr_python_transport.IFront_register_msg_handler(self, componentType, callback) + + def async_send_message(self, routeType, routeInfo, payload, seq, timeout, errorCallback, msgHandler): + return _wedpr_python_transport.IFront_async_send_message(self, routeType, routeInfo, payload, seq, timeout, errorCallback, msgHandler) + + def async_send_response(self, dstNode, dstNodeSize, traceID, payload, seq, errorCallback): + return _wedpr_python_transport.IFront_async_send_response(self, dstNode, dstNodeSize, traceID, payload, seq, errorCallback) + + def push_msg(self, routeType, routeInfo, payload, seq, timeout): + return _wedpr_python_transport.IFront_push_msg(self, routeType, routeInfo, payload, seq, timeout) + + def pop(self, topic, timeoutMs): + return _wedpr_python_transport.IFront_pop(self, topic, timeoutMs) + + def peek(self, topic): + return _wedpr_python_transport.IFront_peek(self, topic) + + def asyncGetPeers(self, getPeersCallback): + return _wedpr_python_transport.IFront_asyncGetPeers(self, getPeersCallback) + + def nodeInfo(self): + return _wedpr_python_transport.IFront_nodeInfo(self) + + def registerTopic(self, topic): + r""" + register the topic + + :type topic: string + :param topic: the topic to register + """ + return _wedpr_python_transport.IFront_registerTopic(self, topic) + + def unRegisterTopic(self, topic): + r""" + unRegister the topic + + :type topic: string + :param topic: the topic to unregister + """ + return _wedpr_python_transport.IFront_unRegisterTopic(self, topic) + + def registerComponent(self, component): + return _wedpr_python_transport.IFront_registerComponent(self, component) + + def unRegisterComponent(self, component): + return _wedpr_python_transport.IFront_unRegisterComponent(self, component) + + def updateMetaInfo(self, meta): + return _wedpr_python_transport.IFront_updateMetaInfo(self, meta) + + def selectNodesByRoutePolicy(self, routeType, routeInfo): + return _wedpr_python_transport.IFront_selectNodesByRoutePolicy(self, routeType, routeInfo) + + def getNodeDiscovery(self): + return _wedpr_python_transport.IFront_getNodeDiscovery(self) + + +# Register IFront in _wedpr_python_transport: +_wedpr_python_transport.IFront_swigregister(IFront) + + +class IFrontBuilder(object): + thisown = property(lambda x: x.this.own(), lambda x, + v: x.this.own(v), doc="The membership flag") + + def __init__(self, *args, **kwargs): + raise AttributeError("No constructor defined - class is abstract") + __repr__ = _swig_repr + __swig_destroy__ = _wedpr_python_transport.delete_IFrontBuilder + + def buildClient(self, endPoint, onUnHealthHandler, removeHandlerOnUnhealth): + return _wedpr_python_transport.IFrontBuilder_buildClient(self, endPoint, onUnHealthHandler, removeHandlerOnUnhealth) + + +# Register IFrontBuilder in _wedpr_python_transport: +_wedpr_python_transport.IFrontBuilder_swigregister(IFrontBuilder) + + +class INodeDiscovery(object): + thisown = property(lambda x: x.this.own(), lambda x, + v: x.this.own(v), doc="The membership flag") + + def __init__(self, *args, **kwargs): + raise AttributeError("No constructor defined - class is abstract") + __repr__ = _swig_repr + __swig_destroy__ = _wedpr_python_transport.delete_INodeDiscovery + + def getAliveNodeList(self): + return _wedpr_python_transport.INodeDiscovery_getAliveNodeList(self) + + +# Register INodeDiscovery in _wedpr_python_transport: +_wedpr_python_transport.INodeDiscovery_swigregister(INodeDiscovery) +SDKMode_AIR = _wedpr_python_transport.SDKMode_AIR +SDKMode_PRO = _wedpr_python_transport.SDKMode_PRO + + +class TransportBuilder(object): + thisown = property(lambda x: x.this.own(), lambda x, + v: x.this.own(v), doc="The membership flag") + __repr__ = _swig_repr + + def __init__(self): + _wedpr_python_transport.TransportBuilder_swiginit( + self, _wedpr_python_transport.new_TransportBuilder()) + __swig_destroy__ = _wedpr_python_transport.delete_TransportBuilder + + def buildProTransport(self, config): + return _wedpr_python_transport.TransportBuilder_buildProTransport(self, config) + + def buildConfig(self, threadPoolSize, nodeID): + return _wedpr_python_transport.TransportBuilder_buildConfig(self, threadPoolSize, nodeID) + + def frontConfigBuilder(self): + return _wedpr_python_transport.TransportBuilder_frontConfigBuilder(self) + + def initLog(self, configPath): + return _wedpr_python_transport.TransportBuilder_initLog(self, configPath) + + +# Register TransportBuilder in _wedpr_python_transport: +_wedpr_python_transport.TransportBuilder_swigregister(TransportBuilder) + + +class Transport(object): + thisown = property(lambda x: x.this.own(), lambda x, + v: x.this.own(v), doc="The membership flag") + __repr__ = _swig_repr + + def __init__(self, config): + _wedpr_python_transport.Transport_swiginit( + self, _wedpr_python_transport.new_Transport(config)) + __swig_destroy__ = _wedpr_python_transport.delete_Transport + + def start(self): + return _wedpr_python_transport.Transport_start(self) + + def stop(self): + return _wedpr_python_transport.Transport_stop(self) + + def getFront(self): + return _wedpr_python_transport.Transport_getFront(self) + + def gateway(self): + return _wedpr_python_transport.Transport_gateway(self) + + def msgPayloadBuilder(self): + return _wedpr_python_transport.Transport_msgPayloadBuilder(self) + + def msgBuilder(self): + return _wedpr_python_transport.Transport_msgBuilder(self) + + def msgHeaderBuilder(self): + return _wedpr_python_transport.Transport_msgHeaderBuilder(self) + + def routeInfoBuilder(self): + return _wedpr_python_transport.Transport_routeInfoBuilder(self) + + def getConfig(self): + return _wedpr_python_transport.Transport_getConfig(self) + + +# Register Transport in _wedpr_python_transport: +_wedpr_python_transport.Transport_swigregister(Transport) + + +class INodeInfo(object): + thisown = property(lambda x: x.this.own(), lambda x, + v: x.this.own(v), doc="The membership flag") + + def __init__(self, *args, **kwargs): + raise AttributeError("No constructor defined - class is abstract") + __repr__ = _swig_repr + __swig_destroy__ = _wedpr_python_transport.delete_INodeInfo + + def endPoint(self): + return _wedpr_python_transport.INodeInfo_endPoint(self) + + def nodeID(self): + return _wedpr_python_transport.INodeInfo_nodeID(self) + + def setNodeID(self, nodeID): + return _wedpr_python_transport.INodeInfo_setNodeID(self, nodeID) + + def setEndPoint(self, endPoint): + return _wedpr_python_transport.INodeInfo_setEndPoint(self, endPoint) + + def addComponent(self, component): + return _wedpr_python_transport.INodeInfo_addComponent(self, component) + + def eraseComponent(self, component): + return _wedpr_python_transport.INodeInfo_eraseComponent(self, component) + + def componentExist(self, component): + return _wedpr_python_transport.INodeInfo_componentExist(self, component) + + def copiedComponents(self): + return _wedpr_python_transport.INodeInfo_copiedComponents(self) + + def meta(self): + return _wedpr_python_transport.INodeInfo_meta(self) + + def setMeta(self, meta): + return _wedpr_python_transport.INodeInfo_setMeta(self, meta) + + +# Register INodeInfo in _wedpr_python_transport: +_wedpr_python_transport.INodeInfo_swigregister(INodeInfo) + + +def printNodeInfo(nodeInfo): + return _wedpr_python_transport.printNodeInfo(nodeInfo) diff --git a/cpp/wedpr-transport/sdk-wrapper/python/bindings/wedpr_python_gateway_sdk/transport/impl/__init__.py b/cpp/wedpr-transport/sdk-wrapper/python/bindings/wedpr_python_gateway_sdk/transport/impl/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/cpp/wedpr-transport/sdk-wrapper/python/bindings/wedpr_python_gateway_sdk/transport/impl/message_factory.py b/cpp/wedpr-transport/sdk-wrapper/python/bindings/wedpr_python_gateway_sdk/transport/impl/message_factory.py new file mode 100644 index 00000000..1ee38f3c --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/python/bindings/wedpr_python_gateway_sdk/transport/impl/message_factory.py @@ -0,0 +1,11 @@ +from wedpr_python_gateway_sdk.transport.impl.message_impl import MessageImpl +from wedpr_python_gateway_sdk.transport.api.message_api import MessageAPI +from wedpr_python_gateway_sdk.transport.generated.wedpr_python_transport import Message + + +class MessageFactory: + @staticmethod + def build(message: Message) -> MessageAPI: + if message is None: + return None + return MessageImpl(message) diff --git a/cpp/wedpr-transport/sdk-wrapper/python/bindings/wedpr_python_gateway_sdk/transport/impl/message_impl.py b/cpp/wedpr-transport/sdk-wrapper/python/bindings/wedpr_python_gateway_sdk/transport/impl/message_impl.py new file mode 100644 index 00000000..aec2cfc5 --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/python/bindings/wedpr_python_gateway_sdk/transport/impl/message_impl.py @@ -0,0 +1,93 @@ +# -*- coding: utf-8 -*- + +from wedpr_python_gateway_sdk.transport.api.message_api import MessageHeaderAPI +from wedpr_python_gateway_sdk.transport.api.message_api import MessageAPI +from wedpr_python_gateway_sdk.transport.generated.wedpr_python_transport import Message +from wedpr_python_gateway_sdk.transport.generated.wedpr_python_transport import MessageHeader + + +class MessageHeaderImpl(MessageHeaderAPI): + + def __init__(self, header: MessageHeader): + if header is None: + raise Exception( + "Build MessageHeader failed for empty header object passed in") + self.__header = header + + def get_version(self) -> str: + return self.__header.version() + + def get_trace_id(self) -> str: + return self.__header.traceID() + + def get_src_gw_node(self) -> str: + return self.__header.srcGwNode() + + def get_dst_gw_node(self) -> str: + return self.__header.dstGwNode() + + def get_packet_type(self) -> int: + return self.__header.packetType() + + def get_ttl(self) -> int: + return self.__header.ttl() + + def get_ext(self) -> int: + return self.__header.exit() + + def is_resp_packet(self) -> bool: + return self.__header.isRespPacket() + + def get_route_type(self) -> int: + return self.__header.routeType() + + def get_component_type(self) -> str: + return self.__header.optionalField().componentType() + + def get_src_node(self) -> bytes: + return self.__header.optionalField().srcNodeBuffer() + + def get_dst_node(self) -> bytes: + return self.__header.optionalField().dstNodeBuffer() + + def get_dst_inst(self) -> str: + return self.__header.optionalField().dstInst() + + def get_src_inst(self) -> str: + return self.__header.optionalField().srcInst() + + def get_topic(self) -> str: + return self.__header.optionalField().topic() + + def detail(self) -> str: + return f"version: {self.get_version()}, topic: {self.get_topic()}, src_inst: {self.get_src_inst()},src_node: {str(self.get_src_node())}, dst_inst: {self.get_dst_inst()}, dst_node: {str(self.get_dst_node())}" + + def __repr__(self): + return self.detail() + + +class MessageImpl(MessageAPI): + def __init__(self, message: Message): + if message is None: + raise Exception( + "Build Message failed for empty message object passed in") + self.__message = message + self.__message_header = MessageHeaderImpl(self.__message.header()) + + def get_header(self) -> MessageHeaderAPI: + return self.__message_header + + def get_seq(self) -> int: + return self.__message.frontMessage().seq() + + def get_payload(self) -> bytes: + return self.__message.frontMessage().dataBuffer() + + def get_length(self) -> int: + return self.__message.frontMessage().length() + + def detail(self) -> str: + return f"seq: {self.get_seq()}, header: {self.get_header().detail()}, length: {self.get_length()}" + + def __repr__(self): + return self.detail() diff --git a/cpp/wedpr-transport/sdk-wrapper/python/bindings/wedpr_python_gateway_sdk/transport/impl/route_info_builder.py b/cpp/wedpr-transport/sdk-wrapper/python/bindings/wedpr_python_gateway_sdk/transport/impl/route_info_builder.py new file mode 100644 index 00000000..498e78b7 --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/python/bindings/wedpr_python_gateway_sdk/transport/impl/route_info_builder.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +from wedpr_python_gateway_sdk.transport.generated.wedpr_python_transport import MessageOptionalHeaderBuilder +from wedpr_python_gateway_sdk.transport.generated.wedpr_python_transport import MessageOptionalHeader + + +class RouteInfoBuilder: + def __init__(self, builder: MessageOptionalHeaderBuilder): + self.__route_info_builder = builder + + def build(self, topic: str, dst_node: bytes, dst_inst: str, component: str) -> MessageOptionalHeader: + routeInfo = self.__route_info_builder.build() + if topic is not None: + routeInfo.setTopic(topic) + if dst_node is not None: + routeInfo.setDstNodeBuffer(dst_node) + if dst_inst is not None: + routeInfo.setDstInst(dst_inst) + if component is not None: + routeInfo.setComponentType(component) + return routeInfo diff --git a/cpp/wedpr-transport/sdk-wrapper/python/bindings/wedpr_python_gateway_sdk/transport/impl/transport.py b/cpp/wedpr-transport/sdk-wrapper/python/bindings/wedpr_python_gateway_sdk/transport/impl/transport.py new file mode 100644 index 00000000..2b9260a3 --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/python/bindings/wedpr_python_gateway_sdk/transport/impl/transport.py @@ -0,0 +1,156 @@ +# -*- coding: utf-8 -*- + +from wedpr_python_gateway_sdk.transport.generated.wedpr_python_transport import TransportBuilder +from wedpr_python_gateway_sdk.transport.generated.wedpr_python_transport import Transport +from wedpr_python_gateway_sdk.transport.generated.wedpr_python_transport import StringVec +from wedpr_python_gateway_sdk.transport.generated.wedpr_python_transport import Error +from wedpr_python_gateway_sdk.transport.api.message_api import MessageAPI +from wedpr_python_gateway_sdk.transport.impl.route_info_builder import RouteInfoBuilder +from wedpr_python_gateway_sdk.transport.impl.message_factory import MessageFactory +from wedpr_python_gateway_sdk.transport.generated.wedpr_python_transport import MessageOptionalHeader +from wedpr_python_gateway_sdk.transport.api.transport_api import TransportAPI +from wedpr_python_gateway_sdk.transport.impl.transport_config import TransportConfig +import random +from wedpr_python_gateway_sdk.transport.api.transport_api import EntryPointInfo +from wedpr_python_gateway_sdk.transport.api.transport_api import ServiceMeta +from enum import Enum +import signal + + +class RouteType(Enum): + ROUTE_THROUGH_NODEID = 0 + ROUTE_THROUGH_COMPONENT = 1 + ROUTE_THROUGH_AGENCY = 2 + ROUTE_THROUGH_TOPIC = 3 + + +class Transport(TransportAPI): + should_exit = False + + def __init__(self, transport: Transport, transport_config: TransportConfig): + self.__transport = transport + self.__transport_config = transport_config + self.__route_info_builder = RouteInfoBuilder( + self.__transport.routeInfoBuilder()) + self.service_meta = transport_config.service_meta + + def get_config(self) -> TransportConfig: + return self.__transport_config + + def start(self): + self.__transport.start() + + def stop(self): + self.__transport.stop() + + def _push_msg(self, route_type: int, route_info: MessageOptionalHeader, payload: bytes, seq: int, timeout: int): + try: + return self.__transport.getFront().push_msg(route_type, route_info, payload, seq, timeout) + except Exception as e: + raise e + + def select_node_list_by_route_policy(self, route_type: RouteType, dst_inst: str, dst_component: str, dst_node: str = None) -> tuple: + dst_node_bytes = None + if dst_node is not None: + dst_node_bytes = bytes(dst_node, encodings="utf-8") + route_info = self.__route_info_builder.build(topic=None, dst_inst=dst_inst, + component=dst_component, dst_node=dst_node_bytes) + try: + return self.__transport.getFront().selectNodesByRoutePolicy( + route_type.value, route_info) + except Exception as e: + raise e + + def select_node_by_route_policy(self, route_type: RouteType, dst_inst: str, dst_component: str, dst_node: str = None) -> str: + node_list = self.select_node_list_by_route_policy( + route_type, dst_inst, dst_component, dst_node) + if node_list is None or len(node_list) == 0: + return None + selected_node_idx = random.randint(0, len(node_list) - 1) + return node_list[selected_node_idx] + + def push_by_nodeid(self, topic: str, dstNode: bytes, seq: int, payload: bytes, timeout: int): + route_info = self.__route_info_builder.build( + topic=topic, dst_node=dstNode, dst_inst=None, component=None) + result = self._push_msg( + RouteType.ROUTE_THROUGH_NODEID.value, route_info, payload, seq, timeout) + Transport.check_result("push_by_nodeid", result) + + def push_by_topic(self, topic: str, dstInst: str, seq: int, payload: bytes, timeout: int): + route_info = self.__route_info_builder.build( + topic=topic, dst_node=None, dst_inst=dstInst, component=None) + result = self._push_msg( + RouteType.ROUTE_THROUGH_TOPIC.value, route_info, payload, seq, timeout) + Transport.check_result("push_by_topic", result) + + def push_by_inst(self, topic: str, dstInst: str, seq: int, payload: bytes, timeout: int): + route_info = self.__route_info_builder.build( + topic=topic, dst_node=None, dst_inst=dstInst, component=None) + result = self._push_msg( + RouteType.ROUTE_THROUGH_AGENCY.value, route_info, payload, len(payload), seq, timeout) + Transport.check_result("push_by_inst", result) + + def push_by_component(self, topic: str, dstInst: str, component: str, seq: int, payload: bytes, timeout: int): + route_info = self.__route_info_builder.build( + topic=topic, dst_node=None, dst_inst=dstInst, component=component) + result = self._push_msg( + RouteType.ROUTE_THROUGH_COMPONENT.value, route_info, payload, len(payload), seq, timeout) + Transport.check_result("push_by_component", result) + + def pop(self, topic, timeout_ms) -> MessageAPI: + return MessageFactory.build(self.__transport.getFront().pop(topic, timeout_ms)) + + def peek(self, topic): + return self.__transport.peek(topic) + + @staticmethod + def check_result(method: str, result: Error): + if result is None: + return + if result.errorCode() != 0: + raise Exception( + f"call {method} failed for {result.errorMessage()}, code: {result.errorCode()}") + + def register_topic(self, topic): + result = self.__transport.getFront().registerTopic(topic) + Transport.check_result("register_topic", result) + + def unregister_topic(self, topic): + result = self.__transport.getFront().unRegisterTopic(topic) + Transport.check_result("unregister_topic", result) + + def register_component(self, component): + result = self.__transport.getFront().registerComponent(component) + Transport.check_result("register_component", result) + + def unregister_component(self, component): + result = self.__transport.getFront().unRegisterComponent(component) + Transport.check_result("unregister_component", result) + + def get_alive_entrypoints(self, service_name: str) -> [EntryPointInfo]: + alive_entrypoints = [] + alive_node_list = self.__transport.getFront().getNodeDiscovery().getAliveNodeList() + if alive_node_list is None or len(alive_node_list) == 0: + return alive_entrypoints + for i in range(0, len(alive_node_list)): + alive_node_info = alive_node_list[i] + service_meta = ServiceMeta.decode(alive_node_info.meta()) + if service_meta is None or service_meta.serviceInfos is None or len(service_meta.serviceInfos) == 0: + continue + for entrypoint_info in service_meta.serviceInfos: + if entrypoint_info.serviceName.lower() == service_name.lower(): + alive_entrypoints.append(entrypoint_info) + return alive_entrypoints + + def register_service_info(self, service, entrypoint): + self.service_meta.serviceInfos.append(EntryPointInfo( + service_name=service, entrypoint=entrypoint)) + self.__transport.getFront().updateMetaInfo(self.service_meta.encode()) + + +def signal_handler(sig, frame): + print('You pressed Ctrl+C! Exiting gracefully.') + Transport.should_exit = True + + +signal.signal(signal.SIGINT, signal_handler) diff --git a/cpp/wedpr-transport/sdk-wrapper/python/bindings/wedpr_python_gateway_sdk/transport/impl/transport_config.py b/cpp/wedpr-transport/sdk-wrapper/python/bindings/wedpr_python_gateway_sdk/transport/impl/transport_config.py new file mode 100644 index 00000000..d8f5e3ea --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/python/bindings/wedpr_python_gateway_sdk/transport/impl/transport_config.py @@ -0,0 +1,68 @@ +# -*- coding: utf-8 -*- + +import json +from wedpr_python_gateway_sdk.transport.generated.wedpr_python_transport import FrontConfig +from wedpr_python_gateway_sdk.transport.generated.wedpr_python_transport import TransportBuilder +from wedpr_python_gateway_sdk.transport.generated.wedpr_python_transport import EndPoint +from wedpr_python_gateway_sdk.transport.generated.wedpr_python_transport import GrpcConfig +from wedpr_python_gateway_sdk.transport.api.transport_api import ServiceMeta +from wedpr_python_gateway_sdk.transport.api.transport_api import EntryPointInfo + + +class TransportConfig: + """ + the transport config + """ + + def __init__(self, threadpool_size: int, nodeID: str, gateway_targets: str): + self.__transport_builder = TransportBuilder() + self.__front_config = self.__transport_builder.buildConfig( + threadpool_size, nodeID) + self.__front_config.setGatewayGrpcTarget(gateway_targets) + self.service_meta = ServiceMeta(entrypoints_info=[]) + + def get_front_config(self) -> FrontConfig: + return self.__front_config + + def register_service_info(self, service, entrypoint): + self.service_meta.serviceInfos.append(EntryPointInfo( + service_name=service, entrypoint=entrypoint)) + self.__front_config.setMeta(self.service_meta.encode()) + + def register_service_meta(self, service_meta: ServiceMeta): + if service_meta is None: + return + self.service_meta = service_meta + self.__front_config.setMeta(self.service_meta.encode()) + + def get_service_meta(self) -> ServiceMeta: + return self.service_meta + + def set_self_endpoint(self, host: str, port: int, listen_ip: str = None): + endpoint = EndPoint(host, port) + if listen_ip is None: + listen_ip = "0.0.0.0" + endpoint.setListenIp(listen_ip) + self.__front_config.setSelfEndPoint(endpoint) + + def set_grpc_config(self, grpc_config: GrpcConfig): + self.__front_config.setGrpcConfig(grpc_config) + + def get_thread_pool_size(self) -> int: + return self.__front_config.threadPoolSize() + + def get_node_id(self) -> str: + return self.__front_config.nodeID() + + def get_gateway_targets(self) -> str: + return self.__front_config.gatewayGrpcTarget() + + def get_self_endpoint(self) -> EndPoint: + return self.__front_config.selfEndPoint() + + def desc(self): + return f"thread_pool_size: {self.get_thread_pool_size()}, \ + nodeID: {self.get_node_id()}, \ + gatewayTargets: {self.get_gateway_targets()}, \ + endPoint: {self.get_self_endpoint().entryPoint()}," \ + f"serviceMeta: {self.service_meta}" diff --git a/cpp/wedpr-transport/sdk-wrapper/python/bindings/wedpr_python_gateway_sdk/transport/impl/transport_loader.py b/cpp/wedpr-transport/sdk-wrapper/python/bindings/wedpr_python_gateway_sdk/transport/impl/transport_loader.py new file mode 100644 index 00000000..cb602232 --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/python/bindings/wedpr_python_gateway_sdk/transport/impl/transport_loader.py @@ -0,0 +1,93 @@ +# -*- coding: utf-8 -*- +from wedpr_python_gateway_sdk.utils.base_object import BaseObject +from wedpr_python_gateway_sdk.transport.impl.transport_config import TransportConfig +from wedpr_python_gateway_sdk.transport.generated.wedpr_python_transport import TransportBuilder +from wedpr_python_gateway_sdk.transport.impl.transport import Transport +from wedpr_python_gateway_sdk.utils import utils +import signal + + +class TransportConfigObject(BaseObject): + DEFAULT_THREADPOOL_SIZE = 4 + DEFAULT_LISTEN_IP = "0.0.0.0" + + def __init__(self, transport_threadpool_size: int = DEFAULT_THREADPOOL_SIZE, + transport_node_id: str = None, + transport_gateway_targets: str = None, + transport_host_ip: str = None, + transport_listen_port: int = None, + transport_listen_ip: str = DEFAULT_LISTEN_IP, + **params): + self.transport_threadpool_size = transport_threadpool_size + self.transport_node_id = transport_node_id + self.transport_gateway_targets = transport_gateway_targets + self.transport_host_ip = transport_host_ip + self.transport_listen_port = transport_listen_port + self.transport_listen_ip = transport_listen_ip + self.set_params(**params) + self.__check() + + def __check(self): + if self.transport_threadpool_size <= 0: + self.transport_threadpool_size = TransportConfigObject.DEFAULT_THREADPOOL_SIZE + utils.require_not_empty("transport_node_id", self.transport_node_id) + utils.require_not_empty( + "transport_gateway_targets", self.transport_gateway_targets) + utils.require_not_empty("transport_host_ip", self.transport_host_ip) + if self.transport_listen_port <= 0 or self.transport_listen_port > 65535: + raise Exception( + f"Invalid transport listen port: {self.transport_listen_port}, must between 0-65535!") + + def __repr__(self): + return f"transport_threadpool_size: {self.transport_threadpool_size}, " \ + f"transport_node_id: {self.transport_node_id}, " \ + f"transport_gateway_targets: {self.transport_gateway_targets}, " \ + f"transport_host_ip: {self.transport_host_ip}, transport_listen_port: {self.transport_listen_port}" + + +class TransportLoader: + transport_builder = TransportBuilder() + transport_builder.initLog("conf/wedpr_sdk_log_config.ini") + + @staticmethod + def load(transport_config: TransportConfig) -> Transport: + transport = TransportLoader.transport_builder.buildProTransport( + transport_config.get_front_config()) + return Transport(transport, transport_config) + + @staticmethod + def build_config(transport_threadpool_size: int = 4, + transport_node_id: str = None, + transport_gateway_targets: str = None, + transport_host_ip: str = None, + transport_listen_port: int = None, + **params) -> TransportConfig: + config = TransportConfigObject(transport_threadpool_size, + transport_node_id, + transport_gateway_targets, + transport_host_ip, + transport_listen_port, **params) + # build the transport config + transport_config = TransportConfig(config.transport_threadpool_size, + config.transport_node_id, + config.transport_gateway_targets) + # set the self-endpoint + transport_config.set_self_endpoint(config.transport_host_ip, + config.transport_listen_port, + config.transport_listen_ip) + return transport_config + + @staticmethod + def build(transport_threadpool_size: int = 4, + transport_node_id: str = None, + transport_gateway_targets: str = None, + transport_host_ip: str = None, + transport_listen_port: int = None, + **params): + transport_config = TransportLoader.build_config(transport_threadpool_size, + transport_node_id, + transport_gateway_targets, + transport_host_ip, + transport_listen_port, + **params) + return TransportLoader.load(transport_config) diff --git a/cpp/wedpr-transport/sdk-wrapper/python/bindings/wedpr_python_gateway_sdk/utils/__init__.py b/cpp/wedpr-transport/sdk-wrapper/python/bindings/wedpr_python_gateway_sdk/utils/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/cpp/wedpr-transport/sdk-wrapper/python/bindings/wedpr_python_gateway_sdk/utils/base_object.py b/cpp/wedpr-transport/sdk-wrapper/python/bindings/wedpr_python_gateway_sdk/utils/base_object.py new file mode 100644 index 00000000..0dd026b8 --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/python/bindings/wedpr_python_gateway_sdk/utils/base_object.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +from typing import Any +import time + + +class BaseObject: + def set_params(self, **params: Any): + for key, value in params.items(): + setattr(self, key, value) + if hasattr(self, f"{key}"): + setattr(self, f"{key}", value) + return self + + def as_dict(obj): + return {attr: getattr(obj, attr) for attr in dir(obj) if not callable(getattr(obj, attr)) and not attr.startswith("__")} diff --git a/cpp/wedpr-transport/sdk-wrapper/python/bindings/wedpr_python_gateway_sdk/utils/lib_loader.py b/cpp/wedpr-transport/sdk-wrapper/python/bindings/wedpr_python_gateway_sdk/utils/lib_loader.py new file mode 100644 index 00000000..e469aca7 --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/python/bindings/wedpr_python_gateway_sdk/utils/lib_loader.py @@ -0,0 +1,81 @@ +# -*- coding: utf-8 -*- + +import platform +import os +from enum import Enum +import sys +import ctypes + + +class OSType(Enum): + MACOS_X64 = 1 + MACOS_ARM64 = 2 + WINDOWS = 3 + LINUX_X64 = 4 + LINUX_ARM64 = 5 + + +class ArchType(Enum): + ARM64 = 1 + X86_64 = 2 + + +class LibLoader: + # the library information + TRANSPORT_LIB_PATH = "libs" + TRANSPORT_LIB_NAME = "wedpr_python_transport" + LIB_PREFIX = "lib" + MACOS_LIB_POSTFIX = "dylib" + WINDOWS_LIB_POSTFIX = "dll" + LINUX_LIB_PORSTFIX = "so" + # the OS name + MACOS_OS = "darwin" + WINDOWS_OS = "windows" + LINUX_OS = "linux" + + AARCH64 = "aarch64" + ARM64 = "arm64" + X86_64 = "x86_64" + + @staticmethod + def get_arch_type(): + arch_type = platform.machine().lower() + if LibLoader.AARCH64 in arch_type or LibLoader.ARM64 in arch_type: + return ArchType.ARM64 + if LibLoader.X86_64 in arch_type: + return ArchType.X86_64 + raise Exception(f"Unsupported arch type: {arch_type}") + + @staticmethod + def get_os_type(): + os_type = platform.system().lower() + arch_type = LibLoader.get_arch_type() + if LibLoader.MACOS_OS in os_type: + if arch_type == ArchType.ARM64: + return OSType.MACOS_ARM64 + else: + return OSType.MACOS_X64 + if LibLoader.LINUX_OS in os_type: + if arch_type == ArchType.ARM64: + return OSType.LINUX_ARM64 + else: + return OSType.LINUX_X64 + if LibLoader.WINDOWS_OS in os_type: + return OSType.WINDOWS + raise Exception(f"Unsupported os {os_type}, arch: {arch_type}") + + @staticmethod + def get_lib_name(): + os_type = LibLoader.get_os_type() + if os_type == OSType.WINDOWS: + return "{}{}.{}".format(LibLoader.LIB_PREFIX, LibLoader.TRANSPORT_LIB_NAME, LibLoader.WINDOWS_LIB_POSTFIX) + if os_type == OSType.MACOS_ARM64: + return "{}{}-arm64.{}".format(LibLoader.LIB_PREFIX, LibLoader.TRANSPORT_LIB_NAME, LibLoader.MACOS_LIB_POSTFIX) + if os_type == OSType.MACOS_X64: + return "{}{}.{}".format(LibLoader.LIB_PREFIX, LibLoader.TRANSPORT_LIB_NAME, LibLoader.MACOS_LIB_POSTFIX) + if os_type == OSType.LINUX_ARM64: + return "{}{}.{}-arm64".format(LibLoader.LIB_PREFIX, LibLoader.TRANSPORT_LIB_NAME, LibLoader.LINUX_LIB_PORSTFIX) + if os_type == OSType.LINUX_X64: + return "{}{}.{}".format(LibLoader.LIB_PREFIX, LibLoader.TRANSPORT_LIB_NAME, LibLoader.LINUX_LIB_PORSTFIX) + raise Exception( + f"get_lib_name failed for not support the os_type: {os_type}") diff --git a/cpp/wedpr-transport/sdk-wrapper/python/bindings/wedpr_python_gateway_sdk/utils/tests/test_lib_loader.py b/cpp/wedpr-transport/sdk-wrapper/python/bindings/wedpr_python_gateway_sdk/utils/tests/test_lib_loader.py new file mode 100644 index 00000000..025c6f32 --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/python/bindings/wedpr_python_gateway_sdk/utils/tests/test_lib_loader.py @@ -0,0 +1,12 @@ +# -*- coding: utf-8 -*- +import unittest +from wedpr_python_gateway_sdk.utils.lib_loader import LibLoader + + +class TestLibLoader(unittest.TestCase): + def test_load_lib(self): + LibLoader.get_lib_name() + + +if __name__ == '__main__': + unittest.main() diff --git a/cpp/wedpr-transport/sdk-wrapper/python/bindings/wedpr_python_gateway_sdk/utils/utils.py b/cpp/wedpr-transport/sdk-wrapper/python/bindings/wedpr_python_gateway_sdk/utils/utils.py new file mode 100644 index 00000000..68254eaa --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/python/bindings/wedpr_python_gateway_sdk/utils/utils.py @@ -0,0 +1,5 @@ +# -*- coding: utf-8 -*- + +def require_not_empty(field, value): + if value is None or len(value) == 0: + raise Exception(f"The field {field} must not empty!") diff --git a/cpp/wedpr-transport/sdk-wrapper/python/src/wedpr_python_transportPYTHON_wrap.cxx b/cpp/wedpr-transport/sdk-wrapper/python/src/wedpr_python_transportPYTHON_wrap.cxx new file mode 100644 index 00000000..f5b2674f --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/python/src/wedpr_python_transportPYTHON_wrap.cxx @@ -0,0 +1,30366 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (https://www.swig.org). + * Version 4.2.1 + * + * Do not make changes to this file unless you know what you are doing - modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + + +#define SWIG_VERSION 0x040201 +#define SWIGPYTHON +#define SWIG_DIRECTORS +#define SWIG_PYTHON_DIRECTOR_NO_VTABLE + +/* ----------------------------------------------------------------------------- + * This section contains generic SWIG labels for method/variable + * declarations/attributes, and other compiler dependent labels. + * ----------------------------------------------------------------------------- */ + +/* template workaround for compilers that cannot correctly implement the C++ standard */ +#ifndef SWIGTEMPLATEDISAMBIGUATOR +# if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x560) +# define SWIGTEMPLATEDISAMBIGUATOR template +# elif defined(__HP_aCC) +/* Needed even with `aCC -AA' when `aCC -V' reports HP ANSI C++ B3910B A.03.55 */ +/* If we find a maximum version that requires this, the test would be __HP_aCC <= 35500 for A.03.55 */ +# define SWIGTEMPLATEDISAMBIGUATOR template +# else +# define SWIGTEMPLATEDISAMBIGUATOR +# endif +#endif + +/* inline attribute */ +#ifndef SWIGINLINE +# if defined(__cplusplus) || (defined(__GNUC__) && !defined(__STRICT_ANSI__)) +# define SWIGINLINE inline +# else +# define SWIGINLINE +# endif +#endif + +/* attribute recognised by some compilers to avoid 'unused' warnings */ +#ifndef SWIGUNUSED +# if defined(__GNUC__) +# if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) +# define SWIGUNUSED __attribute__ ((__unused__)) +# else +# define SWIGUNUSED +# endif +# elif defined(__ICC) +# define SWIGUNUSED __attribute__ ((__unused__)) +# else +# define SWIGUNUSED +# endif +#endif + +#ifndef SWIG_MSC_UNSUPPRESS_4505 +# if defined(_MSC_VER) +# pragma warning(disable : 4505) /* unreferenced local function has been removed */ +# endif +#endif + +#ifndef SWIGUNUSEDPARM +# ifdef __cplusplus +# define SWIGUNUSEDPARM(p) +# else +# define SWIGUNUSEDPARM(p) p SWIGUNUSED +# endif +#endif + +/* internal SWIG method */ +#ifndef SWIGINTERN +# define SWIGINTERN static SWIGUNUSED +#endif + +/* internal inline SWIG method */ +#ifndef SWIGINTERNINLINE +# define SWIGINTERNINLINE SWIGINTERN SWIGINLINE +#endif + +/* exporting methods */ +#if defined(__GNUC__) +# if (__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) +# ifndef GCC_HASCLASSVISIBILITY +# define GCC_HASCLASSVISIBILITY +# endif +# endif +#endif + +#ifndef SWIGEXPORT +# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) +# if defined(STATIC_LINKED) +# define SWIGEXPORT +# else +# define SWIGEXPORT __declspec(dllexport) +# endif +# else +# if defined(__GNUC__) && defined(GCC_HASCLASSVISIBILITY) +# define SWIGEXPORT __attribute__ ((visibility("default"))) +# else +# define SWIGEXPORT +# endif +# endif +#endif + +/* calling conventions for Windows */ +#ifndef SWIGSTDCALL +# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) +# define SWIGSTDCALL __stdcall +# else +# define SWIGSTDCALL +# endif +#endif + +/* Deal with Microsoft's attempt at deprecating C standard runtime functions */ +#if !defined(SWIG_NO_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE) +# define _CRT_SECURE_NO_DEPRECATE +#endif + +/* Deal with Microsoft's attempt at deprecating methods in the standard C++ library */ +#if !defined(SWIG_NO_SCL_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_SCL_SECURE_NO_DEPRECATE) +# define _SCL_SECURE_NO_DEPRECATE +#endif + +/* Deal with Apple's deprecated 'AssertMacros.h' from Carbon-framework */ +#if defined(__APPLE__) && !defined(__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES) +# define __ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES 0 +#endif + +/* Intel's compiler complains if a variable which was never initialised is + * cast to void, which is a common idiom which we use to indicate that we + * are aware a variable isn't used. So we just silence that warning. + * See: https://github.com/swig/swig/issues/192 for more discussion. + */ +#ifdef __INTEL_COMPILER +# pragma warning disable 592 +#endif + +#if defined(__cplusplus) && __cplusplus >=201103L +# define SWIG_NULLPTR nullptr +#else +# define SWIG_NULLPTR NULL +#endif + +/* ----------------------------------------------------------------------------- + * swigcompat.swg + * + * Macros to provide support compatibility with older C and C++ standards. + * ----------------------------------------------------------------------------- */ + +/* C99 and C++11 should provide snprintf, but define SWIG_NO_SNPRINTF + * if you're missing it. + */ +#if ((defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L) || \ + (defined __cplusplus && __cplusplus >= 201103L) || \ + defined SWIG_HAVE_SNPRINTF) && \ + !defined SWIG_NO_SNPRINTF +# define SWIG_snprintf(O,S,F,A) snprintf(O,S,F,A) +# define SWIG_snprintf2(O,S,F,A,B) snprintf(O,S,F,A,B) +#else +/* Fallback versions ignore the buffer size, but most of our uses either have a + * fixed maximum possible size or dynamically allocate a buffer that's large + * enough. + */ +# define SWIG_snprintf(O,S,F,A) sprintf(O,F,A) +# define SWIG_snprintf2(O,S,F,A,B) sprintf(O,F,A,B) +#endif + + +#if defined(__GNUC__) && defined(_WIN32) && !defined(SWIG_PYTHON_NO_HYPOT_WORKAROUND) +/* Workaround for '::hypot' has not been declared', see https://bugs.python.org/issue11566 */ +# include +#endif + +#if !defined(PY_SSIZE_T_CLEAN) && !defined(SWIG_NO_PY_SSIZE_T_CLEAN) +#define PY_SSIZE_T_CLEAN +#endif + +#if __GNUC__ >= 7 +#pragma GCC diagnostic push +#if defined(__cplusplus) && __cplusplus >=201703L +#pragma GCC diagnostic ignored "-Wregister" /* For python-2.7 headers that use register */ +#endif +#endif + +#if defined(_DEBUG) && defined(SWIG_PYTHON_INTERPRETER_NO_DEBUG) +/* Use debug wrappers with the Python release dll */ + +#if defined(_MSC_VER) && _MSC_VER >= 1929 +/* Workaround compilation errors when redefining _DEBUG in MSVC 2019 version 16.10 and later + * See https://github.com/swig/swig/issues/2090 */ +# include +#endif + +# undef _DEBUG +# include +# define _DEBUG 1 +#else +# include +#endif + +#if __GNUC__ >= 7 +#pragma GCC diagnostic pop +#endif + +#include + +/* ----------------------------------------------------------------------------- + * swigrun.swg + * + * This file contains generic C API SWIG runtime support for pointer + * type checking. + * ----------------------------------------------------------------------------- */ + +/* This should only be incremented when either the layout of swig_type_info changes, + or for whatever reason, the runtime changes incompatibly */ +#define SWIG_RUNTIME_VERSION "4" + +/* define SWIG_TYPE_TABLE_NAME as "SWIG_TYPE_TABLE" */ +#ifdef SWIG_TYPE_TABLE +# define SWIG_QUOTE_STRING(x) #x +# define SWIG_EXPAND_AND_QUOTE_STRING(x) SWIG_QUOTE_STRING(x) +# define SWIG_TYPE_TABLE_NAME SWIG_EXPAND_AND_QUOTE_STRING(SWIG_TYPE_TABLE) +#else +# define SWIG_TYPE_TABLE_NAME +#endif + +/* + You can use the SWIGRUNTIME and SWIGRUNTIMEINLINE macros for + creating a static or dynamic library from the SWIG runtime code. + In 99.9% of the cases, SWIG just needs to declare them as 'static'. + + But only do this if strictly necessary, ie, if you have problems + with your compiler or suchlike. +*/ + +#ifndef SWIGRUNTIME +# define SWIGRUNTIME SWIGINTERN +#endif + +#ifndef SWIGRUNTIMEINLINE +# define SWIGRUNTIMEINLINE SWIGRUNTIME SWIGINLINE +#endif + +/* Generic buffer size */ +#ifndef SWIG_BUFFER_SIZE +# define SWIG_BUFFER_SIZE 1024 +#endif + +/* Flags for pointer conversions */ +#define SWIG_POINTER_DISOWN 0x1 +#define SWIG_CAST_NEW_MEMORY 0x2 +#define SWIG_POINTER_NO_NULL 0x4 +#define SWIG_POINTER_CLEAR 0x8 +#define SWIG_POINTER_RELEASE (SWIG_POINTER_CLEAR | SWIG_POINTER_DISOWN) + +/* Flags for new pointer objects */ +#define SWIG_POINTER_OWN 0x1 + + +/* + Flags/methods for returning states. + + The SWIG conversion methods, as ConvertPtr, return an integer + that tells if the conversion was successful or not. And if not, + an error code can be returned (see swigerrors.swg for the codes). + + Use the following macros/flags to set or process the returning + states. + + In old versions of SWIG, code such as the following was usually written: + + if (SWIG_ConvertPtr(obj,vptr,ty.flags) != -1) { + // success code + } else { + //fail code + } + + Now you can be more explicit: + + int res = SWIG_ConvertPtr(obj,vptr,ty.flags); + if (SWIG_IsOK(res)) { + // success code + } else { + // fail code + } + + which is the same really, but now you can also do + + Type *ptr; + int res = SWIG_ConvertPtr(obj,(void **)(&ptr),ty.flags); + if (SWIG_IsOK(res)) { + // success code + if (SWIG_IsNewObj(res) { + ... + delete *ptr; + } else { + ... + } + } else { + // fail code + } + + I.e., now SWIG_ConvertPtr can return new objects and you can + identify the case and take care of the deallocation. Of course that + also requires SWIG_ConvertPtr to return new result values, such as + + int SWIG_ConvertPtr(obj, ptr,...) { + if () { + if () { + *ptr = ; + return SWIG_NEWOBJ; + } else { + *ptr = ; + return SWIG_OLDOBJ; + } + } else { + return SWIG_BADOBJ; + } + } + + Of course, returning the plain '0(success)/-1(fail)' still works, but you can be + more explicit by returning SWIG_BADOBJ, SWIG_ERROR or any of the + SWIG errors code. + + Finally, if the SWIG_CASTRANK_MODE is enabled, the result code + allows returning the 'cast rank', for example, if you have this + + int food(double) + int fooi(int); + + and you call + + food(1) // cast rank '1' (1 -> 1.0) + fooi(1) // cast rank '0' + + just use the SWIG_AddCast()/SWIG_CheckState() +*/ + +#define SWIG_OK (0) +/* Runtime errors are < 0 */ +#define SWIG_ERROR (-1) +/* Errors in range -1 to -99 are in swigerrors.swg (errors for all languages including those not using the runtime) */ +/* Errors in range -100 to -199 are language specific errors defined in *errors.swg */ +/* Errors < -200 are generic runtime specific errors */ +#define SWIG_ERROR_RELEASE_NOT_OWNED (-200) + +#define SWIG_IsOK(r) (r >= 0) +#define SWIG_ArgError(r) ((r != SWIG_ERROR) ? r : SWIG_TypeError) + +/* The CastRankLimit says how many bits are used for the cast rank */ +#define SWIG_CASTRANKLIMIT (1 << 8) +/* The NewMask denotes the object was created (using new/malloc) */ +#define SWIG_NEWOBJMASK (SWIG_CASTRANKLIMIT << 1) +/* The TmpMask is for in/out typemaps that use temporary objects */ +#define SWIG_TMPOBJMASK (SWIG_NEWOBJMASK << 1) +/* Simple returning values */ +#define SWIG_BADOBJ (SWIG_ERROR) +#define SWIG_OLDOBJ (SWIG_OK) +#define SWIG_NEWOBJ (SWIG_OK | SWIG_NEWOBJMASK) +#define SWIG_TMPOBJ (SWIG_OK | SWIG_TMPOBJMASK) +/* Check, add and del object mask methods */ +#define SWIG_AddNewMask(r) (SWIG_IsOK(r) ? (r | SWIG_NEWOBJMASK) : r) +#define SWIG_DelNewMask(r) (SWIG_IsOK(r) ? (r & ~SWIG_NEWOBJMASK) : r) +#define SWIG_IsNewObj(r) (SWIG_IsOK(r) && (r & SWIG_NEWOBJMASK)) +#define SWIG_AddTmpMask(r) (SWIG_IsOK(r) ? (r | SWIG_TMPOBJMASK) : r) +#define SWIG_DelTmpMask(r) (SWIG_IsOK(r) ? (r & ~SWIG_TMPOBJMASK) : r) +#define SWIG_IsTmpObj(r) (SWIG_IsOK(r) && (r & SWIG_TMPOBJMASK)) + +/* Cast-Rank Mode */ +#if defined(SWIG_CASTRANK_MODE) +# ifndef SWIG_TypeRank +# define SWIG_TypeRank unsigned long +# endif +# ifndef SWIG_MAXCASTRANK /* Default cast allowed */ +# define SWIG_MAXCASTRANK (2) +# endif +# define SWIG_CASTRANKMASK ((SWIG_CASTRANKLIMIT) -1) +# define SWIG_CastRank(r) (r & SWIG_CASTRANKMASK) +SWIGINTERNINLINE int SWIG_AddCast(int r) { + return SWIG_IsOK(r) ? ((SWIG_CastRank(r) < SWIG_MAXCASTRANK) ? (r + 1) : SWIG_ERROR) : r; +} +SWIGINTERNINLINE int SWIG_CheckState(int r) { + return SWIG_IsOK(r) ? SWIG_CastRank(r) + 1 : 0; +} +#else /* no cast-rank mode */ +# define SWIG_AddCast(r) (r) +# define SWIG_CheckState(r) (SWIG_IsOK(r) ? 1 : 0) +#endif + + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void *(*swig_converter_func)(void *, int *); +typedef struct swig_type_info *(*swig_dycast_func)(void **); + +/* Structure to store information on one type */ +typedef struct swig_type_info { + const char *name; /* mangled name of this type */ + const char *str; /* human readable name of this type */ + swig_dycast_func dcast; /* dynamic cast function down a hierarchy */ + struct swig_cast_info *cast; /* linked list of types that can cast into this type */ + void *clientdata; /* language specific type data */ + int owndata; /* flag if the structure owns the clientdata */ +} swig_type_info; + +/* Structure to store a type and conversion function used for casting */ +typedef struct swig_cast_info { + swig_type_info *type; /* pointer to type that is equivalent to this type */ + swig_converter_func converter; /* function to cast the void pointers */ + struct swig_cast_info *next; /* pointer to next cast in linked list */ + struct swig_cast_info *prev; /* pointer to the previous cast */ +} swig_cast_info; + +/* Structure used to store module information + * Each module generates one structure like this, and the runtime collects + * all of these structures and stores them in a circularly linked list.*/ +typedef struct swig_module_info { + swig_type_info **types; /* Array of pointers to swig_type_info structures that are in this module */ + size_t size; /* Number of types in this module */ + struct swig_module_info *next; /* Pointer to next element in circularly linked list */ + swig_type_info **type_initial; /* Array of initially generated type structures */ + swig_cast_info **cast_initial; /* Array of initially generated casting structures */ + void *clientdata; /* Language specific module data */ +} swig_module_info; + +/* + Compare two type names skipping the space characters, therefore + "char*" == "char *" and "Class" == "Class", etc. + + Return 0 when the two name types are equivalent, as in + strncmp, but skipping ' '. +*/ +SWIGRUNTIME int +SWIG_TypeNameComp(const char *f1, const char *l1, + const char *f2, const char *l2) { + for (;(f1 != l1) && (f2 != l2); ++f1, ++f2) { + while ((*f1 == ' ') && (f1 != l1)) ++f1; + while ((*f2 == ' ') && (f2 != l2)) ++f2; + if (*f1 != *f2) return (*f1 > *f2) ? 1 : -1; + } + return (int)((l1 - f1) - (l2 - f2)); +} + +/* + Check type equivalence in a name list like ||... + Return 0 if equal, -1 if nb < tb, 1 if nb > tb +*/ +SWIGRUNTIME int +SWIG_TypeCmp(const char *nb, const char *tb) { + int equiv = 1; + const char* te = tb + strlen(tb); + const char* ne = nb; + while (equiv != 0 && *ne) { + for (nb = ne; *ne; ++ne) { + if (*ne == '|') break; + } + equiv = SWIG_TypeNameComp(nb, ne, tb, te); + if (*ne) ++ne; + } + return equiv; +} + +/* + Check type equivalence in a name list like ||... + Return 0 if not equal, 1 if equal +*/ +SWIGRUNTIME int +SWIG_TypeEquiv(const char *nb, const char *tb) { + return SWIG_TypeCmp(nb, tb) == 0 ? 1 : 0; +} + +/* + Check the typename +*/ +SWIGRUNTIME swig_cast_info * +SWIG_TypeCheck(const char *c, swig_type_info *ty) { + if (ty) { + swig_cast_info *iter = ty->cast; + while (iter) { + if (strcmp(iter->type->name, c) == 0) { + if (iter == ty->cast) + return iter; + /* Move iter to the top of the linked list */ + iter->prev->next = iter->next; + if (iter->next) + iter->next->prev = iter->prev; + iter->next = ty->cast; + iter->prev = 0; + if (ty->cast) ty->cast->prev = iter; + ty->cast = iter; + return iter; + } + iter = iter->next; + } + } + return 0; +} + +/* + Identical to SWIG_TypeCheck, except strcmp is replaced with a pointer comparison +*/ +SWIGRUNTIME swig_cast_info * +SWIG_TypeCheckStruct(const swig_type_info *from, swig_type_info *ty) { + if (ty) { + swig_cast_info *iter = ty->cast; + while (iter) { + if (iter->type == from) { + if (iter == ty->cast) + return iter; + /* Move iter to the top of the linked list */ + iter->prev->next = iter->next; + if (iter->next) + iter->next->prev = iter->prev; + iter->next = ty->cast; + iter->prev = 0; + if (ty->cast) ty->cast->prev = iter; + ty->cast = iter; + return iter; + } + iter = iter->next; + } + } + return 0; +} + +/* + Cast a pointer up an inheritance hierarchy +*/ +SWIGRUNTIMEINLINE void * +SWIG_TypeCast(swig_cast_info *ty, void *ptr, int *newmemory) { + return ((!ty) || (!ty->converter)) ? ptr : (*ty->converter)(ptr, newmemory); +} + +/* + Dynamic pointer casting. Down an inheritance hierarchy +*/ +SWIGRUNTIME swig_type_info * +SWIG_TypeDynamicCast(swig_type_info *ty, void **ptr) { + swig_type_info *lastty = ty; + if (!ty || !ty->dcast) return ty; + while (ty && (ty->dcast)) { + ty = (*ty->dcast)(ptr); + if (ty) lastty = ty; + } + return lastty; +} + +/* + Return the name associated with this type +*/ +SWIGRUNTIMEINLINE const char * +SWIG_TypeName(const swig_type_info *ty) { + return ty->name; +} + +/* + Return the pretty name associated with this type, + that is an unmangled type name in a form presentable to the user. +*/ +SWIGRUNTIME const char * +SWIG_TypePrettyName(const swig_type_info *type) { + /* The "str" field contains the equivalent pretty names of the + type, separated by vertical-bar characters. Choose the last + name. It should be the most specific; a fully resolved name + but not necessarily with default template parameters expanded. */ + if (!type) return NULL; + if (type->str != NULL) { + const char *last_name = type->str; + const char *s; + for (s = type->str; *s; s++) + if (*s == '|') last_name = s+1; + return last_name; + } + else + return type->name; +} + +/* + Set the clientdata field for a type +*/ +SWIGRUNTIME void +SWIG_TypeClientData(swig_type_info *ti, void *clientdata) { + swig_cast_info *cast = ti->cast; + /* if (ti->clientdata == clientdata) return; */ + ti->clientdata = clientdata; + + while (cast) { + if (!cast->converter) { + swig_type_info *tc = cast->type; + if (!tc->clientdata) { + SWIG_TypeClientData(tc, clientdata); + } + } + cast = cast->next; + } +} +SWIGRUNTIME void +SWIG_TypeNewClientData(swig_type_info *ti, void *clientdata) { + SWIG_TypeClientData(ti, clientdata); + ti->owndata = 1; +} + +/* + Search for a swig_type_info structure only by mangled name + Search is a O(log #types) + + We start searching at module start, and finish searching when start == end. + Note: if start == end at the beginning of the function, we go all the way around + the circular list. +*/ +SWIGRUNTIME swig_type_info * +SWIG_MangledTypeQueryModule(swig_module_info *start, + swig_module_info *end, + const char *name) { + swig_module_info *iter = start; + do { + if (iter->size) { + size_t l = 0; + size_t r = iter->size - 1; + do { + /* since l+r >= 0, we can (>> 1) instead (/ 2) */ + size_t i = (l + r) >> 1; + const char *iname = iter->types[i]->name; + if (iname) { + int compare = strcmp(name, iname); + if (compare == 0) { + return iter->types[i]; + } else if (compare < 0) { + if (i) { + r = i - 1; + } else { + break; + } + } else if (compare > 0) { + l = i + 1; + } + } else { + break; /* should never happen */ + } + } while (l <= r); + } + iter = iter->next; + } while (iter != end); + return 0; +} + +/* + Search for a swig_type_info structure for either a mangled name or a human readable name. + It first searches the mangled names of the types, which is a O(log #types) + If a type is not found it then searches the human readable names, which is O(#types). + + We start searching at module start, and finish searching when start == end. + Note: if start == end at the beginning of the function, we go all the way around + the circular list. +*/ +SWIGRUNTIME swig_type_info * +SWIG_TypeQueryModule(swig_module_info *start, + swig_module_info *end, + const char *name) { + /* STEP 1: Search the name field using binary search */ + swig_type_info *ret = SWIG_MangledTypeQueryModule(start, end, name); + if (ret) { + return ret; + } else { + /* STEP 2: If the type hasn't been found, do a complete search + of the str field (the human readable name) */ + swig_module_info *iter = start; + do { + size_t i = 0; + for (; i < iter->size; ++i) { + if (iter->types[i]->str && (SWIG_TypeEquiv(iter->types[i]->str, name))) + return iter->types[i]; + } + iter = iter->next; + } while (iter != end); + } + + /* neither found a match */ + return 0; +} + +/* + Pack binary data into a string +*/ +SWIGRUNTIME char * +SWIG_PackData(char *c, void *ptr, size_t sz) { + static const char hex[17] = "0123456789abcdef"; + const unsigned char *u = (unsigned char *) ptr; + const unsigned char *eu = u + sz; + for (; u != eu; ++u) { + unsigned char uu = *u; + *(c++) = hex[(uu & 0xf0) >> 4]; + *(c++) = hex[uu & 0xf]; + } + return c; +} + +/* + Unpack binary data from a string +*/ +SWIGRUNTIME const char * +SWIG_UnpackData(const char *c, void *ptr, size_t sz) { + unsigned char *u = (unsigned char *) ptr; + const unsigned char *eu = u + sz; + for (; u != eu; ++u) { + char d = *(c++); + unsigned char uu; + if ((d >= '0') && (d <= '9')) + uu = (unsigned char)((d - '0') << 4); + else if ((d >= 'a') && (d <= 'f')) + uu = (unsigned char)((d - ('a'-10)) << 4); + else + return (char *) 0; + d = *(c++); + if ((d >= '0') && (d <= '9')) + uu |= (unsigned char)(d - '0'); + else if ((d >= 'a') && (d <= 'f')) + uu |= (unsigned char)(d - ('a'-10)); + else + return (char *) 0; + *u = uu; + } + return c; +} + +/* + Pack 'void *' into a string buffer. +*/ +SWIGRUNTIME char * +SWIG_PackVoidPtr(char *buff, void *ptr, const char *name, size_t bsz) { + char *r = buff; + if ((2*sizeof(void *) + 2) > bsz) return 0; + *(r++) = '_'; + r = SWIG_PackData(r,&ptr,sizeof(void *)); + if (strlen(name) + 1 > (bsz - (r - buff))) return 0; + strcpy(r,name); + return buff; +} + +SWIGRUNTIME const char * +SWIG_UnpackVoidPtr(const char *c, void **ptr, const char *name) { + if (*c != '_') { + if (strcmp(c,"NULL") == 0) { + *ptr = (void *) 0; + return name; + } else { + return 0; + } + } + return SWIG_UnpackData(++c,ptr,sizeof(void *)); +} + +SWIGRUNTIME char * +SWIG_PackDataName(char *buff, void *ptr, size_t sz, const char *name, size_t bsz) { + char *r = buff; + size_t lname = (name ? strlen(name) : 0); + if ((2*sz + 2 + lname) > bsz) return 0; + *(r++) = '_'; + r = SWIG_PackData(r,ptr,sz); + if (lname) { + strncpy(r,name,lname+1); + } else { + *r = 0; + } + return buff; +} + +SWIGRUNTIME const char * +SWIG_UnpackDataName(const char *c, void *ptr, size_t sz, const char *name) { + if (*c != '_') { + if (strcmp(c,"NULL") == 0) { + memset(ptr,0,sz); + return name; + } else { + return 0; + } + } + return SWIG_UnpackData(++c,ptr,sz); +} + +#ifdef __cplusplus +} +#endif + +/* SWIG Errors applicable to all language modules, values are reserved from -1 to -99 */ +#define SWIG_UnknownError -1 +#define SWIG_IOError -2 +#define SWIG_RuntimeError -3 +#define SWIG_IndexError -4 +#define SWIG_TypeError -5 +#define SWIG_DivisionByZero -6 +#define SWIG_OverflowError -7 +#define SWIG_SyntaxError -8 +#define SWIG_ValueError -9 +#define SWIG_SystemError -10 +#define SWIG_AttributeError -11 +#define SWIG_MemoryError -12 +#define SWIG_NullReferenceError -13 + + +/* Compatibility macros for Python 3 */ +#if PY_VERSION_HEX >= 0x03000000 + +#define PyClass_Check(obj) PyObject_IsInstance(obj, (PyObject *)&PyType_Type) +#define PyInt_Check(x) PyLong_Check(x) +#define PyInt_AsLong(x) PyLong_AsLong(x) +#define PyInt_FromLong(x) PyLong_FromLong(x) +#define PyInt_FromSize_t(x) PyLong_FromSize_t(x) +#define PyString_Check(name) PyBytes_Check(name) +#define PyString_FromString(x) PyUnicode_FromString(x) +#define PyString_Format(fmt, args) PyUnicode_Format(fmt, args) +#define PyString_AsString(str) PyBytes_AsString(str) +#define PyString_Size(str) PyBytes_Size(str) +#define PyString_InternFromString(key) PyUnicode_InternFromString(key) +#define Py_TPFLAGS_HAVE_CLASS Py_TPFLAGS_BASETYPE +#define _PyLong_FromSsize_t(x) PyLong_FromSsize_t(x) + +#endif + +#ifndef Py_TYPE +# define Py_TYPE(op) ((op)->ob_type) +#endif + +/* SWIG APIs for compatibility of both Python 2 & 3 */ + +#if PY_VERSION_HEX >= 0x03000000 +# define SWIG_Python_str_FromFormat PyUnicode_FromFormat +#else +# define SWIG_Python_str_FromFormat PyString_FromFormat +#endif + + +/* Wrapper around PyUnicode_AsUTF8AndSize - call Py_XDECREF on the returned pbytes when finished with the returned string */ +SWIGINTERN const char * +SWIG_PyUnicode_AsUTF8AndSize(PyObject *str, Py_ssize_t *psize, PyObject **pbytes) +{ +#if PY_VERSION_HEX >= 0x03030000 +# if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x030A0000 + *pbytes = NULL; + return PyUnicode_AsUTF8AndSize(str, psize); +# else + *pbytes = PyUnicode_AsUTF8String(str); + const char *chars = *pbytes ? PyBytes_AsString(*pbytes) : NULL; + if (chars && psize) + *psize = PyBytes_Size(*pbytes); + return chars; +# endif +#else + char *chars = NULL; + *pbytes = NULL; + PyString_AsStringAndSize(str, &chars, psize); + return chars; +#endif +} + +SWIGINTERN PyObject* +SWIG_Python_str_FromChar(const char *c) +{ +#if PY_VERSION_HEX >= 0x03000000 + return PyUnicode_FromString(c); +#else + return PyString_FromString(c); +#endif +} + +#ifndef PyObject_DEL +# define PyObject_DEL PyObject_Del +#endif + +/* SWIGPY_USE_CAPSULE is no longer used within SWIG itself, but some user interface files check for it. */ +# define SWIGPY_USE_CAPSULE +#ifdef SWIGPYTHON_BUILTIN +# define SWIGPY_CAPSULE_ATTR_NAME "type_pointer_capsule_builtin" SWIG_TYPE_TABLE_NAME +#else +# define SWIGPY_CAPSULE_ATTR_NAME "type_pointer_capsule" SWIG_TYPE_TABLE_NAME +#endif +# define SWIGPY_CAPSULE_NAME ("swig_runtime_data" SWIG_RUNTIME_VERSION "." SWIGPY_CAPSULE_ATTR_NAME) + +#if PY_VERSION_HEX < 0x03020000 +#define PyDescr_TYPE(x) (((PyDescrObject *)(x))->d_type) +#define PyDescr_NAME(x) (((PyDescrObject *)(x))->d_name) +#define Py_hash_t long +#endif + +#ifdef Py_LIMITED_API +# define PyTuple_GET_ITEM PyTuple_GetItem +/* Note that PyTuple_SetItem() has different semantics from PyTuple_SET_ITEM as it decref's the original tuple item, so in general they cannot be used + interchangeably. However in SWIG-generated code PyTuple_SET_ITEM is only used with newly initialized tuples without any items and for them this does work. */ +# define PyTuple_SET_ITEM PyTuple_SetItem +# define PyTuple_GET_SIZE PyTuple_Size +# define PyCFunction_GET_FLAGS PyCFunction_GetFlags +# define PyCFunction_GET_FUNCTION PyCFunction_GetFunction +# define PyCFunction_GET_SELF PyCFunction_GetSelf +# define PyList_GET_ITEM PyList_GetItem +# define PyList_SET_ITEM PyList_SetItem +# define PySliceObject PyObject +#endif + +/* ----------------------------------------------------------------------------- + * error manipulation + * ----------------------------------------------------------------------------- */ + +SWIGRUNTIME PyObject* +SWIG_Python_ErrorType(int code) { + PyObject* type = 0; + switch(code) { + case SWIG_MemoryError: + type = PyExc_MemoryError; + break; + case SWIG_IOError: + type = PyExc_IOError; + break; + case SWIG_RuntimeError: + type = PyExc_RuntimeError; + break; + case SWIG_IndexError: + type = PyExc_IndexError; + break; + case SWIG_TypeError: + type = PyExc_TypeError; + break; + case SWIG_DivisionByZero: + type = PyExc_ZeroDivisionError; + break; + case SWIG_OverflowError: + type = PyExc_OverflowError; + break; + case SWIG_SyntaxError: + type = PyExc_SyntaxError; + break; + case SWIG_ValueError: + type = PyExc_ValueError; + break; + case SWIG_SystemError: + type = PyExc_SystemError; + break; + case SWIG_AttributeError: + type = PyExc_AttributeError; + break; + default: + type = PyExc_RuntimeError; + } + return type; +} + + +SWIGRUNTIME void +SWIG_Python_AddErrorMsg(const char* mesg) +{ + PyObject *type = 0; + PyObject *value = 0; + PyObject *traceback = 0; + + if (PyErr_Occurred()) + PyErr_Fetch(&type, &value, &traceback); + if (value) { + PyObject *old_str = PyObject_Str(value); + PyObject *bytes = NULL; + const char *tmp = SWIG_PyUnicode_AsUTF8AndSize(old_str, NULL, &bytes); + PyErr_Clear(); + Py_XINCREF(type); + if (tmp) + PyErr_Format(type, "%s %s", tmp, mesg); + else + PyErr_Format(type, "%s", mesg); + Py_XDECREF(bytes); + Py_DECREF(old_str); + Py_DECREF(value); + } else { + PyErr_SetString(PyExc_RuntimeError, mesg); + } +} + +SWIGRUNTIME int +SWIG_Python_TypeErrorOccurred(PyObject *obj) +{ + PyObject *error; + if (obj) + return 0; + error = PyErr_Occurred(); + return error && PyErr_GivenExceptionMatches(error, PyExc_TypeError); +} + +SWIGRUNTIME void +SWIG_Python_RaiseOrModifyTypeError(const char *message) +{ + if (SWIG_Python_TypeErrorOccurred(NULL)) { + /* Use existing TypeError to preserve stacktrace and enhance with given message */ + PyObject *newvalue; + PyObject *type = NULL, *value = NULL, *traceback = NULL; + PyErr_Fetch(&type, &value, &traceback); +#if PY_VERSION_HEX >= 0x03000000 + newvalue = PyUnicode_FromFormat("%S\nAdditional information:\n%s", value, message); +#else + newvalue = PyString_FromFormat("%s\nAdditional information:\n%s", PyString_AsString(value), message); +#endif + if (newvalue) { + Py_XDECREF(value); + PyErr_Restore(type, newvalue, traceback); + } else { + PyErr_Restore(type, value, traceback); + } + } else { + /* Raise TypeError using given message */ + PyErr_SetString(PyExc_TypeError, message); + } +} + +#if defined(SWIG_PYTHON_NO_THREADS) +# if defined(SWIG_PYTHON_THREADS) +# undef SWIG_PYTHON_THREADS +# endif +#endif +#if defined(SWIG_PYTHON_THREADS) /* Threading support is enabled */ +# if !defined(SWIG_PYTHON_USE_GIL) && !defined(SWIG_PYTHON_NO_USE_GIL) +# define SWIG_PYTHON_USE_GIL +# endif +# if defined(SWIG_PYTHON_USE_GIL) /* Use PyGILState threads calls */ +# if !defined(SWIG_PYTHON_INITIALIZE_THREADS) +# if PY_VERSION_HEX < 0x03070000 +# define SWIG_PYTHON_INITIALIZE_THREADS PyEval_InitThreads() +# else +# define SWIG_PYTHON_INITIALIZE_THREADS +# endif +# endif +# ifdef __cplusplus /* C++ code */ + class SWIG_Python_Thread_Block { + bool status; + PyGILState_STATE state; + public: + void end() { if (status) { PyGILState_Release(state); status = false;} } + SWIG_Python_Thread_Block() : status(true), state(PyGILState_Ensure()) {} + ~SWIG_Python_Thread_Block() { end(); } + }; + class SWIG_Python_Thread_Allow { + bool status; + PyThreadState *save; + public: + void end() { if (status) { status = false; PyEval_RestoreThread(save); }} + SWIG_Python_Thread_Allow() : status(true), save(PyEval_SaveThread()) {} + ~SWIG_Python_Thread_Allow() { end(); } + }; +# define SWIG_PYTHON_THREAD_BEGIN_BLOCK SWIG_Python_Thread_Block _swig_thread_block +# define SWIG_PYTHON_THREAD_END_BLOCK _swig_thread_block.end() +# define SWIG_PYTHON_THREAD_BEGIN_ALLOW SWIG_Python_Thread_Allow _swig_thread_allow +# define SWIG_PYTHON_THREAD_END_ALLOW _swig_thread_allow.end() +# else /* C code */ +# define SWIG_PYTHON_THREAD_BEGIN_BLOCK PyGILState_STATE _swig_thread_block = PyGILState_Ensure() +# define SWIG_PYTHON_THREAD_END_BLOCK PyGILState_Release(_swig_thread_block) +# define SWIG_PYTHON_THREAD_BEGIN_ALLOW PyThreadState *_swig_thread_allow = PyEval_SaveThread() +# define SWIG_PYTHON_THREAD_END_ALLOW PyEval_RestoreThread(_swig_thread_allow) +# endif +# else /* Old thread way, not implemented, user must provide it */ +# if !defined(SWIG_PYTHON_INITIALIZE_THREADS) +# define SWIG_PYTHON_INITIALIZE_THREADS +# endif +# if !defined(SWIG_PYTHON_THREAD_BEGIN_BLOCK) +# define SWIG_PYTHON_THREAD_BEGIN_BLOCK +# endif +# if !defined(SWIG_PYTHON_THREAD_END_BLOCK) +# define SWIG_PYTHON_THREAD_END_BLOCK +# endif +# if !defined(SWIG_PYTHON_THREAD_BEGIN_ALLOW) +# define SWIG_PYTHON_THREAD_BEGIN_ALLOW +# endif +# if !defined(SWIG_PYTHON_THREAD_END_ALLOW) +# define SWIG_PYTHON_THREAD_END_ALLOW +# endif +# endif +#else /* No thread support */ +# define SWIG_PYTHON_INITIALIZE_THREADS +# define SWIG_PYTHON_THREAD_BEGIN_BLOCK +# define SWIG_PYTHON_THREAD_END_BLOCK +# define SWIG_PYTHON_THREAD_BEGIN_ALLOW +# define SWIG_PYTHON_THREAD_END_ALLOW +#endif + +/* ----------------------------------------------------------------------------- + * Python API portion that goes into the runtime + * ----------------------------------------------------------------------------- */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* ----------------------------------------------------------------------------- + * Constant declarations + * ----------------------------------------------------------------------------- */ + +/* Constant Types */ +#define SWIG_PY_POINTER 4 +#define SWIG_PY_BINARY 5 + +/* Constant information structure */ +typedef struct swig_const_info { + int type; + const char *name; + long lvalue; + double dvalue; + void *pvalue; + swig_type_info **ptype; +} swig_const_info; + +#ifdef __cplusplus +} +#endif + + +/* ----------------------------------------------------------------------------- + * pyrun.swg + * + * This file contains the runtime support for Python modules + * and includes code for managing global variables and pointer + * type checking. + * + * ----------------------------------------------------------------------------- */ + +#if PY_VERSION_HEX < 0x02070000 /* 2.7.0 */ +# error "This version of SWIG only supports Python >= 2.7" +#endif + +#if PY_VERSION_HEX >= 0x03000000 && PY_VERSION_HEX < 0x03030000 +# error "This version of SWIG only supports Python 3 >= 3.3" +#endif + +/* Common SWIG API */ + +/* for raw pointers */ +#define SWIG_Python_ConvertPtr(obj, pptr, type, flags) SWIG_Python_ConvertPtrAndOwn(obj, pptr, type, flags, 0) +#define SWIG_ConvertPtr(obj, pptr, type, flags) SWIG_Python_ConvertPtr(obj, pptr, type, flags) +#define SWIG_ConvertPtrAndOwn(obj,pptr,type,flags,own) SWIG_Python_ConvertPtrAndOwn(obj, pptr, type, flags, own) + +#ifdef SWIGPYTHON_BUILTIN +#define SWIG_NewPointerObj(ptr, type, flags) SWIG_Python_NewPointerObj(self, ptr, type, flags) +#else +#define SWIG_NewPointerObj(ptr, type, flags) SWIG_Python_NewPointerObj(NULL, ptr, type, flags) +#endif + +#define SWIG_InternalNewPointerObj(ptr, type, flags) SWIG_Python_NewPointerObj(NULL, ptr, type, flags) + +#define SWIG_CheckImplicit(ty) SWIG_Python_CheckImplicit(ty) +#define SWIG_AcquirePtr(ptr, src) SWIG_Python_AcquirePtr(ptr, src) +#define swig_owntype int + +/* for raw packed data */ +#define SWIG_ConvertPacked(obj, ptr, sz, ty) SWIG_Python_ConvertPacked(obj, ptr, sz, ty) +#define SWIG_NewPackedObj(ptr, sz, type) SWIG_Python_NewPackedObj(ptr, sz, type) + +/* for class or struct pointers */ +#define SWIG_ConvertInstance(obj, pptr, type, flags) SWIG_ConvertPtr(obj, pptr, type, flags) +#define SWIG_NewInstanceObj(ptr, type, flags) SWIG_NewPointerObj(ptr, type, flags) + +/* for C or C++ function pointers */ +#define SWIG_ConvertFunctionPtr(obj, pptr, type) SWIG_Python_ConvertFunctionPtr(obj, pptr, type) +#define SWIG_NewFunctionPtrObj(ptr, type) SWIG_Python_NewPointerObj(NULL, ptr, type, 0) + +/* for C++ member pointers, ie, member methods */ +#define SWIG_ConvertMember(obj, ptr, sz, ty) SWIG_Python_ConvertPacked(obj, ptr, sz, ty) +#define SWIG_NewMemberObj(ptr, sz, type) SWIG_Python_NewPackedObj(ptr, sz, type) + + +/* Runtime API */ + +#define SWIG_GetModule(clientdata) SWIG_Python_GetModule(clientdata) +#define SWIG_SetModule(clientdata, pointer) SWIG_Python_SetModule(pointer) +#define SWIG_NewClientData(obj) SwigPyClientData_New(obj) + +#define SWIG_SetErrorObj SWIG_Python_SetErrorObj +#define SWIG_SetErrorMsg SWIG_Python_SetErrorMsg +#define SWIG_ErrorType(code) SWIG_Python_ErrorType(code) +#define SWIG_Error(code, msg) SWIG_Python_SetErrorMsg(SWIG_ErrorType(code), msg) +#define SWIG_fail goto fail + + +/* Runtime API implementation */ + +/* Error manipulation */ + +SWIGINTERN void +SWIG_Python_SetErrorObj(PyObject *errtype, PyObject *obj) { + SWIG_PYTHON_THREAD_BEGIN_BLOCK; + PyErr_SetObject(errtype, obj); + Py_DECREF(obj); + SWIG_PYTHON_THREAD_END_BLOCK; +} + +SWIGINTERN void +SWIG_Python_SetErrorMsg(PyObject *errtype, const char *msg) { + SWIG_PYTHON_THREAD_BEGIN_BLOCK; + PyErr_SetString(errtype, msg); + SWIG_PYTHON_THREAD_END_BLOCK; +} + +#define SWIG_Python_Raise(obj, type, desc) SWIG_Python_SetErrorObj(SWIG_Python_ExceptionType(desc), obj) + +/* Set a constant value */ + +#if defined(SWIGPYTHON_BUILTIN) + +SWIGINTERN void +SwigPyBuiltin_AddPublicSymbol(PyObject *seq, const char *key) { + PyObject *s = PyString_InternFromString(key); + PyList_Append(seq, s); + Py_DECREF(s); +} + +SWIGINTERN void +SWIG_Python_SetConstant(PyObject *d, PyObject *public_interface, const char *name, PyObject *obj) { + PyDict_SetItemString(d, name, obj); + Py_DECREF(obj); + if (public_interface) + SwigPyBuiltin_AddPublicSymbol(public_interface, name); +} + +#else + +SWIGINTERN void +SWIG_Python_SetConstant(PyObject *d, const char *name, PyObject *obj) { + PyDict_SetItemString(d, name, obj); + Py_DECREF(obj); +} + +#endif + +/* Append a value to the result obj */ + +SWIGINTERN PyObject* +SWIG_Python_AppendOutput(PyObject* result, PyObject* obj) { + if (!result) { + result = obj; + } else if (result == Py_None) { + Py_DECREF(result); + result = obj; + } else { + if (!PyList_Check(result)) { + PyObject *o2 = result; + result = PyList_New(1); + if (result) { + PyList_SET_ITEM(result, 0, o2); + } else { + Py_DECREF(obj); + return o2; + } + } + PyList_Append(result,obj); + Py_DECREF(obj); + } + return result; +} + +/* Unpack the argument tuple */ + +SWIGINTERN Py_ssize_t +SWIG_Python_UnpackTuple(PyObject *args, const char *name, Py_ssize_t min, Py_ssize_t max, PyObject **objs) +{ + if (!args) { + if (!min && !max) { + return 1; + } else { + PyErr_Format(PyExc_TypeError, "%s expected %s%d arguments, got none", + name, (min == max ? "" : "at least "), (int)min); + return 0; + } + } + if (!PyTuple_Check(args)) { + if (min <= 1 && max >= 1) { + Py_ssize_t i; + objs[0] = args; + for (i = 1; i < max; ++i) { + objs[i] = 0; + } + return 2; + } + PyErr_SetString(PyExc_SystemError, "UnpackTuple() argument list is not a tuple"); + return 0; + } else { + Py_ssize_t l = PyTuple_GET_SIZE(args); + if (l < min) { + PyErr_Format(PyExc_TypeError, "%s expected %s%d arguments, got %d", + name, (min == max ? "" : "at least "), (int)min, (int)l); + return 0; + } else if (l > max) { + PyErr_Format(PyExc_TypeError, "%s expected %s%d arguments, got %d", + name, (min == max ? "" : "at most "), (int)max, (int)l); + return 0; + } else { + Py_ssize_t i; + for (i = 0; i < l; ++i) { + objs[i] = PyTuple_GET_ITEM(args, i); + } + for (; l < max; ++l) { + objs[l] = 0; + } + return i + 1; + } + } +} + +SWIGINTERN int +SWIG_Python_CheckNoKeywords(PyObject *kwargs, const char *name) { + int no_kwargs = 1; + if (kwargs) { + assert(PyDict_Check(kwargs)); + if (PyDict_Size(kwargs) > 0) { + PyErr_Format(PyExc_TypeError, "%s() does not take keyword arguments", name); + no_kwargs = 0; + } + } + return no_kwargs; +} + +/* A functor is a function object with one single object argument */ +#define SWIG_Python_CallFunctor(functor, obj) PyObject_CallFunctionObjArgs(functor, obj, NULL); + +/* + Helper for static pointer initialization for both C and C++ code, for example + static PyObject *SWIG_STATIC_POINTER(MyVar) = NewSomething(...); +*/ +#ifdef __cplusplus +#define SWIG_STATIC_POINTER(var) var +#else +#define SWIG_STATIC_POINTER(var) var = 0; if (!var) var +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* Python-specific SWIG API */ +#define SWIG_newvarlink() SWIG_Python_newvarlink() +#define SWIG_addvarlink(p, name, get_attr, set_attr) SWIG_Python_addvarlink(p, name, get_attr, set_attr) +#define SWIG_InstallConstants(d, constants) SWIG_Python_InstallConstants(d, constants) + +/* ----------------------------------------------------------------------------- + * global variable support code. + * ----------------------------------------------------------------------------- */ + +typedef struct swig_globalvar { + char *name; /* Name of global variable */ + PyObject *(*get_attr)(void); /* Return the current value */ + int (*set_attr)(PyObject *); /* Set the value */ + struct swig_globalvar *next; +} swig_globalvar; + +typedef struct swig_varlinkobject { + PyObject_HEAD + swig_globalvar *vars; +} swig_varlinkobject; + +SWIGINTERN PyObject * +swig_varlink_repr(PyObject *SWIGUNUSEDPARM(v)) { +#if PY_VERSION_HEX >= 0x03000000 + return PyUnicode_InternFromString(""); +#else + return PyString_FromString(""); +#endif +} + +SWIGINTERN PyObject * +swig_varlink_str(PyObject *o) { + swig_varlinkobject *v = (swig_varlinkobject *) o; +#if PY_VERSION_HEX >= 0x03000000 + PyObject *str = PyUnicode_InternFromString("("); + PyObject *tail; + PyObject *joined; + swig_globalvar *var; + for (var = v->vars; var; var=var->next) { + tail = PyUnicode_FromString(var->name); + joined = PyUnicode_Concat(str, tail); + Py_DecRef(str); + Py_DecRef(tail); + str = joined; + if (var->next) { + tail = PyUnicode_InternFromString(", "); + joined = PyUnicode_Concat(str, tail); + Py_DecRef(str); + Py_DecRef(tail); + str = joined; + } + } + tail = PyUnicode_InternFromString(")"); + joined = PyUnicode_Concat(str, tail); + Py_DecRef(str); + Py_DecRef(tail); + str = joined; +#else + PyObject *str = PyString_FromString("("); + swig_globalvar *var; + for (var = v->vars; var; var=var->next) { + PyString_ConcatAndDel(&str,PyString_FromString(var->name)); + if (var->next) PyString_ConcatAndDel(&str,PyString_FromString(", ")); + } + PyString_ConcatAndDel(&str,PyString_FromString(")")); +#endif + return str; +} + +SWIGINTERN void +swig_varlink_dealloc(PyObject *o) { + swig_varlinkobject *v = (swig_varlinkobject *) o; + swig_globalvar *var = v->vars; + while (var) { + swig_globalvar *n = var->next; + free(var->name); + free(var); + var = n; + } +} + +SWIGINTERN PyObject * +swig_varlink_getattr(PyObject *o, char *n) { + swig_varlinkobject *v = (swig_varlinkobject *) o; + PyObject *res = NULL; + swig_globalvar *var = v->vars; + while (var) { + if (strcmp(var->name,n) == 0) { + res = (*var->get_attr)(); + break; + } + var = var->next; + } + if (res == NULL && !PyErr_Occurred()) { + PyErr_Format(PyExc_AttributeError, "Unknown C global variable '%s'", n); + } + return res; +} + +SWIGINTERN int +swig_varlink_setattr(PyObject *o, char *n, PyObject *p) { + swig_varlinkobject *v = (swig_varlinkobject *) o; + int res = 1; + swig_globalvar *var = v->vars; + while (var) { + if (strcmp(var->name,n) == 0) { + res = (*var->set_attr)(p); + break; + } + var = var->next; + } + if (res == 1 && !PyErr_Occurred()) { + PyErr_Format(PyExc_AttributeError, "Unknown C global variable '%s'", n); + } + return res; +} + +SWIGINTERN PyTypeObject* +swig_varlink_type(void) { + static char varlink__doc__[] = "Swig var link object"; +#ifndef Py_LIMITED_API + static PyTypeObject varlink_type; + static int type_init = 0; + if (!type_init) { + const PyTypeObject tmp = { +#if PY_VERSION_HEX >= 0x03000000 + PyVarObject_HEAD_INIT(NULL, 0) +#else + PyObject_HEAD_INIT(NULL) + 0, /* ob_size */ +#endif + "swigvarlink", /* tp_name */ + sizeof(swig_varlinkobject), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor) swig_varlink_dealloc, /* tp_dealloc */ +#if PY_VERSION_HEX < 0x030800b4 + (printfunc)0, /*tp_print*/ +#else + (Py_ssize_t)0, /*tp_vectorcall_offset*/ +#endif + (getattrfunc) swig_varlink_getattr, /* tp_getattr */ + (setattrfunc) swig_varlink_setattr, /* tp_setattr */ + 0, /* tp_compare */ + (reprfunc) swig_varlink_repr, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + (reprfunc) swig_varlink_str, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + 0, /* tp_flags */ + varlink__doc__, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* tp_iter -> tp_weaklist */ + 0, /* tp_del */ + 0, /* tp_version_tag */ +#if PY_VERSION_HEX >= 0x03040000 + 0, /* tp_finalize */ +#endif +#if PY_VERSION_HEX >= 0x03080000 + 0, /* tp_vectorcall */ +#endif +#if (PY_VERSION_HEX >= 0x03080000) && (PY_VERSION_HEX < 0x03090000) + 0, /* tp_print */ +#endif +#if PY_VERSION_HEX >= 0x030C0000 + 0, /* tp_watched */ +#endif +#ifdef COUNT_ALLOCS + 0, /* tp_allocs */ + 0, /* tp_frees */ + 0, /* tp_maxalloc */ + 0, /* tp_prev */ + 0 /* tp_next */ +#endif + }; + varlink_type = tmp; + type_init = 1; + if (PyType_Ready(&varlink_type) < 0) + return NULL; + } + return &varlink_type; +#else + PyType_Slot slots[] = { + { Py_tp_dealloc, (void *)swig_varlink_dealloc }, + { Py_tp_repr, (void *)swig_varlink_repr }, + { Py_tp_getattr, (void *)swig_varlink_getattr }, + { Py_tp_setattr, (void *)swig_varlink_setattr }, + { Py_tp_str, (void *)swig_varlink_str }, + { Py_tp_doc, (void *)varlink__doc__ }, + { 0, NULL } + }; + PyType_Spec spec = { + "swigvarlink", + sizeof(swig_varlinkobject), + 0, + Py_TPFLAGS_DEFAULT, + slots + }; + return (PyTypeObject *)PyType_FromSpec(&spec); +#endif +} + +/* Create a variable linking object for use later */ +SWIGINTERN PyObject * +SWIG_Python_newvarlink(void) { + swig_varlinkobject *result = PyObject_New(swig_varlinkobject, swig_varlink_type()); + if (result) { + result->vars = 0; + } + return ((PyObject*) result); +} + +SWIGINTERN void +SWIG_Python_addvarlink(PyObject *p, const char *name, PyObject *(*get_attr)(void), int (*set_attr)(PyObject *p)) { + swig_varlinkobject *v = (swig_varlinkobject *) p; + swig_globalvar *gv = (swig_globalvar *) malloc(sizeof(swig_globalvar)); + if (gv) { + size_t size = strlen(name)+1; + gv->name = (char *)malloc(size); + if (gv->name) { + memcpy(gv->name, name, size); + gv->get_attr = get_attr; + gv->set_attr = set_attr; + gv->next = v->vars; + } + } + v->vars = gv; +} + + +static PyObject *Swig_Globals_global = NULL; + +SWIGINTERN PyObject * +SWIG_globals(void) { + if (Swig_Globals_global == NULL) { + Swig_Globals_global = SWIG_newvarlink(); + } + return Swig_Globals_global; +} + +#ifdef __cplusplus +} +#endif + +/* ----------------------------------------------------------------------------- + * Pointer declarations + * ----------------------------------------------------------------------------- */ + +/* Flags for new pointer objects */ +#define SWIG_POINTER_NOSHADOW (SWIG_POINTER_OWN << 1) +#define SWIG_POINTER_NEW (SWIG_POINTER_NOSHADOW | SWIG_POINTER_OWN) + +#define SWIG_POINTER_IMPLICIT_CONV (SWIG_POINTER_DISOWN << 1) + +#define SWIG_BUILTIN_TP_INIT (SWIG_POINTER_OWN << 2) +#define SWIG_BUILTIN_INIT (SWIG_BUILTIN_TP_INIT | SWIG_POINTER_OWN) + +#ifdef __cplusplus +extern "C" { +#endif + +/* The python void return value */ + +SWIGRUNTIMEINLINE PyObject * +SWIG_Py_Void(void) +{ + PyObject *none = Py_None; + Py_INCREF(none); + return none; +} + +/* SwigPyClientData */ + +typedef struct { + PyObject *klass; + PyObject *newraw; + PyObject *newargs; + PyObject *destroy; + int delargs; + int implicitconv; + PyTypeObject *pytype; +} SwigPyClientData; + +SWIGRUNTIMEINLINE int +SWIG_Python_CheckImplicit(swig_type_info *ty) +{ + SwigPyClientData *data = (SwigPyClientData *)ty->clientdata; + int fail = data ? data->implicitconv : 0; + if (fail) + PyErr_SetString(PyExc_TypeError, "Implicit conversion is prohibited for explicit constructors."); + return fail; +} + +SWIGRUNTIMEINLINE PyObject * +SWIG_Python_ExceptionType(swig_type_info *desc) { + SwigPyClientData *data = desc ? (SwigPyClientData *) desc->clientdata : 0; + PyObject *klass = data ? data->klass : 0; + return (klass ? klass : PyExc_RuntimeError); +} + + +SWIGRUNTIME SwigPyClientData * +SwigPyClientData_New(PyObject* obj) +{ + if (!obj) { + return 0; + } else { + SwigPyClientData *data = (SwigPyClientData *)malloc(sizeof(SwigPyClientData)); + /* the klass element */ + data->klass = obj; + Py_INCREF(data->klass); + /* the newraw method and newargs arguments used to create a new raw instance */ + if (PyClass_Check(obj)) { + data->newraw = 0; + Py_INCREF(obj); + data->newargs = obj; + } else { + data->newraw = PyObject_GetAttrString(data->klass, "__new__"); + if (data->newraw) { + data->newargs = PyTuple_New(1); + if (data->newargs) { + Py_INCREF(obj); + PyTuple_SET_ITEM(data->newargs, 0, obj); + } else { + Py_DECREF(data->newraw); + Py_DECREF(data->klass); + free(data); + return 0; + } + } else { + Py_INCREF(obj); + data->newargs = obj; + } + } + /* the destroy method, aka as the C++ delete method */ + data->destroy = PyObject_GetAttrString(data->klass, "__swig_destroy__"); + if (PyErr_Occurred()) { + PyErr_Clear(); + data->destroy = 0; + } + if (data->destroy) { + data->delargs = !(PyCFunction_GET_FLAGS(data->destroy) & METH_O); + } else { + data->delargs = 0; + } + data->implicitconv = 0; + data->pytype = 0; + return data; + } +} + +SWIGRUNTIME void +SwigPyClientData_Del(SwigPyClientData *data) +{ + Py_XDECREF(data->klass); + Py_XDECREF(data->newraw); + Py_XDECREF(data->newargs); + Py_XDECREF(data->destroy); + free(data); +} + +/* =============== SwigPyObject =====================*/ + +typedef struct { + PyObject_HEAD + void *ptr; + swig_type_info *ty; + int own; + PyObject *next; +#ifdef SWIGPYTHON_BUILTIN + PyObject *dict; +#endif +} SwigPyObject; + + +#ifdef SWIGPYTHON_BUILTIN + +SWIGRUNTIME PyObject * +SwigPyObject_get___dict__(PyObject *v, PyObject *SWIGUNUSEDPARM(args)) +{ + SwigPyObject *sobj = (SwigPyObject *)v; + + if (!sobj->dict) + sobj->dict = PyDict_New(); + + Py_XINCREF(sobj->dict); + return sobj->dict; +} + +#endif + +SWIGRUNTIME PyObject * +SwigPyObject_long(SwigPyObject *v) +{ + return PyLong_FromVoidPtr(v->ptr); +} + +SWIGRUNTIME PyObject * +SwigPyObject_format(const char* fmt, SwigPyObject *v) +{ + PyObject *res = NULL; + PyObject *args = PyTuple_New(1); + if (args) { + PyObject *val = SwigPyObject_long(v); + if (val) { + PyObject *ofmt; + PyTuple_SET_ITEM(args, 0, val); + ofmt = SWIG_Python_str_FromChar(fmt); + if (ofmt) { +#if PY_VERSION_HEX >= 0x03000000 + res = PyUnicode_Format(ofmt,args); +#else + res = PyString_Format(ofmt,args); +#endif + Py_DECREF(ofmt); + } + } + Py_DECREF(args); + } + return res; +} + +SWIGRUNTIME PyObject * +SwigPyObject_oct(SwigPyObject *v) +{ + return SwigPyObject_format("%o",v); +} + +SWIGRUNTIME PyObject * +SwigPyObject_hex(SwigPyObject *v) +{ + return SwigPyObject_format("%x",v); +} + +SWIGRUNTIME PyObject * +SwigPyObject_repr(SwigPyObject *v) +{ + const char *name = SWIG_TypePrettyName(v->ty); + PyObject *repr = SWIG_Python_str_FromFormat("", (name ? name : "unknown"), (void *)v); + if (repr && v->next) { + PyObject *nrep = SwigPyObject_repr((SwigPyObject *)v->next); + if (nrep) { +# if PY_VERSION_HEX >= 0x03000000 + PyObject *joined = PyUnicode_Concat(repr, nrep); + Py_DecRef(repr); + Py_DecRef(nrep); + repr = joined; +# else + PyString_ConcatAndDel(&repr,nrep); +# endif + } else { + Py_DecRef(repr); + repr = NULL; + } + } + return repr; +} + +/* We need a version taking two PyObject* parameters so it's a valid + * PyCFunction to use in swigobject_methods[]. */ +SWIGRUNTIME PyObject * +SwigPyObject_repr2(PyObject *v, PyObject *SWIGUNUSEDPARM(args)) +{ + return SwigPyObject_repr((SwigPyObject*)v); +} + +SWIGRUNTIME int +SwigPyObject_compare(SwigPyObject *v, SwigPyObject *w) +{ + void *i = v->ptr; + void *j = w->ptr; + return (i < j) ? -1 : ((i > j) ? 1 : 0); +} + +/* Added for Python 3.x, would it also be useful for Python 2.x? */ +SWIGRUNTIME PyObject* +SwigPyObject_richcompare(SwigPyObject *v, SwigPyObject *w, int op) +{ + PyObject* res = NULL; + if (!PyErr_Occurred()) { + if (op != Py_EQ && op != Py_NE) { + Py_INCREF(Py_NotImplemented); + return Py_NotImplemented; + } + res = PyBool_FromLong( (SwigPyObject_compare(v, w)==0) == (op == Py_EQ) ? 1 : 0); + } + return res; +} + + +SWIGRUNTIME PyTypeObject* SwigPyObject_TypeOnce(void); + +#ifdef SWIGPYTHON_BUILTIN +static swig_type_info *SwigPyObject_stype = 0; +SWIGRUNTIME PyTypeObject* +SwigPyObject_type(void) { + SwigPyClientData *cd; + assert(SwigPyObject_stype); + cd = (SwigPyClientData*) SwigPyObject_stype->clientdata; + assert(cd); + assert(cd->pytype); + return cd->pytype; +} +#else +SWIGRUNTIME PyTypeObject* +SwigPyObject_type(void) { + static PyTypeObject *SWIG_STATIC_POINTER(type) = SwigPyObject_TypeOnce(); + return type; +} +#endif + +SWIGRUNTIMEINLINE int +SwigPyObject_Check(PyObject *op) { + PyTypeObject *target_tp = SwigPyObject_type(); + PyTypeObject *op_type = Py_TYPE(op); +#ifdef SWIGPYTHON_BUILTIN + if (PyType_IsSubtype(op_type, target_tp)) + return 1; + return (strcmp(op_type->tp_name, "SwigPyObject") == 0); +#else + if (op_type == target_tp) + return 1; +# ifdef Py_LIMITED_API + int cmp; + PyObject *tp_name = PyObject_GetAttrString((PyObject *)op_type, "__name__"); + if (!tp_name) + return 0; + cmp = PyUnicode_CompareWithASCIIString(tp_name, "SwigPyObject"); + Py_DECREF(tp_name); + return cmp == 0; +# else + return (strcmp(op_type->tp_name, "SwigPyObject") == 0); +# endif +#endif +} + +SWIGRUNTIME PyObject * +SwigPyObject_New(void *ptr, swig_type_info *ty, int own); + +static PyObject* Swig_Capsule_global = NULL; + +SWIGRUNTIME void +SwigPyObject_dealloc(PyObject *v) +{ + SwigPyObject *sobj = (SwigPyObject *) v; + PyObject *next = sobj->next; + if (sobj->own == SWIG_POINTER_OWN) { + swig_type_info *ty = sobj->ty; + SwigPyClientData *data = ty ? (SwigPyClientData *) ty->clientdata : 0; + PyObject *destroy = data ? data->destroy : 0; + if (destroy) { + /* destroy is always a VARARGS method */ + PyObject *res; + + /* PyObject_CallFunction() has the potential to silently drop + the active exception. In cases of unnamed temporary + variable or where we just finished iterating over a generator + StopIteration will be active right now, and this needs to + remain true upon return from SwigPyObject_dealloc. So save + and restore. */ + + PyObject *type = NULL, *value = NULL, *traceback = NULL; + PyErr_Fetch(&type, &value, &traceback); + + if (data->delargs) { + /* we need to create a temporary object to carry the destroy operation */ + PyObject *tmp = SwigPyObject_New(sobj->ptr, ty, 0); + if (tmp) { + res = SWIG_Python_CallFunctor(destroy, tmp); + } else { + res = 0; + } + Py_XDECREF(tmp); + } else { + PyCFunction meth = PyCFunction_GET_FUNCTION(destroy); + PyObject *mself = PyCFunction_GET_SELF(destroy); + res = ((*meth)(mself, v)); + } + if (!res) + PyErr_WriteUnraisable(destroy); + + PyErr_Restore(type, value, traceback); + + Py_XDECREF(res); + } +#if !defined(SWIG_PYTHON_SILENT_MEMLEAK) + else { + const char *name = SWIG_TypePrettyName(ty); + printf("swig/python detected a memory leak of type '%s', no destructor found.\n", (name ? name : "unknown")); + } +#endif + Py_XDECREF(Swig_Capsule_global); + } + Py_XDECREF(next); +#ifdef SWIGPYTHON_BUILTIN + Py_XDECREF(sobj->dict); +#endif + PyObject_DEL(v); +} + +SWIGRUNTIME PyObject* +SwigPyObject_append(PyObject* v, PyObject* next) +{ + SwigPyObject *sobj = (SwigPyObject *) v; + if (!SwigPyObject_Check(next)) { + PyErr_SetString(PyExc_TypeError, "Attempt to append a non SwigPyObject"); + return NULL; + } + ((SwigPyObject *)next)->next = sobj->next; + sobj->next = next; + Py_INCREF(next); + return SWIG_Py_Void(); +} + +SWIGRUNTIME PyObject* +SwigPyObject_next(PyObject* v, PyObject *SWIGUNUSEDPARM(args)) +{ + SwigPyObject *sobj = (SwigPyObject *) v; + if (sobj->next) { + Py_INCREF(sobj->next); + return sobj->next; + } else { + return SWIG_Py_Void(); + } +} + +SWIGINTERN PyObject* +SwigPyObject_disown(PyObject* v, PyObject *SWIGUNUSEDPARM(args)) +{ + SwigPyObject *sobj = (SwigPyObject *)v; + sobj->own = 0; + return SWIG_Py_Void(); +} + +SWIGINTERN PyObject* +SwigPyObject_acquire(PyObject* v, PyObject *SWIGUNUSEDPARM(args)) +{ + SwigPyObject *sobj = (SwigPyObject *)v; + sobj->own = SWIG_POINTER_OWN; + return SWIG_Py_Void(); +} + +SWIGINTERN PyObject* +SwigPyObject_own(PyObject *v, PyObject *args) +{ + PyObject *val = 0; + if (!PyArg_UnpackTuple(args, "own", 0, 1, &val)) { + return NULL; + } else { + SwigPyObject *sobj = (SwigPyObject *)v; + PyObject *obj = PyBool_FromLong(sobj->own); + if (val) { + if (PyObject_IsTrue(val)) { + Py_DECREF(SwigPyObject_acquire(v,args)); + } else { + Py_DECREF(SwigPyObject_disown(v,args)); + } + } + return obj; + } +} + +static PyMethodDef +swigobject_methods[] = { + {"disown", SwigPyObject_disown, METH_NOARGS, "releases ownership of the pointer"}, + {"acquire", SwigPyObject_acquire, METH_NOARGS, "acquires ownership of the pointer"}, + {"own", SwigPyObject_own, METH_VARARGS, "returns/sets ownership of the pointer"}, + {"append", SwigPyObject_append, METH_O, "appends another 'this' object"}, + {"next", SwigPyObject_next, METH_NOARGS, "returns the next 'this' object"}, + {"__repr__",SwigPyObject_repr2, METH_NOARGS, "returns object representation"}, + {0, 0, 0, 0} +}; + +SWIGRUNTIME PyTypeObject* +SwigPyObject_TypeOnce(void) { + static char swigobject_doc[] = "Swig object carries a C/C++ instance pointer"; +#ifndef Py_LIMITED_API + static PyNumberMethods SwigPyObject_as_number = { + (binaryfunc)0, /*nb_add*/ + (binaryfunc)0, /*nb_subtract*/ + (binaryfunc)0, /*nb_multiply*/ + /* nb_divide removed in Python 3 */ +#if PY_VERSION_HEX < 0x03000000 + (binaryfunc)0, /*nb_divide*/ +#endif + (binaryfunc)0, /*nb_remainder*/ + (binaryfunc)0, /*nb_divmod*/ + (ternaryfunc)0,/*nb_power*/ + (unaryfunc)0, /*nb_negative*/ + (unaryfunc)0, /*nb_positive*/ + (unaryfunc)0, /*nb_absolute*/ + (inquiry)0, /*nb_nonzero*/ + 0, /*nb_invert*/ + 0, /*nb_lshift*/ + 0, /*nb_rshift*/ + 0, /*nb_and*/ + 0, /*nb_xor*/ + 0, /*nb_or*/ +#if PY_VERSION_HEX < 0x03000000 + 0, /*nb_coerce*/ +#endif + (unaryfunc)SwigPyObject_long, /*nb_int*/ +#if PY_VERSION_HEX < 0x03000000 + (unaryfunc)SwigPyObject_long, /*nb_long*/ +#else + 0, /*nb_reserved*/ +#endif + (unaryfunc)0, /*nb_float*/ +#if PY_VERSION_HEX < 0x03000000 + (unaryfunc)SwigPyObject_oct, /*nb_oct*/ + (unaryfunc)SwigPyObject_hex, /*nb_hex*/ +#endif +#if PY_VERSION_HEX >= 0x03050000 /* 3.5 */ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_inplace_matrix_multiply */ +#elif PY_VERSION_HEX >= 0x03000000 /* 3.0 */ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_index, nb_inplace_divide removed */ +#else + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_index */ +#endif + }; + + static PyTypeObject swigpyobject_type; + static int type_init = 0; + if (!type_init) { + const PyTypeObject tmp = { +#if PY_VERSION_HEX >= 0x03000000 + PyVarObject_HEAD_INIT(NULL, 0) +#else + PyObject_HEAD_INIT(NULL) + 0, /* ob_size */ +#endif + "SwigPyObject", /* tp_name */ + sizeof(SwigPyObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)SwigPyObject_dealloc, /* tp_dealloc */ +#if PY_VERSION_HEX < 0x030800b4 + (printfunc)0, /*tp_print*/ +#else + (Py_ssize_t)0, /*tp_vectorcall_offset*/ +#endif + (getattrfunc)0, /* tp_getattr */ + (setattrfunc)0, /* tp_setattr */ +#if PY_VERSION_HEX >= 0x03000000 + 0, /* tp_reserved in 3.0.1, tp_compare in 3.0.0 but not used */ +#else + (cmpfunc)SwigPyObject_compare, /* tp_compare */ +#endif + (reprfunc)SwigPyObject_repr, /* tp_repr */ + &SwigPyObject_as_number, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + (hashfunc)0, /* tp_hash */ + (ternaryfunc)0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + swigobject_doc, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + (richcmpfunc)SwigPyObject_richcompare,/* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + swigobject_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ + 0, /* tp_free */ + 0, /* tp_is_gc */ + 0, /* tp_bases */ + 0, /* tp_mro */ + 0, /* tp_cache */ + 0, /* tp_subclasses */ + 0, /* tp_weaklist */ + 0, /* tp_del */ + 0, /* tp_version_tag */ +#if PY_VERSION_HEX >= 0x03040000 + 0, /* tp_finalize */ +#endif +#if PY_VERSION_HEX >= 0x03080000 + 0, /* tp_vectorcall */ +#endif +#if (PY_VERSION_HEX >= 0x03080000) && (PY_VERSION_HEX < 0x03090000) + 0, /* tp_print */ +#endif +#if PY_VERSION_HEX >= 0x030C0000 + 0, /* tp_watched */ +#endif +#ifdef COUNT_ALLOCS + 0, /* tp_allocs */ + 0, /* tp_frees */ + 0, /* tp_maxalloc */ + 0, /* tp_prev */ + 0 /* tp_next */ +#endif + }; + swigpyobject_type = tmp; + type_init = 1; + if (PyType_Ready(&swigpyobject_type) != 0) + return NULL; + } + return &swigpyobject_type; +#else + PyType_Slot slots[] = { + { Py_tp_dealloc, (void *)SwigPyObject_dealloc }, + { Py_tp_repr, (void *)SwigPyObject_repr }, + { Py_tp_getattro, (void *)PyObject_GenericGetAttr }, + { Py_tp_doc, (void *)swigobject_doc }, + { Py_tp_richcompare, (void *)SwigPyObject_richcompare }, + { Py_tp_methods, (void *)swigobject_methods }, + { Py_nb_int, (void *)SwigPyObject_long }, + { 0, NULL } + }; + PyType_Spec spec = { + "SwigPyObject", + sizeof(SwigPyObject), + 0, + Py_TPFLAGS_DEFAULT, + slots + }; + return (PyTypeObject *)PyType_FromSpec(&spec); +#endif +} + +SWIGRUNTIME PyObject * +SwigPyObject_New(void *ptr, swig_type_info *ty, int own) +{ + SwigPyObject *sobj = PyObject_New(SwigPyObject, SwigPyObject_type()); + if (sobj) { + sobj->ptr = ptr; + sobj->ty = ty; + sobj->own = own; + sobj->next = 0; +#ifdef SWIGPYTHON_BUILTIN + sobj->dict = 0; +#endif + if (own == SWIG_POINTER_OWN) { + /* Obtain a reference to the Python capsule wrapping the module information, so that the + * module information is correctly destroyed after all SWIG python objects have been freed + * by the GC (and corresponding destructors invoked) */ + Py_XINCREF(Swig_Capsule_global); + } + } + return (PyObject *)sobj; +} + +/* ----------------------------------------------------------------------------- + * Implements a simple Swig Packed type, and use it instead of string + * ----------------------------------------------------------------------------- */ + +typedef struct { + PyObject_HEAD + void *pack; + swig_type_info *ty; + size_t size; +} SwigPyPacked; + +SWIGRUNTIME PyObject * +SwigPyPacked_repr(SwigPyPacked *v) +{ + char result[SWIG_BUFFER_SIZE]; + if (SWIG_PackDataName(result, v->pack, v->size, 0, sizeof(result))) { + return SWIG_Python_str_FromFormat("", result, v->ty->name); + } else { + return SWIG_Python_str_FromFormat("", v->ty->name); + } +} + +SWIGRUNTIME PyObject * +SwigPyPacked_str(SwigPyPacked *v) +{ + char result[SWIG_BUFFER_SIZE]; + if (SWIG_PackDataName(result, v->pack, v->size, 0, sizeof(result))){ + return SWIG_Python_str_FromFormat("%s%s", result, v->ty->name); + } else { + return SWIG_Python_str_FromChar(v->ty->name); + } +} + +SWIGRUNTIME int +SwigPyPacked_compare(SwigPyPacked *v, SwigPyPacked *w) +{ + size_t i = v->size; + size_t j = w->size; + int s = (i < j) ? -1 : ((i > j) ? 1 : 0); + return s ? s : strncmp((const char *)v->pack, (const char *)w->pack, 2*v->size); +} + +SWIGRUNTIME PyTypeObject* SwigPyPacked_TypeOnce(void); + +SWIGRUNTIME PyTypeObject* +SwigPyPacked_type(void) { + static PyTypeObject *SWIG_STATIC_POINTER(type) = SwigPyPacked_TypeOnce(); + return type; +} + +SWIGRUNTIMEINLINE int +SwigPyPacked_Check(PyObject *op) { + PyTypeObject* op_type = Py_TYPE(op); + if (op_type == SwigPyPacked_TypeOnce()) + return 1; +#ifdef Py_LIMITED_API + int cmp; + PyObject *tp_name = PyObject_GetAttrString((PyObject *)op_type, "__name__"); + if (!tp_name) + return 0; + cmp = PyUnicode_CompareWithASCIIString(tp_name, "SwigPyPacked"); + Py_DECREF(tp_name); + return cmp == 0; +#else + return (strcmp(op_type->tp_name, "SwigPyPacked") == 0); +#endif +} + +SWIGRUNTIME void +SwigPyPacked_dealloc(PyObject *v) +{ + if (SwigPyPacked_Check(v)) { + SwigPyPacked *sobj = (SwigPyPacked *) v; + free(sobj->pack); + } + PyObject_DEL(v); +} + +SWIGRUNTIME PyTypeObject* +SwigPyPacked_TypeOnce(void) { + static char swigpacked_doc[] = "Swig object carries a C/C++ instance pointer"; +#ifndef Py_LIMITED_API + static PyTypeObject swigpypacked_type; + static int type_init = 0; + if (!type_init) { + const PyTypeObject tmp = { +#if PY_VERSION_HEX>=0x03000000 + PyVarObject_HEAD_INIT(NULL, 0) +#else + PyObject_HEAD_INIT(NULL) + 0, /* ob_size */ +#endif + "SwigPyPacked", /* tp_name */ + sizeof(SwigPyPacked), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)SwigPyPacked_dealloc, /* tp_dealloc */ +#if PY_VERSION_HEX < 0x030800b4 + (printfunc)0, /*tp_print*/ +#else + (Py_ssize_t)0, /*tp_vectorcall_offset*/ +#endif + (getattrfunc)0, /* tp_getattr */ + (setattrfunc)0, /* tp_setattr */ +#if PY_VERSION_HEX>=0x03000000 + 0, /* tp_reserved in 3.0.1 */ +#else + (cmpfunc)SwigPyPacked_compare, /* tp_compare */ +#endif + (reprfunc)SwigPyPacked_repr, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + (hashfunc)0, /* tp_hash */ + (ternaryfunc)0, /* tp_call */ + (reprfunc)SwigPyPacked_str, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + swigpacked_doc, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ + 0, /* tp_free */ + 0, /* tp_is_gc */ + 0, /* tp_bases */ + 0, /* tp_mro */ + 0, /* tp_cache */ + 0, /* tp_subclasses */ + 0, /* tp_weaklist */ + 0, /* tp_del */ + 0, /* tp_version_tag */ +#if PY_VERSION_HEX >= 0x03040000 + 0, /* tp_finalize */ +#endif +#if PY_VERSION_HEX >= 0x03080000 + 0, /* tp_vectorcall */ +#endif +#if (PY_VERSION_HEX >= 0x03080000) && (PY_VERSION_HEX < 0x03090000) + 0, /* tp_print */ +#endif +#if PY_VERSION_HEX >= 0x030C0000 + 0, /* tp_watched */ +#endif +#ifdef COUNT_ALLOCS + 0, /* tp_allocs */ + 0, /* tp_frees */ + 0, /* tp_maxalloc */ + 0, /* tp_prev */ + 0 /* tp_next */ +#endif + }; + swigpypacked_type = tmp; + type_init = 1; + if (PyType_Ready(&swigpypacked_type) != 0) + return NULL; + } + return &swigpypacked_type; +#else + PyType_Slot slots[] = { + { Py_tp_dealloc, (void *)SwigPyPacked_dealloc }, + { Py_tp_repr, (void *)SwigPyPacked_repr }, + { Py_tp_str, (void *)SwigPyPacked_str }, + { Py_tp_getattro, (void *)PyObject_GenericGetAttr }, + { Py_tp_doc, (void *)swigpacked_doc }, + { 0, NULL } + }; + PyType_Spec spec = { + "SwigPyPacked", + sizeof(SwigPyPacked), + 0, + Py_TPFLAGS_DEFAULT, + slots + }; + return (PyTypeObject *)PyType_FromSpec(&spec); +#endif +} + +SWIGRUNTIME PyObject * +SwigPyPacked_New(void *ptr, size_t size, swig_type_info *ty) +{ + SwigPyPacked *sobj = PyObject_New(SwigPyPacked, SwigPyPacked_type()); + if (sobj) { + void *pack = malloc(size); + if (pack) { + memcpy(pack, ptr, size); + sobj->pack = pack; + sobj->ty = ty; + sobj->size = size; + } else { + PyObject_DEL((PyObject *) sobj); + sobj = 0; + } + } + return (PyObject *) sobj; +} + +SWIGRUNTIME swig_type_info * +SwigPyPacked_UnpackData(PyObject *obj, void *ptr, size_t size) +{ + if (SwigPyPacked_Check(obj)) { + SwigPyPacked *sobj = (SwigPyPacked *)obj; + if (sobj->size != size) return 0; + memcpy(ptr, sobj->pack, size); + return sobj->ty; + } else { + return 0; + } +} + +/* ----------------------------------------------------------------------------- + * pointers/data manipulation + * ----------------------------------------------------------------------------- */ + +static PyObject *Swig_This_global = NULL; + +SWIGRUNTIME PyObject * +SWIG_This(void) +{ + if (Swig_This_global == NULL) + Swig_This_global = SWIG_Python_str_FromChar("this"); + return Swig_This_global; +} + +/* #define SWIG_PYTHON_SLOW_GETSET_THIS */ + +/* TODO: I don't know how to implement the fast getset in Python 3 right now */ +#if PY_VERSION_HEX>=0x03000000 +#define SWIG_PYTHON_SLOW_GETSET_THIS +#endif + +SWIGRUNTIME SwigPyObject * +SWIG_Python_GetSwigThis(PyObject *pyobj) +{ + PyObject *obj; + + if (SwigPyObject_Check(pyobj)) + return (SwigPyObject *) pyobj; + +#ifdef SWIGPYTHON_BUILTIN + (void)obj; +# ifdef PyWeakref_CheckProxy + if (PyWeakref_CheckProxy(pyobj)) { + pyobj = PyWeakref_GET_OBJECT(pyobj); + if (pyobj && SwigPyObject_Check(pyobj)) + return (SwigPyObject*) pyobj; + } +# endif + return NULL; +#else + + obj = 0; + +#if !defined(SWIG_PYTHON_SLOW_GETSET_THIS) + if (PyInstance_Check(pyobj)) { + obj = _PyInstance_Lookup(pyobj, SWIG_This()); + } else { + PyObject **dictptr = _PyObject_GetDictPtr(pyobj); + if (dictptr != NULL) { + PyObject *dict = *dictptr; + obj = dict ? PyDict_GetItem(dict, SWIG_This()) : 0; + } else { +#ifdef PyWeakref_CheckProxy + if (PyWeakref_CheckProxy(pyobj)) { + PyObject *wobj = PyWeakref_GET_OBJECT(pyobj); + return wobj ? SWIG_Python_GetSwigThis(wobj) : 0; + } +#endif + obj = PyObject_GetAttr(pyobj,SWIG_This()); + if (obj) { + Py_DECREF(obj); + } else { + if (PyErr_Occurred()) PyErr_Clear(); + return 0; + } + } + } +#else + obj = PyObject_GetAttr(pyobj,SWIG_This()); + if (obj) { + Py_DECREF(obj); + } else { + if (PyErr_Occurred()) PyErr_Clear(); + return 0; + } +#endif + if (obj && !SwigPyObject_Check(obj)) { + /* a PyObject is called 'this', try to get the 'real this' + SwigPyObject from it */ + return SWIG_Python_GetSwigThis(obj); + } + return (SwigPyObject *)obj; +#endif +} + +/* Acquire a pointer value */ + +SWIGRUNTIME int +SWIG_Python_AcquirePtr(PyObject *obj, int own) { + if (own == SWIG_POINTER_OWN) { + SwigPyObject *sobj = SWIG_Python_GetSwigThis(obj); + if (sobj) { + int oldown = sobj->own; + sobj->own = own; + return oldown; + } + } + return 0; +} + +/* Convert a pointer value */ + +SWIGRUNTIME int +SWIG_Python_ConvertPtrAndOwn(PyObject *obj, void **ptr, swig_type_info *ty, int flags, int *own) { + int res; + SwigPyObject *sobj; + int implicit_conv = (flags & SWIG_POINTER_IMPLICIT_CONV) != 0; + + if (!obj) + return SWIG_ERROR; + if (obj == Py_None && !implicit_conv) { + if (ptr) + *ptr = 0; + return (flags & SWIG_POINTER_NO_NULL) ? SWIG_NullReferenceError : SWIG_OK; + } + + res = SWIG_ERROR; + + sobj = SWIG_Python_GetSwigThis(obj); + if (own) + *own = 0; + while (sobj) { + void *vptr = sobj->ptr; + if (ty) { + swig_type_info *to = sobj->ty; + if (to == ty) { + /* no type cast needed */ + if (ptr) *ptr = vptr; + break; + } else { + swig_cast_info *tc = SWIG_TypeCheck(to->name,ty); + if (!tc) { + sobj = (SwigPyObject *)sobj->next; + } else { + if (ptr) { + int newmemory = 0; + *ptr = SWIG_TypeCast(tc,vptr,&newmemory); + if (newmemory == SWIG_CAST_NEW_MEMORY) { + assert(own); /* badly formed typemap which will lead to a memory leak - it must set and use own to delete *ptr */ + if (own) + *own = *own | SWIG_CAST_NEW_MEMORY; + } + } + break; + } + } + } else { + if (ptr) *ptr = vptr; + break; + } + } + if (sobj) { + if (((flags & SWIG_POINTER_RELEASE) == SWIG_POINTER_RELEASE) && !sobj->own) { + res = SWIG_ERROR_RELEASE_NOT_OWNED; + } else { + if (own) + *own = *own | sobj->own; + if (flags & SWIG_POINTER_DISOWN) { + sobj->own = 0; + } + if (flags & SWIG_POINTER_CLEAR) { + sobj->ptr = 0; + } + res = SWIG_OK; + } + } else { + if (implicit_conv) { + SwigPyClientData *data = ty ? (SwigPyClientData *) ty->clientdata : 0; + if (data && !data->implicitconv) { + PyObject *klass = data->klass; + if (klass) { + PyObject *impconv; + data->implicitconv = 1; /* avoid recursion and call 'explicit' constructors*/ + impconv = SWIG_Python_CallFunctor(klass, obj); + data->implicitconv = 0; + if (PyErr_Occurred()) { + PyErr_Clear(); + impconv = 0; + } + if (impconv) { + SwigPyObject *iobj = SWIG_Python_GetSwigThis(impconv); + if (iobj) { + void *vptr; + res = SWIG_Python_ConvertPtrAndOwn((PyObject*)iobj, &vptr, ty, 0, 0); + if (SWIG_IsOK(res)) { + if (ptr) { + *ptr = vptr; + /* transfer the ownership to 'ptr' */ + iobj->own = 0; + res = SWIG_AddCast(res); + res = SWIG_AddNewMask(res); + } else { + res = SWIG_AddCast(res); + } + } + } + Py_DECREF(impconv); + } + } + } + if (!SWIG_IsOK(res) && obj == Py_None) { + if (ptr) + *ptr = 0; + if (PyErr_Occurred()) + PyErr_Clear(); + res = SWIG_OK; + } + } + } + return res; +} + +/* Convert a function ptr value */ + +SWIGRUNTIME int +SWIG_Python_ConvertFunctionPtr(PyObject *obj, void **ptr, swig_type_info *ty) { + if (!PyCFunction_Check(obj)) { + return SWIG_ConvertPtr(obj, ptr, ty, 0); + } else { + void *vptr = 0; + swig_cast_info *tc; + + /* here we get the method pointer for callbacks */ +#ifndef Py_LIMITED_API + const char *doc = (((PyCFunctionObject *)obj) -> m_ml -> ml_doc); +#else + PyObject* pystr_doc = PyObject_GetAttrString(obj, "__doc__"); + PyObject *bytes = NULL; + const char *doc = pystr_doc ? SWIG_PyUnicode_AsUTF8AndSize(pystr_doc, NULL, &bytes) : 0; +#endif + const char *desc = doc ? strstr(doc, "swig_ptr: ") : 0; + if (desc) + desc = ty ? SWIG_UnpackVoidPtr(desc + 10, &vptr, ty->name) : 0; +#ifdef Py_LIMITED_API + Py_XDECREF(bytes); + Py_XDECREF(pystr_doc); +#endif + if (!desc) + return SWIG_ERROR; + tc = SWIG_TypeCheck(desc,ty); + if (tc) { + int newmemory = 0; + *ptr = SWIG_TypeCast(tc,vptr,&newmemory); + assert(!newmemory); /* newmemory handling not yet implemented */ + } else { + return SWIG_ERROR; + } + return SWIG_OK; + } +} + +/* Convert a packed pointer value */ + +SWIGRUNTIME int +SWIG_Python_ConvertPacked(PyObject *obj, void *ptr, size_t sz, swig_type_info *ty) { + swig_type_info *to = SwigPyPacked_UnpackData(obj, ptr, sz); + if (!to) return SWIG_ERROR; + if (ty) { + if (to != ty) { + /* check type cast? */ + swig_cast_info *tc = SWIG_TypeCheck(to->name,ty); + if (!tc) return SWIG_ERROR; + } + } + return SWIG_OK; +} + +/* ----------------------------------------------------------------------------- + * Create a new pointer object + * ----------------------------------------------------------------------------- */ + +/* + Create a new instance object, without calling __init__, and set the + 'this' attribute. +*/ + +SWIGRUNTIME PyObject* +SWIG_Python_NewShadowInstance(SwigPyClientData *data, PyObject *swig_this) +{ + PyObject *inst = 0; + PyObject *newraw = data->newraw; + if (newraw) { + inst = PyObject_Call(newraw, data->newargs, NULL); + if (inst) { +#if !defined(SWIG_PYTHON_SLOW_GETSET_THIS) + PyObject **dictptr = _PyObject_GetDictPtr(inst); + if (dictptr != NULL) { + PyObject *dict = *dictptr; + if (dict == NULL) { + dict = PyDict_New(); + *dictptr = dict; + } + if (dict) { + PyDict_SetItem(dict, SWIG_This(), swig_this); + } else{ + Py_DECREF(inst); + inst = 0; + } + } +#else + if (PyObject_SetAttr(inst, SWIG_This(), swig_this) == -1) { + Py_DECREF(inst); + inst = 0; + } +#endif + } + } else { +#if PY_VERSION_HEX >= 0x03000000 + PyObject *empty_args = PyTuple_New(0); + if (empty_args) { + PyObject *empty_kwargs = PyDict_New(); + if (empty_kwargs) { +#ifndef Py_LIMITED_API + newfunc newfn = ((PyTypeObject *)data->newargs)->tp_new; +#else + newfunc newfn = (newfunc)PyType_GetSlot((PyTypeObject *)data->newargs, Py_tp_new); +#endif + inst = newfn((PyTypeObject *)data->newargs, empty_args, empty_kwargs); + Py_DECREF(empty_kwargs); + if (inst) { + if (PyObject_SetAttr(inst, SWIG_This(), swig_this) == -1) { + Py_DECREF(inst); + inst = 0; + } else { + PyType_Modified(Py_TYPE(inst)); + } + } + } + Py_DECREF(empty_args); + } +#else + PyObject *dict = PyDict_New(); + if (dict) { + PyDict_SetItem(dict, SWIG_This(), swig_this); + inst = PyInstance_NewRaw(data->newargs, dict); + Py_DECREF(dict); + } +#endif + } + return inst; +} + +SWIGRUNTIME int +SWIG_Python_SetSwigThis(PyObject *inst, PyObject *swig_this) +{ +#if !defined(SWIG_PYTHON_SLOW_GETSET_THIS) + PyObject **dictptr = _PyObject_GetDictPtr(inst); + if (dictptr != NULL) { + PyObject *dict = *dictptr; + if (dict == NULL) { + dict = PyDict_New(); + *dictptr = dict; + } + if (dict) { + return PyDict_SetItem(dict, SWIG_This(), swig_this); + } else{ + return -1; + } + } +#endif + return PyObject_SetAttr(inst, SWIG_This(), swig_this); +} + + +SWIGINTERN PyObject * +SWIG_Python_InitShadowInstance(PyObject *args) { + PyObject *obj[2]; + if (!SWIG_Python_UnpackTuple(args, "swiginit", 2, 2, obj)) { + return NULL; + } else { + SwigPyObject *sthis = SWIG_Python_GetSwigThis(obj[0]); + if (sthis) { + Py_DECREF(SwigPyObject_append((PyObject*) sthis, obj[1])); + } else { + if (SWIG_Python_SetSwigThis(obj[0], obj[1]) != 0) + return NULL; + } + return SWIG_Py_Void(); + } +} + +/* Create a new pointer object */ + +SWIGRUNTIME PyObject * +SWIG_Python_NewPointerObj(PyObject *self, void *ptr, swig_type_info *type, int flags) { + SwigPyClientData *clientdata; + PyObject * robj; + int own; + + if (!ptr) + return SWIG_Py_Void(); + + clientdata = type ? (SwigPyClientData *)(type->clientdata) : 0; + own = (flags & SWIG_POINTER_OWN) ? SWIG_POINTER_OWN : 0; + if (clientdata && clientdata->pytype) { + SwigPyObject *newobj; + if (flags & SWIG_BUILTIN_TP_INIT) { + newobj = (SwigPyObject*) self; + if (newobj->ptr) { +#ifndef Py_LIMITED_API + allocfunc alloc = clientdata->pytype->tp_alloc; +#else + allocfunc alloc = (allocfunc)PyType_GetSlot(clientdata->pytype, Py_tp_alloc); +#endif + PyObject *next_self = alloc(clientdata->pytype, 0); + while (newobj->next) + newobj = (SwigPyObject *) newobj->next; + newobj->next = next_self; + newobj = (SwigPyObject *)next_self; +#ifdef SWIGPYTHON_BUILTIN + newobj->dict = 0; +#endif + } + } else { + newobj = PyObject_New(SwigPyObject, clientdata->pytype); +#ifdef SWIGPYTHON_BUILTIN + if (newobj) { + newobj->dict = 0; + } +#endif + } + if (newobj) { + newobj->ptr = ptr; + newobj->ty = type; + newobj->own = own; + newobj->next = 0; + return (PyObject*) newobj; + } + return SWIG_Py_Void(); + } + + assert(!(flags & SWIG_BUILTIN_TP_INIT)); + + robj = SwigPyObject_New(ptr, type, own); + if (robj && clientdata && !(flags & SWIG_POINTER_NOSHADOW)) { + PyObject *inst = SWIG_Python_NewShadowInstance(clientdata, robj); + Py_DECREF(robj); + robj = inst; + } + return robj; +} + +/* Create a new packed object */ + +SWIGRUNTIMEINLINE PyObject * +SWIG_Python_NewPackedObj(void *ptr, size_t sz, swig_type_info *type) { + return ptr ? SwigPyPacked_New((void *) ptr, sz, type) : SWIG_Py_Void(); +} + +/* -----------------------------------------------------------------------------* + * Get type list + * -----------------------------------------------------------------------------*/ + +#ifdef SWIG_LINK_RUNTIME +void *SWIG_ReturnGlobalTypeList(void *); +#endif + +static PyObject *Swig_TypeCache_global = NULL; + +/* The python cached type query */ +SWIGRUNTIME PyObject * +SWIG_Python_TypeCache(void) { + if (Swig_TypeCache_global == NULL) { + Swig_TypeCache_global = PyDict_New(); + } + return Swig_TypeCache_global; +} + +SWIGRUNTIME swig_module_info * +SWIG_Python_GetModule(void *SWIGUNUSEDPARM(clientdata)) { +#ifdef SWIG_LINK_RUNTIME + static void *type_pointer = (void *)0; + /* first check if module already created */ + if (!type_pointer) { + type_pointer = SWIG_ReturnGlobalTypeList((void *)0); + } +#else + void *type_pointer = PyCapsule_Import(SWIGPY_CAPSULE_NAME, 0); + if (PyErr_Occurred()) { + PyErr_Clear(); + type_pointer = (void *)0; + } +#endif + return (swig_module_info *) type_pointer; +} + + +static int interpreter_counter = 0; /* how many (sub-)interpreters are using swig_module's types */ + +SWIGRUNTIME void +SWIG_Python_DestroyModule(PyObject *obj) +{ + swig_module_info *swig_module = (swig_module_info *) PyCapsule_GetPointer(obj, SWIGPY_CAPSULE_NAME); + swig_type_info **types = swig_module->types; + size_t i; + if (--interpreter_counter != 0) /* another sub-interpreter may still be using the swig_module's types */ + return; + for (i =0; i < swig_module->size; ++i) { + swig_type_info *ty = types[i]; + if (ty->owndata) { + SwigPyClientData *data = (SwigPyClientData *) ty->clientdata; + ty->clientdata = 0; + if (data) SwigPyClientData_Del(data); + } + } + Py_DECREF(SWIG_This()); + Swig_This_global = NULL; + Py_DECREF(SWIG_globals()); + Swig_Globals_global = NULL; + Py_DECREF(SWIG_Python_TypeCache()); + Swig_TypeCache_global = NULL; + Swig_Capsule_global = NULL; +} + +SWIGRUNTIME void +SWIG_Python_SetModule(swig_module_info *swig_module) { +#if PY_VERSION_HEX >= 0x03000000 + /* Add a dummy module object into sys.modules */ + PyObject *module = PyImport_AddModule("swig_runtime_data" SWIG_RUNTIME_VERSION); +#else + static PyMethodDef swig_empty_runtime_method_table[] = { {NULL, NULL, 0, NULL} }; /* Sentinel */ + PyObject *module = Py_InitModule("swig_runtime_data" SWIG_RUNTIME_VERSION, swig_empty_runtime_method_table); +#endif + PyObject *pointer = PyCapsule_New((void *) swig_module, SWIGPY_CAPSULE_NAME, SWIG_Python_DestroyModule); + if (pointer && module) { + if (PyModule_AddObject(module, SWIGPY_CAPSULE_ATTR_NAME, pointer) == 0) { + ++interpreter_counter; + Swig_Capsule_global = pointer; + } else { + Py_DECREF(pointer); + } + } else { + Py_XDECREF(pointer); + } +} + +SWIGRUNTIME swig_type_info * +SWIG_Python_TypeQuery(const char *type) +{ + PyObject *cache = SWIG_Python_TypeCache(); + PyObject *key = SWIG_Python_str_FromChar(type); + PyObject *obj = PyDict_GetItem(cache, key); + swig_type_info *descriptor; + if (obj) { + descriptor = (swig_type_info *) PyCapsule_GetPointer(obj, NULL); + } else { + swig_module_info *swig_module = SWIG_GetModule(0); + descriptor = SWIG_TypeQueryModule(swig_module, swig_module, type); + if (descriptor) { + obj = PyCapsule_New((void*) descriptor, NULL, NULL); + if (obj) { + PyDict_SetItem(cache, key, obj); + Py_DECREF(obj); + } + } + } + Py_DECREF(key); + return descriptor; +} + +/* + For backward compatibility only +*/ +#define SWIG_POINTER_EXCEPTION 0 +#define SWIG_arg_fail(arg) SWIG_Python_ArgFail(arg) +#define SWIG_MustGetPtr(p, type, argnum, flags) SWIG_Python_MustGetPtr(p, type, argnum, flags) + +SWIGRUNTIME int +SWIG_Python_AddErrMesg(const char* mesg, int infront) +{ + if (PyErr_Occurred()) { + PyObject *type = 0; + PyObject *value = 0; + PyObject *traceback = 0; + PyErr_Fetch(&type, &value, &traceback); + if (value) { + PyObject *old_str = PyObject_Str(value); + PyObject *bytes = NULL; + const char *tmp = SWIG_PyUnicode_AsUTF8AndSize(old_str, NULL, &bytes); + const char *errmesg = tmp ? tmp : "Invalid error message"; + Py_XINCREF(type); + PyErr_Clear(); + if (infront) { + PyErr_Format(type, "%s %s", mesg, errmesg); + } else { + PyErr_Format(type, "%s %s", errmesg, mesg); + } + Py_XDECREF(bytes); + Py_DECREF(old_str); + } + return 1; + } else { + return 0; + } +} + +SWIGRUNTIME int +SWIG_Python_ArgFail(int argnum) +{ + if (PyErr_Occurred()) { + /* add information about failing argument */ + char mesg[256]; + PyOS_snprintf(mesg, sizeof(mesg), "argument number %d:", argnum); + return SWIG_Python_AddErrMesg(mesg, 1); + } else { + return 0; + } +} + +SWIGRUNTIMEINLINE const char * +SwigPyObject_GetDesc(PyObject *self) +{ + SwigPyObject *v = (SwigPyObject *)self; + swig_type_info *ty = v ? v->ty : 0; + return ty ? ty->str : ""; +} + +SWIGRUNTIME void +SWIG_Python_TypeError(const char *type, PyObject *obj) +{ + if (type) { +#if defined(SWIG_COBJECT_TYPES) + if (obj && SwigPyObject_Check(obj)) { + const char *otype = (const char *) SwigPyObject_GetDesc(obj); + if (otype) { + PyErr_Format(PyExc_TypeError, "a '%s' is expected, 'SwigPyObject(%s)' is received", + type, otype); + return; + } + } else +#endif + { +#ifndef Py_LIMITED_API + /* tp_name is not accessible */ + const char *otype = (obj ? obj->ob_type->tp_name : 0); + if (otype) { + PyObject *str = PyObject_Str(obj); + PyObject *bytes = NULL; + const char *cstr = str ? SWIG_PyUnicode_AsUTF8AndSize(str, NULL, &bytes) : 0; + if (cstr) { + PyErr_Format(PyExc_TypeError, "a '%s' is expected, '%s(%s)' is received", + type, otype, cstr); + } else { + PyErr_Format(PyExc_TypeError, "a '%s' is expected, '%s' is received", + type, otype); + } + Py_XDECREF(bytes); + Py_XDECREF(str); + return; + } +#endif + } + PyErr_Format(PyExc_TypeError, "a '%s' is expected", type); + } else { + PyErr_Format(PyExc_TypeError, "unexpected type is received"); + } +} + + +/* Convert a pointer value, signal an exception on a type mismatch */ +SWIGRUNTIME void * +SWIG_Python_MustGetPtr(PyObject *obj, swig_type_info *ty, int SWIGUNUSEDPARM(argnum), int flags) { + void *result; + if (SWIG_Python_ConvertPtr(obj, &result, ty, flags) == -1) { + PyErr_Clear(); + } + return result; +} + +#ifdef SWIGPYTHON_BUILTIN +SWIGRUNTIME int +SWIG_Python_NonDynamicSetAttr(PyObject *obj, PyObject *name, PyObject *value) { + PyTypeObject *tp = obj->ob_type; + PyObject *descr; + PyObject *encoded_name; + descrsetfunc f; + int res = -1; + +# ifdef Py_USING_UNICODE + if (PyString_Check(name)) { + name = PyUnicode_Decode(PyString_AsString(name), PyString_Size(name), NULL, NULL); + if (!name) + return -1; + } else if (!PyUnicode_Check(name)) +# else + if (!PyString_Check(name)) +# endif + { + PyErr_Format(PyExc_TypeError, "attribute name must be string, not '%.200s'", name->ob_type->tp_name); + return -1; + } else { + Py_INCREF(name); + } + + if (!tp->tp_dict) { + if (PyType_Ready(tp) != 0) + goto done; + } + + descr = _PyType_Lookup(tp, name); + f = NULL; + if (descr != NULL) + f = descr->ob_type->tp_descr_set; + if (!f) { + if (PyString_Check(name)) { + encoded_name = name; + Py_INCREF(name); + } else { + encoded_name = PyUnicode_AsUTF8String(name); + if (!encoded_name) + goto done; + } + PyErr_Format(PyExc_AttributeError, "'%.100s' object has no attribute '%.200s'", tp->tp_name, PyString_AsString(encoded_name)); + Py_DECREF(encoded_name); + } else { + res = f(descr, obj, value); + } + + done: + Py_DECREF(name); + return res; +} +#endif + + +#ifdef __cplusplus +} +#endif + + + +#define SWIG_exception_fail(code, msg) do { SWIG_Error(code, msg); SWIG_fail; } while(0) + +#define SWIG_contract_assert(expr, msg) do { if (!(expr)) { SWIG_Error(SWIG_RuntimeError, msg); SWIG_fail; } } while (0) + + + + #define SWIG_exception(code, msg) do { SWIG_Error(code, msg); SWIG_fail;; } while(0) + +/* ----------------------------------------------------------------------------- + * director_common.swg + * + * This file contains support for director classes which is common between + * languages. + * ----------------------------------------------------------------------------- */ + +/* + Use -DSWIG_DIRECTOR_STATIC if you prefer to avoid the use of the + 'Swig' namespace. This could be useful for multi-modules projects. +*/ +#ifdef SWIG_DIRECTOR_STATIC +/* Force anonymous (static) namespace */ +#define Swig +#endif +/* ----------------------------------------------------------------------------- + * director.swg + * + * This file contains support for director classes so that Python proxy + * methods can be called from C++. + * ----------------------------------------------------------------------------- */ + +#ifndef SWIG_DIRECTOR_PYTHON_HEADER_ +#define SWIG_DIRECTOR_PYTHON_HEADER_ + +#include +#include +#include +#include +#include + +#if defined(SWIG_PYTHON_THREADS) +/* __THREAD__ is the old macro to activate some thread support */ +# if !defined(__THREAD__) +# define __THREAD__ 1 +# endif +#endif + +#ifdef __THREAD__ +#ifndef Py_LIMITED_API +# include "pythread.h" +#else +# if defined(_WIN32) +# include +# else +# include +# endif +#endif +#endif + +/* + Use -DSWIG_PYTHON_DIRECTOR_NO_VTABLE if you don't want to generate a 'virtual + table', and avoid multiple GetAttr calls to retrieve the python + methods. +*/ + +#ifndef SWIG_PYTHON_DIRECTOR_NO_VTABLE +#ifndef SWIG_PYTHON_DIRECTOR_VTABLE +#define SWIG_PYTHON_DIRECTOR_VTABLE +#endif +#endif + + + +/* + Use -DSWIG_DIRECTOR_NO_UEH if you prefer to avoid the use of the + Undefined Exception Handler provided by swig. +*/ +#ifndef SWIG_DIRECTOR_NO_UEH +#ifndef SWIG_DIRECTOR_UEH +#define SWIG_DIRECTOR_UEH +#endif +#endif + + +/* + Use -DSWIG_DIRECTOR_NORTTI if you prefer to avoid the use of the + native C++ RTTI and dynamic_cast<>. But be aware that directors + could stop working when using this option. +*/ +#ifdef SWIG_DIRECTOR_NORTTI +/* + When we don't use the native C++ RTTI, we implement a minimal one + only for Directors. +*/ +# ifndef SWIG_DIRECTOR_RTDIR +# define SWIG_DIRECTOR_RTDIR + +namespace Swig { + class Director; + SWIGINTERN std::map& get_rtdir_map() { + static std::map rtdir_map; + return rtdir_map; + } + + SWIGINTERNINLINE void set_rtdir(void *vptr, Director *rtdir) { + get_rtdir_map()[vptr] = rtdir; + } + + SWIGINTERNINLINE Director *get_rtdir(void *vptr) { + std::map::const_iterator pos = get_rtdir_map().find(vptr); + Director *rtdir = (pos != get_rtdir_map().end()) ? pos->second : 0; + return rtdir; + } +} +# endif /* SWIG_DIRECTOR_RTDIR */ + +# define SWIG_DIRECTOR_CAST(ARG) Swig::get_rtdir(static_cast(ARG)) +# define SWIG_DIRECTOR_RGTR(ARG1, ARG2) Swig::set_rtdir(static_cast(ARG1), ARG2) + +#else + +# define SWIG_DIRECTOR_CAST(ARG) dynamic_cast(ARG) +# define SWIG_DIRECTOR_RGTR(ARG1, ARG2) + +#endif /* SWIG_DIRECTOR_NORTTI */ + +extern "C" { + struct swig_type_info; +} + +namespace Swig { + + /* memory handler */ + struct GCItem { + virtual ~GCItem() {} + + virtual int get_own() const { + return 0; + } + }; + + struct GCItem_var { + GCItem_var(GCItem *item = 0) : _item(item) { + } + + GCItem_var& operator=(GCItem *item) { + GCItem *tmp = _item; + _item = item; + delete tmp; + return *this; + } + + ~GCItem_var() { + delete _item; + } + + GCItem * operator->() const { + return _item; + } + + private: + GCItem *_item; + }; + + struct GCItem_Object : GCItem { + GCItem_Object(int own) : _own(own) { + } + + virtual ~GCItem_Object() { + } + + int get_own() const { + return _own; + } + + private: + int _own; + }; + + template + struct GCItem_T : GCItem { + GCItem_T(Type *ptr) : _ptr(ptr) { + } + + virtual ~GCItem_T() { + delete _ptr; + } + + private: + Type *_ptr; + }; + + template + struct GCArray_T : GCItem { + GCArray_T(Type *ptr) : _ptr(ptr) { + } + + virtual ~GCArray_T() { + delete[] _ptr; + } + + private: + Type *_ptr; + }; + + /* base class for director exceptions */ + class DirectorException : public std::exception { + protected: + std::string swig_msg; + public: + DirectorException(PyObject *error, const char *hdr ="", const char *msg ="") : swig_msg(hdr) { + SWIG_PYTHON_THREAD_BEGIN_BLOCK; + if (msg[0]) { + swig_msg += " "; + swig_msg += msg; + } + if (!PyErr_Occurred()) { + PyErr_SetString(error, swig_msg.c_str()); + } + SWIG_PYTHON_THREAD_END_BLOCK; + } + + virtual ~DirectorException() throw() { + } + + /* Deprecated, use what() instead */ + const char *getMessage() const { + return what(); + } + + const char *what() const throw() { + return swig_msg.c_str(); + } + + static void raise(PyObject *error, const char *msg) { + throw DirectorException(error, msg); + } + + static void raise(const char *msg) { + raise(PyExc_RuntimeError, msg); + } + }; + + /* type mismatch in the return value from a python method call */ + class DirectorTypeMismatchException : public DirectorException { + public: + DirectorTypeMismatchException(PyObject *error, const char *msg="") + : DirectorException(error, "SWIG director type mismatch", msg) { + } + + DirectorTypeMismatchException(const char *msg="") + : DirectorException(PyExc_TypeError, "SWIG director type mismatch", msg) { + } + + static void raise(PyObject *error, const char *msg) { + throw DirectorTypeMismatchException(error, msg); + } + + static void raise(const char *msg) { + throw DirectorTypeMismatchException(msg); + } + }; + + /* any python exception that occurs during a director method call */ + class DirectorMethodException : public DirectorException { + public: + DirectorMethodException(const char *msg = "") + : DirectorException(PyExc_RuntimeError, "SWIG director method error.", msg) { + } + + static void raise(const char *msg) { + throw DirectorMethodException(msg); + } + }; + + /* attempt to call a pure virtual method via a director method */ + class DirectorPureVirtualException : public DirectorException { + public: + DirectorPureVirtualException(const char *msg = "") + : DirectorException(PyExc_RuntimeError, "SWIG director pure virtual method called", msg) { + } + + static void raise(const char *msg) { + throw DirectorPureVirtualException(msg); + } + }; + + +#ifdef __THREAD__ +#ifndef Py_LIMITED_API + class Mutex + { + public: + Mutex() { + mutex_ = PyThread_allocate_lock(); + } + + ~Mutex() { + PyThread_release_lock(mutex_); + } + + private: + void Lock() { + PyThread_acquire_lock(mutex_, WAIT_LOCK); + } + + void Unlock() { + PyThread_free_lock(mutex_); + } + + PyThread_type_lock mutex_; + + friend class Guard; + }; +#elif defined(_WIN32) + class Mutex : private CRITICAL_SECTION { + public: + Mutex() { + InitializeCriticalSection(this); + } + + ~Mutex() { + DeleteCriticalSection(this); + } + + private: + void Lock() { + EnterCriticalSection(this); + } + + void Unlock() { + LeaveCriticalSection(this); + } + + friend class Guard; + }; +#else + class Mutex { + public: + Mutex() { + pthread_mutex_init(&mutex_, NULL); + } + + ~Mutex() { + pthread_mutex_destroy(&mutex_); + } + + private: + void Lock() { + pthread_mutex_lock(&mutex_); + } + + void Unlock() { + pthread_mutex_unlock(&mutex_); + } + + friend class Guard; + + pthread_mutex_t mutex_; + }; +#endif + class Guard { + Mutex &mutex_; + + public: + Guard(Mutex & mutex) : mutex_(mutex) { + mutex_.Lock(); + } + + ~Guard() { + mutex_.Unlock(); + } + }; +# define SWIG_GUARD(mutex) Guard _guard(mutex) +#else +# define SWIG_GUARD(mutex) +#endif + + /* director base class */ + class Director { + private: + /* pointer to the wrapped python object */ + PyObject *swig_self; + /* flag indicating whether the object is owned by python or c++ */ + mutable bool swig_disown_flag; + + /* decrement the reference count of the wrapped python object */ + void swig_decref() const { + if (swig_disown_flag) { + SWIG_PYTHON_THREAD_BEGIN_BLOCK; + Py_DECREF(swig_self); + SWIG_PYTHON_THREAD_END_BLOCK; + } + } + + public: + /* wrap a python object. */ + Director(PyObject *self) : swig_self(self), swig_disown_flag(false) { + } + + /* discard our reference at destruction */ + virtual ~Director() { + swig_decref(); + } + + /* return a pointer to the wrapped python object */ + PyObject *swig_get_self() const { + return swig_self; + } + + /* acquire ownership of the wrapped python object (the sense of "disown" is from python) */ + void swig_disown() const { + if (!swig_disown_flag) { + swig_disown_flag=true; + swig_incref(); + } + } + + /* increase the reference count of the wrapped python object */ + void swig_incref() const { + if (swig_disown_flag) { + Py_INCREF(swig_self); + } + } + + /* methods to implement pseudo protected director members */ + virtual bool swig_get_inner(const char * /* swig_protected_method_name */) const { + return true; + } + + virtual void swig_set_inner(const char * /* swig_protected_method_name */, bool /* swig_val */) const { + } + + /* ownership management */ + private: + typedef std::map swig_ownership_map; + mutable swig_ownership_map swig_owner; +#ifdef __THREAD__ + static Mutex swig_mutex_own; +#endif + + public: + template + void swig_acquire_ownership_array(Type *vptr) const { + if (vptr) { + SWIG_GUARD(swig_mutex_own); + swig_owner[vptr] = new GCArray_T(vptr); + } + } + + template + void swig_acquire_ownership(Type *vptr) const { + if (vptr) { + SWIG_GUARD(swig_mutex_own); + swig_owner[vptr] = new GCItem_T(vptr); + } + } + + void swig_acquire_ownership_obj(void *vptr, int own) const { + if (vptr && own) { + SWIG_GUARD(swig_mutex_own); + swig_owner[vptr] = new GCItem_Object(own); + } + } + + int swig_release_ownership(void *vptr) const { + int own = 0; + if (vptr) { + SWIG_GUARD(swig_mutex_own); + swig_ownership_map::iterator iter = swig_owner.find(vptr); + if (iter != swig_owner.end()) { + own = iter->second->get_own(); + swig_owner.erase(iter); + } + } + return own; + } + + template + static PyObject *swig_pyobj_disown(PyObject *pyobj, PyObject *SWIGUNUSEDPARM(args)) { + SwigPyObject *sobj = (SwigPyObject *)pyobj; + sobj->own = 0; + Director *d = SWIG_DIRECTOR_CAST(reinterpret_cast(sobj->ptr)); + if (d) + d->swig_disown(); + return PyWeakref_NewProxy(pyobj, NULL); + } + }; + +#ifdef __THREAD__ + Mutex Director::swig_mutex_own; +#endif +} + +#endif + +/* -------- TYPES TABLE (BEGIN) -------- */ + +#define SWIGTYPE_p_ConstPtr swig_types[0] +#define SWIGTYPE_p_InputBuffer swig_types[1] +#define SWIGTYPE_p_OutputBuffer swig_types[2] +#define SWIGTYPE_p_PrevStdError swig_types[3] +#define SWIGTYPE_p_Ptr swig_types[4] +#define SWIGTYPE_p_UniqueConstPtr swig_types[5] +#define SWIGTYPE_p_UniquePtr swig_types[6] +#define SWIGTYPE_p_allocator_type swig_types[7] +#define SWIGTYPE_p_bcos__Error swig_types[8] +#define SWIGTYPE_p_bcos__bytesConstRef swig_types[9] +#define SWIGTYPE_p_char swig_types[10] +#define SWIGTYPE_p_difference_type swig_types[11] +#define SWIGTYPE_p_int swig_types[12] +#define SWIGTYPE_p_long_long swig_types[13] +#define SWIGTYPE_p_p_PyObject swig_types[14] +#define SWIGTYPE_p_ppc__front__ErrorCallback swig_types[15] +#define SWIGTYPE_p_ppc__front__FrontConfig swig_types[16] +#define SWIGTYPE_p_ppc__front__FrontConfigBuilder swig_types[17] +#define SWIGTYPE_p_ppc__front__GetPeersInfoHandler swig_types[18] +#define SWIGTYPE_p_ppc__front__IFront swig_types[19] +#define SWIGTYPE_p_ppc__front__IFrontBuilder swig_types[20] +#define SWIGTYPE_p_ppc__front__IFrontClient swig_types[21] +#define SWIGTYPE_p_ppc__front__IMessageHandler swig_types[22] +#define SWIGTYPE_p_ppc__front__INodeDiscovery swig_types[23] +#define SWIGTYPE_p_ppc__front__MessageDispatcherHandler swig_types[24] +#define SWIGTYPE_p_ppc__front__SendResponseHandler swig_types[25] +#define SWIGTYPE_p_ppc__gateway__IGateway__Ptr swig_types[26] +#define SWIGTYPE_p_ppc__protocol__EndPoint swig_types[27] +#define SWIGTYPE_p_ppc__protocol__GrpcConfig swig_types[28] +#define SWIGTYPE_p_ppc__protocol__GrpcServerConfig swig_types[29] +#define SWIGTYPE_p_ppc__protocol__INodeInfo swig_types[30] +#define SWIGTYPE_p_ppc__protocol__Message swig_types[31] +#define SWIGTYPE_p_ppc__protocol__MessageBuilder swig_types[32] +#define SWIGTYPE_p_ppc__protocol__MessageHeader swig_types[33] +#define SWIGTYPE_p_ppc__protocol__MessageHeaderBuilder swig_types[34] +#define SWIGTYPE_p_ppc__protocol__MessageOptionalHeader swig_types[35] +#define SWIGTYPE_p_ppc__protocol__MessageOptionalHeaderBuilder swig_types[36] +#define SWIGTYPE_p_ppc__protocol__MessagePayload swig_types[37] +#define SWIGTYPE_p_ppc__protocol__MessagePayloadBuilder swig_types[38] +#define SWIGTYPE_p_ppc__protocol__RouteType swig_types[39] +#define SWIGTYPE_p_ppc__sdk__Transport swig_types[40] +#define SWIGTYPE_p_ppc__sdk__TransportBuilder swig_types[41] +#define SWIGTYPE_p_short swig_types[42] +#define SWIGTYPE_p_signed_char swig_types[43] +#define SWIGTYPE_p_size_type swig_types[44] +#define SWIGTYPE_p_std__allocatorT_signed_char_t swig_types[45] +#define SWIGTYPE_p_std__allocatorT_std__shared_ptrT_ppc__protocol__INodeInfo_t_t swig_types[46] +#define SWIGTYPE_p_std__allocatorT_std__string_t swig_types[47] +#define SWIGTYPE_p_std__allocatorT_unsigned_char_t swig_types[48] +#define SWIGTYPE_p_std__exception swig_types[49] +#define SWIGTYPE_p_std__functionT_void_fF_t swig_types[50] +#define SWIGTYPE_p_std__functionT_void_fstd__shared_ptrT_bcos__Error_tF_t swig_types[51] +#define SWIGTYPE_p_std__functionT_void_fstd__shared_ptrT_bcos__Error_t_std__shared_ptrT_ppc__protocol__Message_t_std__functionT_void_fstd__shared_ptrT_bcos__bytes_t_RRF_tF_t swig_types[52] +#define SWIGTYPE_p_std__functionT_void_fstd__shared_ptrT_bcos__bytes_t_RRF_t swig_types[53] +#define SWIGTYPE_p_std__functionT_void_fstd__shared_ptrT_ppc__protocol__Message_tF_t swig_types[54] +#define SWIGTYPE_p_std__invalid_argument swig_types[55] +#define SWIGTYPE_p_std__shared_ptrT_bcos__Error_t swig_types[56] +#define SWIGTYPE_p_std__shared_ptrT_bcos__bytes_t swig_types[57] +#define SWIGTYPE_p_std__shared_ptrT_ppc__front__ErrorCallback_t swig_types[58] +#define SWIGTYPE_p_std__shared_ptrT_ppc__front__FrontConfigBuilder_t swig_types[59] +#define SWIGTYPE_p_std__shared_ptrT_ppc__front__FrontConfig_t swig_types[60] +#define SWIGTYPE_p_std__shared_ptrT_ppc__front__GetPeersInfoHandler_t swig_types[61] +#define SWIGTYPE_p_std__shared_ptrT_ppc__front__IFrontClient_t swig_types[62] +#define SWIGTYPE_p_std__shared_ptrT_ppc__front__IFront_t swig_types[63] +#define SWIGTYPE_p_std__shared_ptrT_ppc__front__IMessageHandler_t swig_types[64] +#define SWIGTYPE_p_std__shared_ptrT_ppc__front__INodeDiscovery_t swig_types[65] +#define SWIGTYPE_p_std__shared_ptrT_ppc__front__MessageDispatcherHandler_t swig_types[66] +#define SWIGTYPE_p_std__shared_ptrT_ppc__gateway__IGateway_t swig_types[67] +#define SWIGTYPE_p_std__shared_ptrT_ppc__protocol__GrpcConfig_t swig_types[68] +#define SWIGTYPE_p_std__shared_ptrT_ppc__protocol__INodeInfo_t swig_types[69] +#define SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageBuilder_t swig_types[70] +#define SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageHeaderBuilder_t swig_types[71] +#define SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageHeader_t swig_types[72] +#define SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageOptionalHeaderBuilder_t swig_types[73] +#define SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageOptionalHeader_t swig_types[74] +#define SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessagePayloadBuilder_t swig_types[75] +#define SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessagePayload_t swig_types[76] +#define SWIGTYPE_p_std__shared_ptrT_ppc__protocol__Message_t swig_types[77] +#define SWIGTYPE_p_std__shared_ptrT_ppc__sdk__Transport_t swig_types[78] +#define SWIGTYPE_p_std__string swig_types[79] +#define SWIGTYPE_p_std__string_view swig_types[80] +#define SWIGTYPE_p_std__vectorT_int8_t_t swig_types[81] +#define SWIGTYPE_p_std__vectorT_std__shared_ptrT_ppc__protocol__INodeInfo_t_t swig_types[82] +#define SWIGTYPE_p_std__vectorT_std__string_t swig_types[83] +#define SWIGTYPE_p_std__vectorT_uint8_t_t swig_types[84] +#define SWIGTYPE_p_swig__SwigPyIterator swig_types[85] +#define SWIGTYPE_p_unsigned_char swig_types[86] +#define SWIGTYPE_p_unsigned_int swig_types[87] +#define SWIGTYPE_p_unsigned_long_long swig_types[88] +#define SWIGTYPE_p_unsigned_short swig_types[89] +#define SWIGTYPE_p_value_type swig_types[90] +static swig_type_info *swig_types[92]; +static swig_module_info swig_module = {swig_types, 91, 0, 0, 0, 0}; +#define SWIG_TypeQuery(name) SWIG_TypeQueryModule(&swig_module, &swig_module, name) +#define SWIG_MangledTypeQuery(name) SWIG_MangledTypeQueryModule(&swig_module, &swig_module, name) + +/* -------- TYPES TABLE (END) -------- */ + +#ifdef SWIG_TypeQuery +# undef SWIG_TypeQuery +#endif +#define SWIG_TypeQuery SWIG_Python_TypeQuery + +/*----------------------------------------------- + @(target):= _wedpr_python_transport.so + ------------------------------------------------*/ +#if PY_VERSION_HEX >= 0x03000000 +# define SWIG_init PyInit__wedpr_python_transport + +#else +# define SWIG_init init_wedpr_python_transport + +#endif +#define SWIG_name "_wedpr_python_transport" + +#ifdef __cplusplus +#include +/* SwigValueWrapper is described in swig.swg */ +template class SwigValueWrapper { + struct SwigSmartPointer { + T *ptr; + SwigSmartPointer(T *p) : ptr(p) { } + ~SwigSmartPointer() { delete ptr; } + SwigSmartPointer& operator=(SwigSmartPointer& rhs) { T* oldptr = ptr; ptr = 0; delete oldptr; ptr = rhs.ptr; rhs.ptr = 0; return *this; } + void reset(T *p) { T* oldptr = ptr; ptr = 0; delete oldptr; ptr = p; } + } pointer; + SwigValueWrapper& operator=(const SwigValueWrapper& rhs); + SwigValueWrapper(const SwigValueWrapper& rhs); +public: + SwigValueWrapper() : pointer(0) { } + SwigValueWrapper& operator=(const T& t) { SwigSmartPointer tmp(new T(t)); pointer = tmp; return *this; } +#if __cplusplus >=201103L + SwigValueWrapper& operator=(T&& t) { SwigSmartPointer tmp(new T(std::move(t))); pointer = tmp; return *this; } + operator T&&() const { return std::move(*pointer.ptr); } +#else + operator T&() const { return *pointer.ptr; } +#endif + T *operator&() const { return pointer.ptr; } + static void reset(SwigValueWrapper& t, T *p) { t.pointer.reset(p); } +}; + +/* + * SwigValueInit() is a generic initialisation solution as the following approach: + * + * T c_result = T(); + * + * doesn't compile for all types for example: + * + * unsigned int c_result = unsigned int(); + */ +template T SwigValueInit() { + return T(); +} + +#if __cplusplus >=201103L +# define SWIG_STD_MOVE(OBJ) std::move(OBJ) +#else +# define SWIG_STD_MOVE(OBJ) OBJ +#endif + +#endif + + +#define SWIG_as_voidptr(a) const_cast< void * >(static_cast< const void * >(a)) +#define SWIG_as_voidptrptr(a) ((void)SWIG_as_voidptr(*a),reinterpret_cast< void** >(a)) + + +#include + + +namespace swig { + class SwigPtr_PyObject { + protected: + PyObject *_obj; + + public: + SwigPtr_PyObject() :_obj(0) + { + } + + SwigPtr_PyObject(const SwigPtr_PyObject& item) : _obj(item._obj) + { + SWIG_PYTHON_THREAD_BEGIN_BLOCK; + Py_XINCREF(_obj); + SWIG_PYTHON_THREAD_END_BLOCK; + } + + SwigPtr_PyObject(PyObject *obj, bool initial_ref = true) :_obj(obj) + { + if (initial_ref) { + SWIG_PYTHON_THREAD_BEGIN_BLOCK; + Py_XINCREF(_obj); + SWIG_PYTHON_THREAD_END_BLOCK; + } + } + + SwigPtr_PyObject & operator=(const SwigPtr_PyObject& item) + { + SWIG_PYTHON_THREAD_BEGIN_BLOCK; + Py_XINCREF(item._obj); + Py_XDECREF(_obj); + _obj = item._obj; + SWIG_PYTHON_THREAD_END_BLOCK; + return *this; + } + + ~SwigPtr_PyObject() + { + SWIG_PYTHON_THREAD_BEGIN_BLOCK; + Py_XDECREF(_obj); + SWIG_PYTHON_THREAD_END_BLOCK; + } + + operator PyObject *() const + { + return _obj; + } + + PyObject *operator->() const + { + return _obj; + } + }; +} + + +namespace swig { + struct SwigVar_PyObject : SwigPtr_PyObject { + SwigVar_PyObject(PyObject* obj = 0) : SwigPtr_PyObject(obj, false) { } + + SwigVar_PyObject & operator = (PyObject* obj) + { + Py_XDECREF(_obj); + _obj = obj; + return *this; + } + }; +} + + +#include // Use the C99 official header + + +#include + +#if PY_VERSION_HEX >= 0x03020000 +# define SWIGPY_SLICEOBJECT PyObject +#else +# define SWIGPY_SLICEOBJECT PySliceObject +#endif + + +#include +#include + + +#if defined(__GNUC__) +# if __GNUC__ == 2 && __GNUC_MINOR <= 96 +# define SWIG_STD_NOMODERN_STL +# endif +#endif + + +#include + + +#include + + +namespace swig { + struct stop_iteration { + }; + + struct SwigPyIterator { + private: + SwigPtr_PyObject _seq; + + protected: + SwigPyIterator(PyObject *seq) : _seq(seq) + { + } + + public: + virtual ~SwigPyIterator() {} + + // Access iterator method, required by Python + virtual PyObject *value() const = 0; + + // Forward iterator method, required by Python + virtual SwigPyIterator *incr(size_t n = 1) = 0; + + // Backward iterator method, very common in C++, but not required in Python + virtual SwigPyIterator *decr(size_t /*n*/ = 1) + { + throw stop_iteration(); + } + + // Random access iterator methods, but not required in Python + virtual ptrdiff_t distance(const SwigPyIterator &/*x*/) const + { + throw std::invalid_argument("operation not supported"); + } + + virtual bool equal (const SwigPyIterator &/*x*/) const + { + throw std::invalid_argument("operation not supported"); + } + + // C++ common/needed methods + virtual SwigPyIterator *copy() const = 0; + + PyObject *next() + { + SWIG_PYTHON_THREAD_BEGIN_BLOCK; // disable threads + PyObject *obj = value(); + incr(); + SWIG_PYTHON_THREAD_END_BLOCK; // re-enable threads + return obj; + } + + /* Make an alias for Python 3.x */ + PyObject *__next__() + { + return next(); + } + + PyObject *previous() + { + SWIG_PYTHON_THREAD_BEGIN_BLOCK; // disable threads + decr(); + PyObject *obj = value(); + SWIG_PYTHON_THREAD_END_BLOCK; // re-enable threads + return obj; + } + + SwigPyIterator *advance(ptrdiff_t n) + { + return (n > 0) ? incr(n) : decr(-n); + } + + bool operator == (const SwigPyIterator& x) const + { + return equal(x); + } + + bool operator != (const SwigPyIterator& x) const + { + return ! operator==(x); + } + + SwigPyIterator& operator += (ptrdiff_t n) + { + return *advance(n); + } + + SwigPyIterator& operator -= (ptrdiff_t n) + { + return *advance(-n); + } + + SwigPyIterator* operator + (ptrdiff_t n) const + { + return copy()->advance(n); + } + + SwigPyIterator* operator - (ptrdiff_t n) const + { + return copy()->advance(-n); + } + + ptrdiff_t operator - (const SwigPyIterator& x) const + { + return x.distance(*this); + } + + static swig_type_info* descriptor() { + static int init = 0; + static swig_type_info* desc = 0; + if (!init) { + desc = SWIG_TypeQuery("swig::SwigPyIterator *"); + init = 1; + } + return desc; + } + }; + +#if defined(SWIGPYTHON_BUILTIN) + inline PyObject* make_output_iterator_builtin (PyObject *pyself) + { + Py_INCREF(pyself); + return pyself; + } +#endif +} + + +SWIGINTERN int +SWIG_AsVal_double (PyObject *obj, double *val) +{ + int res = SWIG_TypeError; + if (PyFloat_Check(obj)) { + if (val) *val = PyFloat_AsDouble(obj); + return SWIG_OK; +#if PY_VERSION_HEX < 0x03000000 + } else if (PyInt_Check(obj)) { + if (val) *val = (double) PyInt_AsLong(obj); + return SWIG_OK; +#endif + } else if (PyLong_Check(obj)) { + double v = PyLong_AsDouble(obj); + if (!PyErr_Occurred()) { + if (val) *val = v; + return SWIG_OK; + } else { + PyErr_Clear(); + } + } +#ifdef SWIG_PYTHON_CAST_MODE + { + int dispatch = 0; + double d = PyFloat_AsDouble(obj); + if (!PyErr_Occurred()) { + if (val) *val = d; + return SWIG_AddCast(SWIG_OK); + } else { + PyErr_Clear(); + } + if (!dispatch) { + long v = PyLong_AsLong(obj); + if (!PyErr_Occurred()) { + if (val) *val = v; + return SWIG_AddCast(SWIG_AddCast(SWIG_OK)); + } else { + PyErr_Clear(); + } + } + } +#endif + return res; +} + + +#include + + +#include + + +SWIGINTERNINLINE int +SWIG_CanCastAsInteger(double *d, double min, double max) { + double x = *d; + if ((min <= x && x <= max)) { + double fx, cx, rd; + errno = 0; + fx = floor(x); + cx = ceil(x); + rd = ((x - fx) < 0.5) ? fx : cx; /* simple rint */ + if ((errno == EDOM) || (errno == ERANGE)) { + errno = 0; + } else { + double summ, reps, diff; + if (rd < x) { + diff = x - rd; + } else if (rd > x) { + diff = rd - x; + } else { + return 1; + } + summ = rd + x; + reps = diff/summ; + if (reps < 8*DBL_EPSILON) { + *d = rd; + return 1; + } + } + } + return 0; +} + + +SWIGINTERN int +SWIG_AsVal_unsigned_SS_long (PyObject *obj, unsigned long *val) +{ +#if PY_VERSION_HEX < 0x03000000 + if (PyInt_Check(obj)) { + long v = PyInt_AsLong(obj); + if (v >= 0) { + if (val) *val = v; + return SWIG_OK; + } else { + return SWIG_OverflowError; + } + } else +#endif + if (PyLong_Check(obj)) { + unsigned long v = PyLong_AsUnsignedLong(obj); + if (!PyErr_Occurred()) { + if (val) *val = v; + return SWIG_OK; + } else { + PyErr_Clear(); + return SWIG_OverflowError; + } + } +#ifdef SWIG_PYTHON_CAST_MODE + { + int dispatch = 0; + unsigned long v = PyLong_AsUnsignedLong(obj); + if (!PyErr_Occurred()) { + if (val) *val = v; + return SWIG_AddCast(SWIG_OK); + } else { + PyErr_Clear(); + } + if (!dispatch) { + double d; + int res = SWIG_AddCast(SWIG_AsVal_double (obj,&d)); + // Largest double not larger than ULONG_MAX (not portably calculated easily) + // Note that double(ULONG_MAX) is stored in a double rounded up by one (for 64-bit unsigned long) + // 0xfffffffffffff800ULL == (uint64_t)std::nextafter(double(__uint128_t(ULONG_MAX)+1), double(0)) + const double ulong_max = sizeof(unsigned long) == 8 ? 0xfffffffffffff800ULL : ULONG_MAX; + if (SWIG_IsOK(res) && SWIG_CanCastAsInteger(&d, 0, ulong_max)) { + if (val) *val = (unsigned long)(d); + return res; + } + } + } +#endif + return SWIG_TypeError; +} + + +#include +#if !defined(SWIG_NO_LLONG_MAX) +# if !defined(LLONG_MAX) && defined(__GNUC__) && defined (__LONG_LONG_MAX__) +# define LLONG_MAX __LONG_LONG_MAX__ +# define LLONG_MIN (-LLONG_MAX - 1LL) +# define ULLONG_MAX (LLONG_MAX * 2ULL + 1ULL) +# endif +#endif + + +#if defined(LLONG_MAX) && !defined(SWIG_LONG_LONG_AVAILABLE) +# define SWIG_LONG_LONG_AVAILABLE +#endif + + +#ifdef SWIG_LONG_LONG_AVAILABLE +SWIGINTERN int +SWIG_AsVal_unsigned_SS_long_SS_long (PyObject *obj, unsigned long long *val) +{ + int res = SWIG_TypeError; + if (PyLong_Check(obj)) { + unsigned long long v = PyLong_AsUnsignedLongLong(obj); + if (!PyErr_Occurred()) { + if (val) *val = v; + return SWIG_OK; + } else { + PyErr_Clear(); + res = SWIG_OverflowError; + } + } else { + unsigned long v; + res = SWIG_AsVal_unsigned_SS_long (obj,&v); + if (SWIG_IsOK(res)) { + if (val) *val = v; + return res; + } + } +#ifdef SWIG_PYTHON_CAST_MODE + { + const double mant_max = 1LL << DBL_MANT_DIG; + double d; + res = SWIG_AsVal_double (obj,&d); + if (SWIG_IsOK(res) && !SWIG_CanCastAsInteger(&d, 0, mant_max)) + return SWIG_OverflowError; + if (SWIG_IsOK(res) && SWIG_CanCastAsInteger(&d, 0, mant_max)) { + if (val) *val = (unsigned long long)(d); + return SWIG_AddCast(res); + } + res = SWIG_TypeError; + } +#endif + return res; +} +#endif + + +SWIGINTERNINLINE int +SWIG_AsVal_size_t (PyObject * obj, size_t *val) +{ + int res = SWIG_TypeError; +#ifdef SWIG_LONG_LONG_AVAILABLE + if (sizeof(size_t) <= sizeof(unsigned long)) { +#endif + unsigned long v; + res = SWIG_AsVal_unsigned_SS_long (obj, val ? &v : 0); + if (SWIG_IsOK(res) && val) *val = static_cast< size_t >(v); +#ifdef SWIG_LONG_LONG_AVAILABLE + } else if (sizeof(size_t) <= sizeof(unsigned long long)) { + unsigned long long v; + res = SWIG_AsVal_unsigned_SS_long_SS_long (obj, val ? &v : 0); + if (SWIG_IsOK(res) && val) *val = static_cast< size_t >(v); + } +#endif + return res; +} + + + #define SWIG_From_long PyInt_FromLong + + +#ifdef SWIG_LONG_LONG_AVAILABLE +SWIGINTERNINLINE PyObject* +SWIG_From_long_SS_long (long long value) +{ + return ((value < LONG_MIN) || (value > LONG_MAX)) ? + PyLong_FromLongLong(value) : PyInt_FromLong(static_cast< long >(value)); +} +#endif + + +SWIGINTERNINLINE PyObject * +SWIG_From_ptrdiff_t (ptrdiff_t value) +{ +#ifdef SWIG_LONG_LONG_AVAILABLE + if (sizeof(ptrdiff_t) <= sizeof(long)) { +#endif + return SWIG_From_long (static_cast< long >(value)); +#ifdef SWIG_LONG_LONG_AVAILABLE + } else { + /* assume sizeof(ptrdiff_t) <= sizeof(long long) */ + return SWIG_From_long_SS_long (static_cast< long long >(value)); + } +#endif +} + + +SWIGINTERNINLINE PyObject* + SWIG_From_bool (bool value) +{ + return PyBool_FromLong(value ? 1 : 0); +} + + +SWIGINTERN int +SWIG_AsVal_long (PyObject *obj, long* val) +{ +#if PY_VERSION_HEX < 0x03000000 + if (PyInt_Check(obj)) { + if (val) *val = PyInt_AsLong(obj); + return SWIG_OK; + } else +#endif + if (PyLong_Check(obj)) { + long v = PyLong_AsLong(obj); + if (!PyErr_Occurred()) { + if (val) *val = v; + return SWIG_OK; + } else { + PyErr_Clear(); + return SWIG_OverflowError; + } + } +#ifdef SWIG_PYTHON_CAST_MODE + { + int dispatch = 0; + long v = PyInt_AsLong(obj); + if (!PyErr_Occurred()) { + if (val) *val = v; + return SWIG_AddCast(SWIG_OK); + } else { + PyErr_Clear(); + } + if (!dispatch) { + double d; + int res = SWIG_AddCast(SWIG_AsVal_double (obj,&d)); + // Largest double not larger than LONG_MAX (not portably calculated easily) + // Note that double(LONG_MAX) is stored in a double rounded up by one (for 64-bit long) + // 0x7ffffffffffffc00LL == (int64_t)std::nextafter(double(__uint128_t(LONG_MAX)+1), double(0)) + const double long_max = sizeof(long) == 8 ? 0x7ffffffffffffc00LL : LONG_MAX; + // No equivalent needed for 64-bit double(LONG_MIN) is exactly LONG_MIN + if (SWIG_IsOK(res) && SWIG_CanCastAsInteger(&d, LONG_MIN, long_max)) { + if (val) *val = (long)(d); + return res; + } + } + } +#endif + return SWIG_TypeError; +} + + +#ifdef SWIG_LONG_LONG_AVAILABLE +SWIGINTERN int +SWIG_AsVal_long_SS_long (PyObject *obj, long long *val) +{ + int res = SWIG_TypeError; + if (PyLong_Check(obj)) { + long long v = PyLong_AsLongLong(obj); + if (!PyErr_Occurred()) { + if (val) *val = v; + return SWIG_OK; + } else { + PyErr_Clear(); + res = SWIG_OverflowError; + } + } else { + long v; + res = SWIG_AsVal_long (obj,&v); + if (SWIG_IsOK(res)) { + if (val) *val = v; + return res; + } + } +#ifdef SWIG_PYTHON_CAST_MODE + { + const double mant_max = 1LL << DBL_MANT_DIG; + const double mant_min = -mant_max; + double d; + res = SWIG_AsVal_double (obj,&d); + if (SWIG_IsOK(res) && !SWIG_CanCastAsInteger(&d, mant_min, mant_max)) + return SWIG_OverflowError; + if (SWIG_IsOK(res) && SWIG_CanCastAsInteger(&d, mant_min, mant_max)) { + if (val) *val = (long long)(d); + return SWIG_AddCast(res); + } + res = SWIG_TypeError; + } +#endif + return res; +} +#endif + + +SWIGINTERNINLINE int +SWIG_AsVal_ptrdiff_t (PyObject * obj, ptrdiff_t *val) +{ + int res = SWIG_TypeError; +#ifdef SWIG_LONG_LONG_AVAILABLE + if (sizeof(ptrdiff_t) <= sizeof(long)) { +#endif + long v; + res = SWIG_AsVal_long (obj, val ? &v : 0); + if (SWIG_IsOK(res) && val) *val = static_cast< ptrdiff_t >(v); +#ifdef SWIG_LONG_LONG_AVAILABLE + } else if (sizeof(ptrdiff_t) <= sizeof(long long)) { + long long v; + res = SWIG_AsVal_long_SS_long (obj, val ? &v : 0); + if (SWIG_IsOK(res) && val) *val = static_cast< ptrdiff_t >(v); + } +#endif + return res; +} + + +#include + + +#include + + +SWIGINTERNINLINE PyObject* + SWIG_From_int (int value) +{ + return PyInt_FromLong((long) value); +} + + +#define SWIG_FILE_WITH_INIT +#include +#include +#include +#include +#include +#include "wedpr-transport/sdk/src/TransportBuilder.h" +#include "wedpr-transport/sdk/src/Transport.h" +#include "ppc-framework/libwrapper/Buffer.h" +#include "ppc-framework/front/IFront.h" +#include "ppc-framework/protocol/INodeInfo.h" +#include "ppc-framework/front/INodeDiscovery.h" +#include "ppc-framework/protocol/RouteType.h" +#include "ppc-framework/front/FrontConfig.h" +#include "ppc-framework/protocol/GrpcConfig.h" +#include +#include "ppc-framework/protocol/EndPoint.h" +#include "ppc-framework/protocol/Message.h" +#include "ppc-framework/protocol/MessagePayload.h" + + +namespace swig { + template + struct noconst_traits { + typedef Type noconst_type; + }; + + template + struct noconst_traits { + typedef Type noconst_type; + }; + + /* + type categories + */ + struct pointer_category { }; + struct value_category { }; + + /* + General traits that provides type_name and type_info + */ + template struct traits { }; + + template + inline const char* type_name() { + return traits::noconst_type >::type_name(); + } + + template struct traits_info { + static swig_type_info *type_query(std::string name) { + name += " *"; + return SWIG_TypeQuery(name.c_str()); + } + static swig_type_info *type_info() { + static swig_type_info *info = type_query(type_name()); + return info; + } + }; + + /* + Partial specialization for pointers (traits_info) + */ + template struct traits_info { + static swig_type_info *type_query(std::string name) { + name += " *"; + return SWIG_TypeQuery(name.c_str()); + } + static swig_type_info *type_info() { + static swig_type_info *info = type_query(type_name()); + return info; + } + }; + + template + inline swig_type_info *type_info() { + return traits_info::type_info(); + } + + /* + Partial specialization for pointers (traits) + */ + template struct traits { + typedef pointer_category category; + static std::string make_ptr_name(const char* name) { + std::string ptrname = name; + ptrname += " *"; + return ptrname; + } + static const char* type_name() { + static std::string name = make_ptr_name(swig::type_name()); + return name.c_str(); + } + }; + + template + struct traits_as { }; + + template + struct traits_check { }; + +} + + +namespace swig { + /* + Traits that provides the from method + */ + template struct traits_from_ptr { + static PyObject *from(Type *val, int owner = 0) { + return SWIG_InternalNewPointerObj(val, type_info(), owner); + } + }; + + template struct traits_from { + static PyObject *from(const Type& val) { + return traits_from_ptr::from(new Type(val), 1); + } + }; + + template struct traits_from { + static PyObject *from(Type* val) { + return traits_from_ptr::from(val, 0); + } + }; + + template struct traits_from { + static PyObject *from(const Type* val) { + return traits_from_ptr::from(const_cast(val), 0); + } + }; + + + template + inline PyObject *from(const Type& val) { + return traits_from::from(val); + } + + template + inline PyObject *from_ptr(Type* val, int owner) { + return traits_from_ptr::from(val, owner); + } + + /* + Traits that provides the asval/as/check method + */ + template + struct traits_asptr { + static int asptr(PyObject *obj, Type **val) { + int res = SWIG_ERROR; + swig_type_info *descriptor = type_info(); + if (val) { + Type *p = 0; + int newmem = 0; + res = descriptor ? SWIG_ConvertPtrAndOwn(obj, (void **)&p, descriptor, 0, &newmem) : SWIG_ERROR; + if (SWIG_IsOK(res)) { + if (newmem & SWIG_CAST_NEW_MEMORY) { + res |= SWIG_NEWOBJMASK; + } + *val = p; + } + } else { + res = descriptor ? SWIG_ConvertPtr(obj, 0, descriptor, 0) : SWIG_ERROR; + } + return res; + } + }; + + template + inline int asptr(PyObject *obj, Type **vptr) { + return traits_asptr::asptr(obj, vptr); + } + + template + struct traits_asval { + static int asval(PyObject *obj, Type *val) { + if (val) { + Type *p = 0; + int res = traits_asptr::asptr(obj, &p); + if (!SWIG_IsOK(res)) return res; + if (p) { + typedef typename noconst_traits::noconst_type noconst_type; + *(const_cast(val)) = *p; + if (SWIG_IsNewObj(res)){ + delete p; + res = SWIG_DelNewMask(res); + } + return res; + } else { + return SWIG_ERROR; + } + } else { + return traits_asptr::asptr(obj, (Type **)(0)); + } + } + }; + + template struct traits_asval { + static int asval(PyObject *obj, Type **val) { + if (val) { + typedef typename noconst_traits::noconst_type noconst_type; + noconst_type *p = 0; + int res = traits_asptr::asptr(obj, &p); + if (SWIG_IsOK(res)) { + *(const_cast(val)) = p; + } + return res; + } else { + return traits_asptr::asptr(obj, (Type **)(0)); + } + } + }; + + template + inline int asval(PyObject *obj, Type *val) { + return traits_asval::asval(obj, val); + } + + template + struct traits_as { + static Type as(PyObject *obj) { + Type v; + int res = asval(obj, &v); + if (!obj || !SWIG_IsOK(res)) { + if (!PyErr_Occurred()) { + ::SWIG_Error(SWIG_TypeError, swig::type_name()); + } + throw std::invalid_argument("bad type"); + } + return v; + } + }; + + template + struct traits_as { + static Type as(PyObject *obj) { + Type *v = 0; + int res = (obj ? traits_asptr::asptr(obj, &v) : SWIG_ERROR); + if (SWIG_IsOK(res) && v) { + if (SWIG_IsNewObj(res)) { + Type r(*v); + delete v; + return r; + } else { + return *v; + } + } else { + if (!PyErr_Occurred()) { + SWIG_Error(SWIG_TypeError, swig::type_name()); + } + throw std::invalid_argument("bad type"); + } + } + }; + + template + struct traits_as { + static Type* as(PyObject *obj) { + Type *v = 0; + int res = (obj ? traits_asptr::asptr(obj, &v) : SWIG_ERROR); + if (SWIG_IsOK(res)) { + return v; + } else { + if (!PyErr_Occurred()) { + SWIG_Error(SWIG_TypeError, swig::type_name()); + } + throw std::invalid_argument("bad type"); + } + } + }; + + template + inline Type as(PyObject *obj) { + return traits_as::category>::as(obj); + } + + template + struct traits_check { + static bool check(PyObject *obj) { + int res = obj ? asval(obj, (Type *)(0)) : SWIG_ERROR; + return SWIG_IsOK(res) ? true : false; + } + }; + + template + struct traits_check { + static bool check(PyObject *obj) { + int res = obj ? asptr(obj, (Type **)(0)) : SWIG_ERROR; + return SWIG_IsOK(res) ? true : false; + } + }; + + template + inline bool check(PyObject *obj) { + return traits_check::category>::check(obj); + } +} + + +#if defined(__SUNPRO_CC) && defined(_RWSTD_VER) +# if !defined(SWIG_NO_STD_NOITERATOR_TRAITS_STL) +# define SWIG_STD_NOITERATOR_TRAITS_STL +# endif +#endif + +#if !defined(SWIG_STD_NOITERATOR_TRAITS_STL) +#include +#else +namespace std { + template + struct iterator_traits { + typedef ptrdiff_t difference_type; + typedef typename Iterator::value_type value_type; + }; + + template + struct iterator_traits<__reverse_bi_iterator > { + typedef Distance difference_type; + typedef T value_type; + }; + + template + struct iterator_traits { + typedef T value_type; + typedef ptrdiff_t difference_type; + }; + + template + inline typename iterator_traits<_InputIterator>::difference_type + distance(_InputIterator __first, _InputIterator __last) + { + typename iterator_traits<_InputIterator>::difference_type __n = 0; + while (__first != __last) { + ++__first; ++__n; + } + return __n; + } +} +#endif + + +namespace swig { + template + class SwigPyIterator_T : public SwigPyIterator + { + public: + typedef OutIterator out_iterator; + typedef typename std::iterator_traits::value_type value_type; + typedef SwigPyIterator_T self_type; + + SwigPyIterator_T(out_iterator curr, PyObject *seq) + : SwigPyIterator(seq), current(curr) + { + } + + const out_iterator& get_current() const + { + return current; + } + + + bool equal (const SwigPyIterator &iter) const + { + const self_type *iters = dynamic_cast(&iter); + if (iters) { + return (current == iters->get_current()); + } else { + throw std::invalid_argument("bad iterator type"); + } + } + + ptrdiff_t distance(const SwigPyIterator &iter) const + { + const self_type *iters = dynamic_cast(&iter); + if (iters) { + return std::distance(current, iters->get_current()); + } else { + throw std::invalid_argument("bad iterator type"); + } + } + + protected: + out_iterator current; + }; + + template + struct from_oper + { + typedef const ValueType& argument_type; + typedef PyObject *result_type; + result_type operator()(argument_type v) const + { + return swig::from(v); + } + }; + + template::value_type, + typename FromOper = from_oper > + class SwigPyForwardIteratorOpen_T : public SwigPyIterator_T + { + public: + FromOper from; + typedef OutIterator out_iterator; + typedef ValueType value_type; + typedef SwigPyIterator_T base; + typedef SwigPyForwardIteratorOpen_T self_type; + + SwigPyForwardIteratorOpen_T(out_iterator curr, PyObject *seq) + : SwigPyIterator_T(curr, seq) + { + } + + PyObject *value() const { + return from(static_cast(*(base::current))); + } + + SwigPyIterator *copy() const + { + return new self_type(*this); + } + + SwigPyIterator *incr(size_t n = 1) + { + while (n--) { + ++base::current; + } + return this; + } + + }; + + template::value_type, + typename FromOper = from_oper > + class SwigPyIteratorOpen_T : public SwigPyForwardIteratorOpen_T + { + public: + FromOper from; + typedef OutIterator out_iterator; + typedef ValueType value_type; + typedef SwigPyIterator_T base; + typedef SwigPyIteratorOpen_T self_type; + + SwigPyIteratorOpen_T(out_iterator curr, PyObject *seq) + : SwigPyForwardIteratorOpen_T(curr, seq) + { + } + + SwigPyIterator *decr(size_t n = 1) + { + while (n--) { + --base::current; + } + return this; + } + }; + + template::value_type, + typename FromOper = from_oper > + class SwigPyForwardIteratorClosed_T : public SwigPyIterator_T + { + public: + FromOper from; + typedef OutIterator out_iterator; + typedef ValueType value_type; + typedef SwigPyIterator_T base; + typedef SwigPyForwardIteratorClosed_T self_type; + + SwigPyForwardIteratorClosed_T(out_iterator curr, out_iterator first, out_iterator last, PyObject *seq) + : SwigPyIterator_T(curr, seq), begin(first), end(last) + { + } + + PyObject *value() const { + if (base::current == end) { + throw stop_iteration(); + } else { + return from(static_cast(*(base::current))); + } + } + + SwigPyIterator *copy() const + { + return new self_type(*this); + } + + SwigPyIterator *incr(size_t n = 1) + { + while (n--) { + if (base::current == end) { + throw stop_iteration(); + } else { + ++base::current; + } + } + return this; + } + + protected: + out_iterator begin; + out_iterator end; + }; + + template::value_type, + typename FromOper = from_oper > + class SwigPyIteratorClosed_T : public SwigPyForwardIteratorClosed_T + { + public: + FromOper from; + typedef OutIterator out_iterator; + typedef ValueType value_type; + typedef SwigPyIterator_T base; + typedef SwigPyForwardIteratorClosed_T base0; + typedef SwigPyIteratorClosed_T self_type; + + SwigPyIteratorClosed_T(out_iterator curr, out_iterator first, out_iterator last, PyObject *seq) + : SwigPyForwardIteratorClosed_T(curr, first, last, seq) + { + } + + SwigPyIterator *decr(size_t n = 1) + { + while (n--) { + if (base::current == base0::begin) { + throw stop_iteration(); + } else { + --base::current; + } + } + return this; + } + }; + + + template + inline SwigPyIterator* + make_output_forward_iterator(const OutIter& current, const OutIter& begin,const OutIter& end, PyObject *seq = 0) + { + return new SwigPyForwardIteratorClosed_T(current, begin, end, seq); + } + + template + inline SwigPyIterator* + make_output_iterator(const OutIter& current, const OutIter& begin,const OutIter& end, PyObject *seq = 0) + { + return new SwigPyIteratorClosed_T(current, begin, end, seq); + } + + template + inline SwigPyIterator* + make_output_forward_iterator(const OutIter& current, PyObject *seq = 0) + { + return new SwigPyForwardIteratorOpen_T(current, seq); + } + + template + inline SwigPyIterator* + make_output_iterator(const OutIter& current, PyObject *seq = 0) + { + return new SwigPyIteratorOpen_T(current, seq); + } + +} + + +SWIGINTERN int +SWIG_AsVal_unsigned_SS_char (PyObject * obj, unsigned char *val) +{ + unsigned long v; + int res = SWIG_AsVal_unsigned_SS_long (obj, &v); + if (SWIG_IsOK(res)) { + if ((v > UCHAR_MAX)) { + return SWIG_OverflowError; + } else { + if (val) *val = static_cast< unsigned char >(v); + } + } + return res; +} + + +SWIGINTERNINLINE PyObject* +SWIG_From_unsigned_SS_long (unsigned long value) +{ + return (value > LONG_MAX) ? + PyLong_FromUnsignedLong(value) : PyInt_FromLong(static_cast< long >(value)); +} + + +SWIGINTERNINLINE PyObject * +SWIG_From_unsigned_SS_char (unsigned char value) +{ + return SWIG_From_unsigned_SS_long (value); +} + + +namespace swig { + template <> struct traits< unsigned char > { + typedef value_category category; + static const char* type_name() { return"unsigned char"; } + }; + template <> struct traits_asval< unsigned char > { + typedef unsigned char value_type; + static int asval(PyObject *obj, value_type *val) { + return SWIG_AsVal_unsigned_SS_char (obj, val); + } + }; + template <> struct traits_from< unsigned char > { + typedef unsigned char value_type; + static PyObject *from(const value_type& val) { + return SWIG_From_unsigned_SS_char (val); + } + }; +} + + +#include + +namespace std { + template <> + struct less + { + bool + operator()(PyObject * v, PyObject *w) const + { + bool res; + SWIG_PYTHON_THREAD_BEGIN_BLOCK; + res = PyObject_RichCompareBool(v, w, Py_LT) ? true : false; + /* This may fall into a case of inconsistent + eg. ObjA > ObjX > ObjB + but ObjA < ObjB + */ + if( PyErr_Occurred() && PyErr_ExceptionMatches(PyExc_TypeError) ) + { + /* Objects can't be compared, this mostly occurred in Python 3.0 */ + /* Compare their ptr directly for a workaround */ + res = (v < w); + PyErr_Clear(); + } + SWIG_PYTHON_THREAD_END_BLOCK; + return res; + } + }; + + template <> + struct less + { + bool + operator()(const swig::SwigPtr_PyObject& v, const swig::SwigPtr_PyObject& w) const + { + return std::less()(v, w); + } + }; + + template <> + struct less + { + bool + operator()(const swig::SwigVar_PyObject& v, const swig::SwigVar_PyObject& w) const + { + return std::less()(v, w); + } + }; + +} + +namespace swig { + template <> struct traits { + typedef value_category category; + static const char* type_name() { return "PyObject *"; } + }; + + template <> struct traits_asval { + typedef PyObject * value_type; + static int asval(PyObject *obj, value_type *val) { + if (val) *val = obj; + return SWIG_OK; + } + }; + + template <> + struct traits_check { + static bool check(PyObject *) { + return true; + } + }; + + template <> struct traits_from { + typedef PyObject * value_type; + static PyObject *from(const value_type& val) { + Py_XINCREF(val); + return val; + } + }; + +} + +namespace swig { + template + inline size_t + check_index(Difference i, size_t size, bool insert = false) { + if ( i < 0 ) { + if ((size_t) (-i) <= size) + return (size_t) (i + size); + } else if ( (size_t) i < size ) { + return (size_t) i; + } else if (insert && ((size_t) i == size)) { + return size; + } + throw std::out_of_range("index out of range"); + } + + template + void + slice_adjust(Difference i, Difference j, Py_ssize_t step, size_t size, Difference &ii, Difference &jj, bool insert = false) { + if (step == 0) { + throw std::invalid_argument("slice step cannot be zero"); + } else if (step > 0) { + // Required range: 0 <= i < size, 0 <= j < size, i <= j + if (i < 0) { + ii = 0; + } else if (i < (Difference)size) { + ii = i; + } else if (insert && (i >= (Difference)size)) { + ii = (Difference)size; + } + if (j < 0) { + jj = 0; + } else { + jj = (j < (Difference)size) ? j : (Difference)size; + } + if (jj < ii) + jj = ii; + } else { + // Required range: -1 <= i < size-1, -1 <= j < size-1, i >= j + if (i < -1) { + ii = -1; + } else if (i < (Difference) size) { + ii = i; + } else if (i >= (Difference)(size-1)) { + ii = (Difference)(size-1); + } + if (j < -1) { + jj = -1; + } else { + jj = (j < (Difference)size ) ? j : (Difference)(size-1); + } + if (ii < jj) + ii = jj; + } + } + + template + inline typename Sequence::iterator + getpos(Sequence* self, Difference i) { + typename Sequence::iterator pos = self->begin(); + std::advance(pos, check_index(i,self->size())); + return pos; + } + + template + inline typename Sequence::const_iterator + cgetpos(const Sequence* self, Difference i) { + typename Sequence::const_iterator pos = self->begin(); + std::advance(pos, check_index(i,self->size())); + return pos; + } + + template + inline void + erase(Sequence* seq, const typename Sequence::iterator& position) { + seq->erase(position); + } + + template + struct traits_reserve { + static void reserve(Sequence & /*seq*/, typename Sequence::size_type /*n*/) { + // This should be specialized for types that support reserve + } + }; + + template + inline Sequence* + getslice(const Sequence* self, Difference i, Difference j, Py_ssize_t step) { + typename Sequence::size_type size = self->size(); + Difference ii = 0; + Difference jj = 0; + swig::slice_adjust(i, j, step, size, ii, jj); + + if (step > 0) { + typename Sequence::const_iterator sb = self->begin(); + typename Sequence::const_iterator se = self->begin(); + std::advance(sb,ii); + std::advance(se,jj); + if (step == 1) { + return new Sequence(sb, se); + } else { + Sequence *sequence = new Sequence(); + swig::traits_reserve::reserve(*sequence, (jj - ii + step - 1) / step); + typename Sequence::const_iterator it = sb; + while (it!=se) { + sequence->push_back(*it); + for (Py_ssize_t c=0; c::reserve(*sequence, (ii - jj - step - 1) / -step); + typename Sequence::const_reverse_iterator sb = self->rbegin(); + typename Sequence::const_reverse_iterator se = self->rbegin(); + std::advance(sb,size-ii-1); + std::advance(se,size-jj-1); + typename Sequence::const_reverse_iterator it = sb; + while (it!=se) { + sequence->push_back(*it); + for (Py_ssize_t c=0; c<-step && it!=se; ++c) + it++; + } + return sequence; + } + } + + template + inline void + setslice(Sequence* self, Difference i, Difference j, Py_ssize_t step, const InputSeq& is = InputSeq()) { + typename Sequence::size_type size = self->size(); + Difference ii = 0; + Difference jj = 0; + swig::slice_adjust(i, j, step, size, ii, jj, true); + if (step > 0) { + if (step == 1) { + size_t ssize = jj - ii; + if (ssize <= is.size()) { + // expanding/staying the same size + swig::traits_reserve::reserve(*self, self->size() - ssize + is.size()); + typename Sequence::iterator sb = self->begin(); + typename InputSeq::const_iterator isit = is.begin(); + std::advance(sb,ii); + std::advance(isit, jj - ii); + self->insert(std::copy(is.begin(), isit, sb), isit, is.end()); + } else { + // shrinking + typename Sequence::iterator sb = self->begin(); + typename Sequence::iterator se = self->begin(); + std::advance(sb,ii); + std::advance(se,jj); + self->erase(sb,se); + sb = self->begin(); + std::advance(sb,ii); + self->insert(sb, is.begin(), is.end()); + } + } else { + size_t replacecount = (jj - ii + step - 1) / step; + if (is.size() != replacecount) { + char msg[1024]; + PyOS_snprintf(msg, sizeof(msg), "attempt to assign sequence of size %lu to extended slice of size %lu", (unsigned long)is.size(), (unsigned long)replacecount); + throw std::invalid_argument(msg); + } + typename Sequence::const_iterator isit = is.begin(); + typename Sequence::iterator it = self->begin(); + std::advance(it,ii); + for (size_t rc=0; rcend(); ++rc) { + *it++ = *isit++; + for (Py_ssize_t c=0; c<(step-1) && it != self->end(); ++c) + it++; + } + } + } else { + size_t replacecount = (ii - jj - step - 1) / -step; + if (is.size() != replacecount) { + char msg[1024]; + PyOS_snprintf(msg, sizeof(msg), "attempt to assign sequence of size %lu to extended slice of size %lu", (unsigned long)is.size(), (unsigned long)replacecount); + throw std::invalid_argument(msg); + } + typename Sequence::const_iterator isit = is.begin(); + typename Sequence::reverse_iterator it = self->rbegin(); + std::advance(it,size-ii-1); + for (size_t rc=0; rcrend(); ++rc) { + *it++ = *isit++; + for (Py_ssize_t c=0; c<(-step-1) && it != self->rend(); ++c) + it++; + } + } + } + + template + inline void + delslice(Sequence* self, Difference i, Difference j, Py_ssize_t step) { + typename Sequence::size_type size = self->size(); + Difference ii = 0; + Difference jj = 0; + swig::slice_adjust(i, j, step, size, ii, jj, true); + if (step > 0) { + typename Sequence::iterator sb = self->begin(); + std::advance(sb,ii); + if (step == 1) { + typename Sequence::iterator se = self->begin(); + std::advance(se,jj); + self->erase(sb,se); + } else { + typename Sequence::iterator it = sb; + size_t delcount = (jj - ii + step - 1) / step; + while (delcount) { + it = self->erase(it); + for (Py_ssize_t c=0; c<(step-1) && it != self->end(); ++c) + it++; + delcount--; + } + } + } else { + typename Sequence::reverse_iterator sb = self->rbegin(); + std::advance(sb,size-ii-1); + typename Sequence::reverse_iterator it = sb; + size_t delcount = (ii - jj - step - 1) / -step; + while (delcount) { + it = typename Sequence::reverse_iterator(self->erase((++it).base())); + for (Py_ssize_t c=0; c<(-step-1) && it != self->rend(); ++c) + it++; + delcount--; + } + } + } +} + + +namespace swig { + template + struct IteratorProtocol { + static void assign(PyObject *obj, Seq *seq) { + SwigVar_PyObject iter = PyObject_GetIter(obj); + if (iter) { + SwigVar_PyObject item = PyIter_Next(iter); + while (item) { + seq->insert(seq->end(), swig::as(item)); + item = PyIter_Next(iter); + } + } + } + + static bool check(PyObject *obj) { + bool ret = false; + SwigVar_PyObject iter = PyObject_GetIter(obj); + if (iter) { + SwigVar_PyObject item = PyIter_Next(iter); + ret = true; + while (item) { + ret = swig::check(item); + item = ret ? PyIter_Next(iter) : 0; + } + } + return ret; + } + }; + + template + struct traits_asptr_stdseq { + typedef Seq sequence; + typedef T value_type; + + static bool is_iterable(PyObject *obj) { + SwigVar_PyObject iter = PyObject_GetIter(obj); + PyErr_Clear(); + return iter != 0; + } + + static int asptr(PyObject *obj, sequence **seq) { + int ret = SWIG_ERROR; + if (obj == Py_None || SWIG_Python_GetSwigThis(obj)) { + sequence *p; + swig_type_info *descriptor = swig::type_info(); + if (descriptor && SWIG_IsOK(::SWIG_ConvertPtr(obj, (void **)&p, descriptor, 0))) { + if (seq) *seq = p; + return SWIG_OLDOBJ; + } + } else if (is_iterable(obj)) { + try { + if (seq) { + *seq = new sequence(); + IteratorProtocol::assign(obj, *seq); + if (!PyErr_Occurred()) + return SWIG_NEWOBJ; + } else { + return IteratorProtocol::check(obj) ? SWIG_OK : SWIG_ERROR; + } + } catch (std::exception& e) { + if (seq && !PyErr_Occurred()) + PyErr_SetString(PyExc_TypeError, e.what()); + } + if (seq) + delete *seq; + return SWIG_ERROR; + } + return ret; + } + }; + + template + struct traits_from_stdseq { + typedef Seq sequence; + typedef T value_type; + typedef typename Seq::size_type size_type; + typedef typename sequence::const_iterator const_iterator; + + static PyObject *from(const sequence& seq) { +#ifdef SWIG_PYTHON_EXTRA_NATIVE_CONTAINERS + swig_type_info *desc = swig::type_info(); + if (desc && desc->clientdata) { + return SWIG_InternalNewPointerObj(new sequence(seq), desc, SWIG_POINTER_OWN); + } +#endif + size_type size = seq.size(); + if (size <= (size_type)INT_MAX) { + PyObject *obj = PyTuple_New((Py_ssize_t)size); + Py_ssize_t i = 0; + for (const_iterator it = seq.begin(); it != seq.end(); ++it, ++i) { + PyTuple_SetItem(obj,i,swig::from(*it)); + } + return obj; + } else { + PyErr_SetString(PyExc_OverflowError,"sequence size not valid in python"); + return NULL; + } + } + }; +} + + + namespace swig { + template + struct traits_reserve > { + static void reserve(std::vector &seq, typename std::vector::size_type n) { + seq.reserve(n); + } + }; + + template + struct traits_asptr > { + static int asptr(PyObject *obj, std::vector **vec) { + return traits_asptr_stdseq >::asptr(obj, vec); + } + }; + + template + struct traits_from > { + static PyObject *from(const std::vector& vec) { + return traits_from_stdseq >::from(vec); + } + }; + } + + + namespace swig { + template <> struct traits > > { + typedef pointer_category category; + static const char* type_name() { + return "std::vector<" "unsigned char" "," "std::allocator< unsigned char >" " >"; + } + }; + } + +SWIGINTERN swig::SwigPyIterator *std_vector_Sl_uint8_t_Sg__iterator(std::vector< uint8_t > *self,PyObject **PYTHON_SELF){ + return swig::make_output_iterator(self->begin(), self->begin(), self->end(), *PYTHON_SELF); + } +SWIGINTERN bool std_vector_Sl_uint8_t_Sg____nonzero__(std::vector< uint8_t > const *self){ + return !(self->empty()); + } +SWIGINTERN bool std_vector_Sl_uint8_t_Sg____bool__(std::vector< uint8_t > const *self){ + return !(self->empty()); + } +SWIGINTERN std::vector< unsigned char >::size_type std_vector_Sl_uint8_t_Sg____len__(std::vector< uint8_t > const *self){ + return self->size(); + } + +#ifdef SWIG_LONG_LONG_AVAILABLE +SWIGINTERNINLINE PyObject* +SWIG_From_unsigned_SS_long_SS_long (unsigned long long value) +{ + return (value > LONG_MAX) ? + PyLong_FromUnsignedLongLong(value) : PyInt_FromLong(static_cast< long >(value)); +} +#endif + + +SWIGINTERNINLINE PyObject * +SWIG_From_size_t (size_t value) +{ +#ifdef SWIG_LONG_LONG_AVAILABLE + if (sizeof(size_t) <= sizeof(unsigned long)) { +#endif + return SWIG_From_unsigned_SS_long (static_cast< unsigned long >(value)); +#ifdef SWIG_LONG_LONG_AVAILABLE + } else { + /* assume sizeof(size_t) <= sizeof(unsigned long long) */ + return SWIG_From_unsigned_SS_long_SS_long (static_cast< unsigned long long >(value)); + } +#endif +} + +SWIGINTERN std::vector< unsigned char,std::allocator< unsigned char > > *std_vector_Sl_uint8_t_Sg____getslice__(std::vector< uint8_t > *self,std::vector< unsigned char >::difference_type i,std::vector< unsigned char >::difference_type j){ + return swig::getslice(self, i, j, 1); + } +SWIGINTERN void std_vector_Sl_uint8_t_Sg____setslice____SWIG_0(std::vector< uint8_t > *self,std::vector< unsigned char >::difference_type i,std::vector< unsigned char >::difference_type j){ + swig::setslice(self, i, j, 1, std::vector< unsigned char,std::allocator< unsigned char > >()); + } +SWIGINTERN void std_vector_Sl_uint8_t_Sg____setslice____SWIG_1(std::vector< uint8_t > *self,std::vector< unsigned char >::difference_type i,std::vector< unsigned char >::difference_type j,std::vector< unsigned char,std::allocator< unsigned char > > const &v){ + swig::setslice(self, i, j, 1, v); + } +SWIGINTERN void std_vector_Sl_uint8_t_Sg____delslice__(std::vector< uint8_t > *self,std::vector< unsigned char >::difference_type i,std::vector< unsigned char >::difference_type j){ + swig::delslice(self, i, j, 1); + } +SWIGINTERN void std_vector_Sl_uint8_t_Sg____delitem____SWIG_0(std::vector< uint8_t > *self,std::vector< unsigned char >::difference_type i){ + swig::erase(self, swig::getpos(self, i)); + } +SWIGINTERN std::vector< unsigned char,std::allocator< unsigned char > > *std_vector_Sl_uint8_t_Sg____getitem____SWIG_0(std::vector< uint8_t > *self,SWIGPY_SLICEOBJECT *slice){ + Py_ssize_t i, j, step; + if( !PySlice_Check(slice) ) { + SWIG_Error(SWIG_TypeError, "Slice object expected."); + return NULL; + } + PySlice_GetIndices(slice, (Py_ssize_t)self->size(), &i, &j, &step); + std::vector< unsigned char,std::allocator< unsigned char > >::difference_type id = i; + std::vector< unsigned char,std::allocator< unsigned char > >::difference_type jd = j; + return swig::getslice(self, id, jd, step); + } +SWIGINTERN void std_vector_Sl_uint8_t_Sg____setitem____SWIG_0(std::vector< uint8_t > *self,SWIGPY_SLICEOBJECT *slice,std::vector< unsigned char,std::allocator< unsigned char > > const &v){ + Py_ssize_t i, j, step; + if( !PySlice_Check(slice) ) { + SWIG_Error(SWIG_TypeError, "Slice object expected."); + return; + } + PySlice_GetIndices(slice, (Py_ssize_t)self->size(), &i, &j, &step); + std::vector< unsigned char,std::allocator< unsigned char > >::difference_type id = i; + std::vector< unsigned char,std::allocator< unsigned char > >::difference_type jd = j; + swig::setslice(self, id, jd, step, v); + } +SWIGINTERN void std_vector_Sl_uint8_t_Sg____setitem____SWIG_1(std::vector< uint8_t > *self,SWIGPY_SLICEOBJECT *slice){ + Py_ssize_t i, j, step; + if( !PySlice_Check(slice) ) { + SWIG_Error(SWIG_TypeError, "Slice object expected."); + return; + } + PySlice_GetIndices(slice, (Py_ssize_t)self->size(), &i, &j, &step); + std::vector< unsigned char,std::allocator< unsigned char > >::difference_type id = i; + std::vector< unsigned char,std::allocator< unsigned char > >::difference_type jd = j; + swig::delslice(self, id, jd, step); + } +SWIGINTERN void std_vector_Sl_uint8_t_Sg____delitem____SWIG_1(std::vector< uint8_t > *self,SWIGPY_SLICEOBJECT *slice){ + Py_ssize_t i, j, step; + if( !PySlice_Check(slice) ) { + SWIG_Error(SWIG_TypeError, "Slice object expected."); + return; + } + PySlice_GetIndices(slice, (Py_ssize_t)self->size(), &i, &j, &step); + std::vector< unsigned char,std::allocator< unsigned char > >::difference_type id = i; + std::vector< unsigned char,std::allocator< unsigned char > >::difference_type jd = j; + swig::delslice(self, id, jd, step); + } +SWIGINTERN std::vector< unsigned char >::value_type const &std_vector_Sl_uint8_t_Sg____getitem____SWIG_1(std::vector< uint8_t > const *self,std::vector< unsigned char >::difference_type i){ + return *(swig::cgetpos(self, i)); + } + +namespace swig { + static PyObject* container_owner_attribute() { + static PyObject* attr = SWIG_Python_str_FromChar("__swig_container"); + return attr; + } + + template + struct container_owner { + // By default, do not add the back-reference (for value types) + // Specialization below will check the reference for pointer types. + static bool back_reference(PyObject* /*child*/, PyObject* /*owner*/) { + return false; + } + }; + + template <> + struct container_owner { + /* + * Call to add a back-reference to the owning object when returning a + * reference from a container. Will only set the reference if child + * is a SWIG wrapper object that does not own the pointer. + * + * returns whether the reference was set or not + */ + static bool back_reference(PyObject* child, PyObject* owner) { + SwigPyObject* swigThis = SWIG_Python_GetSwigThis(child); + if (swigThis && (swigThis->own & SWIG_POINTER_OWN) != SWIG_POINTER_OWN) { + return PyObject_SetAttr(child, container_owner_attribute(), owner) != -1; + } + return false; + } + }; +} + +SWIGINTERN void std_vector_Sl_uint8_t_Sg____setitem____SWIG_2(std::vector< uint8_t > *self,std::vector< unsigned char >::difference_type i,std::vector< unsigned char >::value_type const &x){ + *(swig::getpos(self,i)) = x; + } +SWIGINTERN std::vector< unsigned char >::value_type std_vector_Sl_uint8_t_Sg__pop(std::vector< uint8_t > *self){ + if (self->size() == 0) + throw std::out_of_range("pop from empty container"); + std::vector< unsigned char,std::allocator< unsigned char > >::value_type x = self->back(); + self->pop_back(); + return x; + } +SWIGINTERN void std_vector_Sl_uint8_t_Sg__append(std::vector< uint8_t > *self,std::vector< unsigned char >::value_type const &x){ + self->push_back(x); + } +SWIGINTERN std::vector< unsigned char >::iterator std_vector_Sl_uint8_t_Sg__erase__SWIG_0(std::vector< uint8_t > *self,std::vector< unsigned char >::iterator pos){ return self->erase(pos); } +SWIGINTERN std::vector< unsigned char >::iterator std_vector_Sl_uint8_t_Sg__erase__SWIG_1(std::vector< uint8_t > *self,std::vector< unsigned char >::iterator first,std::vector< unsigned char >::iterator last){ return self->erase(first, last); } +SWIGINTERN std::vector< unsigned char >::iterator std_vector_Sl_uint8_t_Sg__insert__SWIG_0(std::vector< uint8_t > *self,std::vector< unsigned char >::iterator pos,std::vector< unsigned char >::value_type const &x){ return self->insert(pos, x); } +SWIGINTERN void std_vector_Sl_uint8_t_Sg__insert__SWIG_1(std::vector< uint8_t > *self,std::vector< unsigned char >::iterator pos,std::vector< unsigned char >::size_type n,std::vector< unsigned char >::value_type const &x){ self->insert(pos, n, x); } + +SWIGINTERN int +SWIG_AsVal_signed_SS_char (PyObject * obj, signed char *val) +{ + long v; + int res = SWIG_AsVal_long (obj, &v); + if (SWIG_IsOK(res)) { + if ((v < SCHAR_MIN || v > SCHAR_MAX)) { + return SWIG_OverflowError; + } else { + if (val) *val = static_cast< signed char >(v); + } + } + return res; +} + + +SWIGINTERNINLINE PyObject * +SWIG_From_signed_SS_char (signed char value) +{ + return SWIG_From_long (value); +} + + +namespace swig { + template <> struct traits< signed char > { + typedef value_category category; + static const char* type_name() { return"signed char"; } + }; + template <> struct traits_asval< signed char > { + typedef signed char value_type; + static int asval(PyObject *obj, value_type *val) { + return SWIG_AsVal_signed_SS_char (obj, val); + } + }; + template <> struct traits_from< signed char > { + typedef signed char value_type; + static PyObject *from(const value_type& val) { + return SWIG_From_signed_SS_char (val); + } + }; +} + + + namespace swig { + template <> struct traits > > { + typedef pointer_category category; + static const char* type_name() { + return "std::vector<" "signed char" "," "std::allocator< signed char >" " >"; + } + }; + } + +SWIGINTERN swig::SwigPyIterator *std_vector_Sl_int8_t_Sg__iterator(std::vector< int8_t > *self,PyObject **PYTHON_SELF){ + return swig::make_output_iterator(self->begin(), self->begin(), self->end(), *PYTHON_SELF); + } +SWIGINTERN bool std_vector_Sl_int8_t_Sg____nonzero__(std::vector< int8_t > const *self){ + return !(self->empty()); + } +SWIGINTERN bool std_vector_Sl_int8_t_Sg____bool__(std::vector< int8_t > const *self){ + return !(self->empty()); + } +SWIGINTERN std::vector< signed char >::size_type std_vector_Sl_int8_t_Sg____len__(std::vector< int8_t > const *self){ + return self->size(); + } +SWIGINTERN std::vector< signed char,std::allocator< signed char > > *std_vector_Sl_int8_t_Sg____getslice__(std::vector< int8_t > *self,std::vector< signed char >::difference_type i,std::vector< signed char >::difference_type j){ + return swig::getslice(self, i, j, 1); + } +SWIGINTERN void std_vector_Sl_int8_t_Sg____setslice____SWIG_0(std::vector< int8_t > *self,std::vector< signed char >::difference_type i,std::vector< signed char >::difference_type j){ + swig::setslice(self, i, j, 1, std::vector< signed char,std::allocator< signed char > >()); + } +SWIGINTERN void std_vector_Sl_int8_t_Sg____setslice____SWIG_1(std::vector< int8_t > *self,std::vector< signed char >::difference_type i,std::vector< signed char >::difference_type j,std::vector< signed char,std::allocator< signed char > > const &v){ + swig::setslice(self, i, j, 1, v); + } +SWIGINTERN void std_vector_Sl_int8_t_Sg____delslice__(std::vector< int8_t > *self,std::vector< signed char >::difference_type i,std::vector< signed char >::difference_type j){ + swig::delslice(self, i, j, 1); + } +SWIGINTERN void std_vector_Sl_int8_t_Sg____delitem____SWIG_0(std::vector< int8_t > *self,std::vector< signed char >::difference_type i){ + swig::erase(self, swig::getpos(self, i)); + } +SWIGINTERN std::vector< signed char,std::allocator< signed char > > *std_vector_Sl_int8_t_Sg____getitem____SWIG_0(std::vector< int8_t > *self,SWIGPY_SLICEOBJECT *slice){ + Py_ssize_t i, j, step; + if( !PySlice_Check(slice) ) { + SWIG_Error(SWIG_TypeError, "Slice object expected."); + return NULL; + } + PySlice_GetIndices(slice, (Py_ssize_t)self->size(), &i, &j, &step); + std::vector< signed char,std::allocator< signed char > >::difference_type id = i; + std::vector< signed char,std::allocator< signed char > >::difference_type jd = j; + return swig::getslice(self, id, jd, step); + } +SWIGINTERN void std_vector_Sl_int8_t_Sg____setitem____SWIG_0(std::vector< int8_t > *self,SWIGPY_SLICEOBJECT *slice,std::vector< signed char,std::allocator< signed char > > const &v){ + Py_ssize_t i, j, step; + if( !PySlice_Check(slice) ) { + SWIG_Error(SWIG_TypeError, "Slice object expected."); + return; + } + PySlice_GetIndices(slice, (Py_ssize_t)self->size(), &i, &j, &step); + std::vector< signed char,std::allocator< signed char > >::difference_type id = i; + std::vector< signed char,std::allocator< signed char > >::difference_type jd = j; + swig::setslice(self, id, jd, step, v); + } +SWIGINTERN void std_vector_Sl_int8_t_Sg____setitem____SWIG_1(std::vector< int8_t > *self,SWIGPY_SLICEOBJECT *slice){ + Py_ssize_t i, j, step; + if( !PySlice_Check(slice) ) { + SWIG_Error(SWIG_TypeError, "Slice object expected."); + return; + } + PySlice_GetIndices(slice, (Py_ssize_t)self->size(), &i, &j, &step); + std::vector< signed char,std::allocator< signed char > >::difference_type id = i; + std::vector< signed char,std::allocator< signed char > >::difference_type jd = j; + swig::delslice(self, id, jd, step); + } +SWIGINTERN void std_vector_Sl_int8_t_Sg____delitem____SWIG_1(std::vector< int8_t > *self,SWIGPY_SLICEOBJECT *slice){ + Py_ssize_t i, j, step; + if( !PySlice_Check(slice) ) { + SWIG_Error(SWIG_TypeError, "Slice object expected."); + return; + } + PySlice_GetIndices(slice, (Py_ssize_t)self->size(), &i, &j, &step); + std::vector< signed char,std::allocator< signed char > >::difference_type id = i; + std::vector< signed char,std::allocator< signed char > >::difference_type jd = j; + swig::delslice(self, id, jd, step); + } +SWIGINTERN std::vector< signed char >::value_type const &std_vector_Sl_int8_t_Sg____getitem____SWIG_1(std::vector< int8_t > const *self,std::vector< signed char >::difference_type i){ + return *(swig::cgetpos(self, i)); + } +SWIGINTERN void std_vector_Sl_int8_t_Sg____setitem____SWIG_2(std::vector< int8_t > *self,std::vector< signed char >::difference_type i,std::vector< signed char >::value_type const &x){ + *(swig::getpos(self,i)) = x; + } +SWIGINTERN std::vector< signed char >::value_type std_vector_Sl_int8_t_Sg__pop(std::vector< int8_t > *self){ + if (self->size() == 0) + throw std::out_of_range("pop from empty container"); + std::vector< signed char,std::allocator< signed char > >::value_type x = self->back(); + self->pop_back(); + return x; + } +SWIGINTERN void std_vector_Sl_int8_t_Sg__append(std::vector< int8_t > *self,std::vector< signed char >::value_type const &x){ + self->push_back(x); + } +SWIGINTERN std::vector< signed char >::iterator std_vector_Sl_int8_t_Sg__erase__SWIG_0(std::vector< int8_t > *self,std::vector< signed char >::iterator pos){ return self->erase(pos); } +SWIGINTERN std::vector< signed char >::iterator std_vector_Sl_int8_t_Sg__erase__SWIG_1(std::vector< int8_t > *self,std::vector< signed char >::iterator first,std::vector< signed char >::iterator last){ return self->erase(first, last); } +SWIGINTERN std::vector< signed char >::iterator std_vector_Sl_int8_t_Sg__insert__SWIG_0(std::vector< int8_t > *self,std::vector< signed char >::iterator pos,std::vector< signed char >::value_type const &x){ return self->insert(pos, x); } +SWIGINTERN void std_vector_Sl_int8_t_Sg__insert__SWIG_1(std::vector< int8_t > *self,std::vector< signed char >::iterator pos,std::vector< signed char >::size_type n,std::vector< signed char >::value_type const &x){ self->insert(pos, n, x); } + +SWIGINTERN swig_type_info* +SWIG_pchar_descriptor(void) +{ + static int init = 0; + static swig_type_info* info = 0; + if (!init) { + info = SWIG_TypeQuery("_p_char"); + init = 1; + } + return info; +} + + +/* Return string from Python obj. NOTE: obj must remain in scope in order + to use the returned cptr (but only when alloc is set to SWIG_OLDOBJ) */ +SWIGINTERN int +SWIG_AsCharPtrAndSize(PyObject *obj, char **cptr, size_t *psize, int *alloc) +{ +#if PY_VERSION_HEX>=0x03000000 +#if defined(SWIG_PYTHON_STRICT_BYTE_CHAR) + if (PyBytes_Check(obj)) +#else + if (PyUnicode_Check(obj)) +#endif +#else + if (PyString_Check(obj)) +#endif + { + char *cstr; Py_ssize_t len; + PyObject *bytes = NULL; + int ret = SWIG_OK; + if (alloc) + *alloc = SWIG_OLDOBJ; +#if PY_VERSION_HEX>=0x03000000 && defined(SWIG_PYTHON_STRICT_BYTE_CHAR) + if (PyBytes_AsStringAndSize(obj, &cstr, &len) == -1) + return SWIG_TypeError; +#else + cstr = (char *)SWIG_PyUnicode_AsUTF8AndSize(obj, &len, &bytes); + if (!cstr) + return SWIG_TypeError; + /* The returned string is only duplicated if the char * returned is not owned and memory managed by obj */ + if (bytes && cptr) { + if (alloc) { + cstr = reinterpret_cast< char* >(memcpy(new char[len + 1], cstr, sizeof(char)*(len + 1))); + *alloc = SWIG_NEWOBJ; + } else { + /* alloc must be set in order to clean up allocated memory */ + return SWIG_RuntimeError; + } + } +#endif + if (cptr) *cptr = cstr; + if (psize) *psize = len + 1; + Py_XDECREF(bytes); + return ret; + } else { +#if defined(SWIG_PYTHON_2_UNICODE) +#if defined(SWIG_PYTHON_STRICT_BYTE_CHAR) +#error "Cannot use both SWIG_PYTHON_2_UNICODE and SWIG_PYTHON_STRICT_BYTE_CHAR at once" +#endif +#if PY_VERSION_HEX<0x03000000 + if (PyUnicode_Check(obj)) { + char *cstr; Py_ssize_t len; + if (!alloc && cptr) { + return SWIG_RuntimeError; + } + obj = PyUnicode_AsUTF8String(obj); + if (!obj) + return SWIG_TypeError; + if (PyString_AsStringAndSize(obj, &cstr, &len) != -1) { + if (cptr) { + if (alloc) *alloc = SWIG_NEWOBJ; + *cptr = reinterpret_cast< char* >(memcpy(new char[len + 1], cstr, sizeof(char)*(len + 1))); + } + if (psize) *psize = len + 1; + + Py_XDECREF(obj); + return SWIG_OK; + } else { + Py_XDECREF(obj); + } + } +#endif +#endif + + swig_type_info* pchar_descriptor = SWIG_pchar_descriptor(); + if (pchar_descriptor) { + void* vptr = 0; + if (SWIG_ConvertPtr(obj, &vptr, pchar_descriptor, 0) == SWIG_OK) { + if (cptr) *cptr = (char *) vptr; + if (psize) *psize = vptr ? (strlen((char *)vptr) + 1) : 0; + if (alloc) *alloc = SWIG_OLDOBJ; + return SWIG_OK; + } + } + } + return SWIG_TypeError; +} + + +SWIGINTERN int +SWIG_AsPtr_std_string (PyObject * obj, std::string **val) +{ + char* buf = 0 ; size_t size = 0; int alloc = SWIG_OLDOBJ; + if (SWIG_IsOK((SWIG_AsCharPtrAndSize(obj, &buf, &size, &alloc)))) { + if (buf) { + if (val) *val = new std::string(buf, size - 1); + if (alloc == SWIG_NEWOBJ) delete[] buf; + return SWIG_NEWOBJ; + } else { + if (val) *val = 0; + return SWIG_OLDOBJ; + } + } else { + static int init = 0; + static swig_type_info* descriptor = 0; + if (!init) { + descriptor = SWIG_TypeQuery("std::string" " *"); + init = 1; + } + if (descriptor) { + std::string *vptr; + int res = SWIG_ConvertPtr(obj, (void**)&vptr, descriptor, 0); + if (SWIG_IsOK(res) && val) *val = vptr; + return res; + } + } + return SWIG_ERROR; +} + + +SWIGINTERN int +SWIG_AsVal_std_string (PyObject * obj, std::string *val) +{ + std::string* v = (std::string *) 0; + int res = SWIG_AsPtr_std_string (obj, &v); + if (!SWIG_IsOK(res)) return res; + if (v) { + if (val) *val = *v; + if (SWIG_IsNewObj(res)) { + delete v; + res = SWIG_DelNewMask(res); + } + return res; + } + return SWIG_ERROR; +} + + +SWIGINTERNINLINE PyObject * +SWIG_FromCharPtrAndSize(const char* carray, size_t size) +{ + if (carray) { + if (size > INT_MAX) { + swig_type_info* pchar_descriptor = SWIG_pchar_descriptor(); + return pchar_descriptor ? + SWIG_InternalNewPointerObj(const_cast< char * >(carray), pchar_descriptor, 0) : SWIG_Py_Void(); + } else { +#if PY_VERSION_HEX >= 0x03000000 +#if defined(SWIG_PYTHON_STRICT_BYTE_CHAR) + return PyBytes_FromStringAndSize(carray, static_cast< Py_ssize_t >(size)); +#else + return PyUnicode_DecodeUTF8(carray, static_cast< Py_ssize_t >(size), "surrogateescape"); +#endif +#else + return PyString_FromStringAndSize(carray, static_cast< Py_ssize_t >(size)); +#endif + } + } else { + return SWIG_Py_Void(); + } +} + + +SWIGINTERNINLINE PyObject * +SWIG_From_std_string (const std::string& s) +{ + return SWIG_FromCharPtrAndSize(s.data(), s.size()); +} + + +namespace swig { + template <> struct traits< std::string > { + typedef value_category category; + static const char* type_name() { return"std::string"; } + }; + template <> struct traits_asval< std::string > { + typedef std::string value_type; + static int asval(PyObject *obj, value_type *val) { + return SWIG_AsVal_std_string (obj, val); + } + }; + template <> struct traits_from< std::string > { + typedef std::string value_type; + static PyObject *from(const value_type& val) { + return SWIG_From_std_string (val); + } + }; +} + + + namespace swig { + template <> struct traits > > { + typedef pointer_category category; + static const char* type_name() { + return "std::vector<" "std::string" "," "std::allocator< std::string >" " >"; + } + }; + } + +SWIGINTERN swig::SwigPyIterator *std_vector_Sl_std_string_Sg__iterator(std::vector< std::string > *self,PyObject **PYTHON_SELF){ + return swig::make_output_iterator(self->begin(), self->begin(), self->end(), *PYTHON_SELF); + } +SWIGINTERN bool std_vector_Sl_std_string_Sg____nonzero__(std::vector< std::string > const *self){ + return !(self->empty()); + } +SWIGINTERN bool std_vector_Sl_std_string_Sg____bool__(std::vector< std::string > const *self){ + return !(self->empty()); + } +SWIGINTERN std::vector< std::string >::size_type std_vector_Sl_std_string_Sg____len__(std::vector< std::string > const *self){ + return self->size(); + } +SWIGINTERN std::vector< std::string,std::allocator< std::string > > *std_vector_Sl_std_string_Sg____getslice__(std::vector< std::string > *self,std::vector< std::string >::difference_type i,std::vector< std::string >::difference_type j){ + return swig::getslice(self, i, j, 1); + } +SWIGINTERN void std_vector_Sl_std_string_Sg____setslice____SWIG_0(std::vector< std::string > *self,std::vector< std::string >::difference_type i,std::vector< std::string >::difference_type j){ + swig::setslice(self, i, j, 1, std::vector< std::string,std::allocator< std::string > >()); + } +SWIGINTERN void std_vector_Sl_std_string_Sg____setslice____SWIG_1(std::vector< std::string > *self,std::vector< std::string >::difference_type i,std::vector< std::string >::difference_type j,std::vector< std::string,std::allocator< std::string > > const &v){ + swig::setslice(self, i, j, 1, v); + } +SWIGINTERN void std_vector_Sl_std_string_Sg____delslice__(std::vector< std::string > *self,std::vector< std::string >::difference_type i,std::vector< std::string >::difference_type j){ + swig::delslice(self, i, j, 1); + } +SWIGINTERN void std_vector_Sl_std_string_Sg____delitem____SWIG_0(std::vector< std::string > *self,std::vector< std::string >::difference_type i){ + swig::erase(self, swig::getpos(self, i)); + } +SWIGINTERN std::vector< std::string,std::allocator< std::string > > *std_vector_Sl_std_string_Sg____getitem____SWIG_0(std::vector< std::string > *self,SWIGPY_SLICEOBJECT *slice){ + Py_ssize_t i, j, step; + if( !PySlice_Check(slice) ) { + SWIG_Error(SWIG_TypeError, "Slice object expected."); + return NULL; + } + PySlice_GetIndices(slice, (Py_ssize_t)self->size(), &i, &j, &step); + std::vector< std::string,std::allocator< std::string > >::difference_type id = i; + std::vector< std::string,std::allocator< std::string > >::difference_type jd = j; + return swig::getslice(self, id, jd, step); + } +SWIGINTERN void std_vector_Sl_std_string_Sg____setitem____SWIG_0(std::vector< std::string > *self,SWIGPY_SLICEOBJECT *slice,std::vector< std::string,std::allocator< std::string > > const &v){ + Py_ssize_t i, j, step; + if( !PySlice_Check(slice) ) { + SWIG_Error(SWIG_TypeError, "Slice object expected."); + return; + } + PySlice_GetIndices(slice, (Py_ssize_t)self->size(), &i, &j, &step); + std::vector< std::string,std::allocator< std::string > >::difference_type id = i; + std::vector< std::string,std::allocator< std::string > >::difference_type jd = j; + swig::setslice(self, id, jd, step, v); + } +SWIGINTERN void std_vector_Sl_std_string_Sg____setitem____SWIG_1(std::vector< std::string > *self,SWIGPY_SLICEOBJECT *slice){ + Py_ssize_t i, j, step; + if( !PySlice_Check(slice) ) { + SWIG_Error(SWIG_TypeError, "Slice object expected."); + return; + } + PySlice_GetIndices(slice, (Py_ssize_t)self->size(), &i, &j, &step); + std::vector< std::string,std::allocator< std::string > >::difference_type id = i; + std::vector< std::string,std::allocator< std::string > >::difference_type jd = j; + swig::delslice(self, id, jd, step); + } +SWIGINTERN void std_vector_Sl_std_string_Sg____delitem____SWIG_1(std::vector< std::string > *self,SWIGPY_SLICEOBJECT *slice){ + Py_ssize_t i, j, step; + if( !PySlice_Check(slice) ) { + SWIG_Error(SWIG_TypeError, "Slice object expected."); + return; + } + PySlice_GetIndices(slice, (Py_ssize_t)self->size(), &i, &j, &step); + std::vector< std::string,std::allocator< std::string > >::difference_type id = i; + std::vector< std::string,std::allocator< std::string > >::difference_type jd = j; + swig::delslice(self, id, jd, step); + } +SWIGINTERN std::vector< std::string >::value_type const &std_vector_Sl_std_string_Sg____getitem____SWIG_1(std::vector< std::string > const *self,std::vector< std::string >::difference_type i){ + return *(swig::cgetpos(self, i)); + } +SWIGINTERN void std_vector_Sl_std_string_Sg____setitem____SWIG_2(std::vector< std::string > *self,std::vector< std::string >::difference_type i,std::vector< std::string >::value_type const &x){ + *(swig::getpos(self,i)) = x; + } +SWIGINTERN std::vector< std::string >::value_type std_vector_Sl_std_string_Sg__pop(std::vector< std::string > *self){ + if (self->size() == 0) + throw std::out_of_range("pop from empty container"); + std::vector< std::string,std::allocator< std::string > >::value_type x = self->back(); + self->pop_back(); + return x; + } +SWIGINTERN void std_vector_Sl_std_string_Sg__append(std::vector< std::string > *self,std::vector< std::string >::value_type const &x){ + self->push_back(x); + } +SWIGINTERN std::vector< std::string >::iterator std_vector_Sl_std_string_Sg__erase__SWIG_0(std::vector< std::string > *self,std::vector< std::string >::iterator pos){ return self->erase(pos); } +SWIGINTERN std::vector< std::string >::iterator std_vector_Sl_std_string_Sg__erase__SWIG_1(std::vector< std::string > *self,std::vector< std::string >::iterator first,std::vector< std::string >::iterator last){ return self->erase(first, last); } +SWIGINTERN std::vector< std::string >::iterator std_vector_Sl_std_string_Sg__insert__SWIG_0(std::vector< std::string > *self,std::vector< std::string >::iterator pos,std::vector< std::string >::value_type const &x){ return self->insert(pos, x); } +SWIGINTERN void std_vector_Sl_std_string_Sg__insert__SWIG_1(std::vector< std::string > *self,std::vector< std::string >::iterator pos,std::vector< std::string >::size_type n,std::vector< std::string >::value_type const &x){ self->insert(pos, n, x); } + + namespace swig { + template <> struct traits< std::shared_ptr< ppc::protocol::INodeInfo > > { + typedef pointer_category category; + static const char* type_name() { return"std::shared_ptr< ppc::protocol::INodeInfo >"; } + }; + } + + + namespace swig { + template <> struct traits, std::allocator< std::shared_ptr< ppc::protocol::INodeInfo > > > > { + typedef pointer_category category; + static const char* type_name() { + return "std::vector<" "std::shared_ptr< ppc::protocol::INodeInfo >" "," "std::allocator< std::shared_ptr< ppc::protocol::INodeInfo > >" " >"; + } + }; + } + +SWIGINTERN swig::SwigPyIterator *std_vector_Sl_std_shared_ptr_Sl_ppc_protocol_INodeInfo_Sg__Sg__iterator(std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *self,PyObject **PYTHON_SELF){ + return swig::make_output_iterator(self->begin(), self->begin(), self->end(), *PYTHON_SELF); + } +SWIGINTERN bool std_vector_Sl_std_shared_ptr_Sl_ppc_protocol_INodeInfo_Sg__Sg____nonzero__(std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > const *self){ + return !(self->empty()); + } +SWIGINTERN bool std_vector_Sl_std_shared_ptr_Sl_ppc_protocol_INodeInfo_Sg__Sg____bool__(std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > const *self){ + return !(self->empty()); + } +SWIGINTERN std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::size_type std_vector_Sl_std_shared_ptr_Sl_ppc_protocol_INodeInfo_Sg__Sg____len__(std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > const *self){ + return self->size(); + } +SWIGINTERN std::vector< std::shared_ptr< ppc::protocol::INodeInfo >,std::allocator< std::shared_ptr< ppc::protocol::INodeInfo > > > *std_vector_Sl_std_shared_ptr_Sl_ppc_protocol_INodeInfo_Sg__Sg____getslice__(std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *self,std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::difference_type i,std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::difference_type j){ + return swig::getslice(self, i, j, 1); + } +SWIGINTERN void std_vector_Sl_std_shared_ptr_Sl_ppc_protocol_INodeInfo_Sg__Sg____setslice____SWIG_0(std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *self,std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::difference_type i,std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::difference_type j){ + swig::setslice(self, i, j, 1, std::vector< std::shared_ptr< ppc::protocol::INodeInfo >,std::allocator< std::shared_ptr< ppc::protocol::INodeInfo > > >()); + } +SWIGINTERN void std_vector_Sl_std_shared_ptr_Sl_ppc_protocol_INodeInfo_Sg__Sg____setslice____SWIG_1(std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *self,std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::difference_type i,std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::difference_type j,std::vector< std::shared_ptr< ppc::protocol::INodeInfo >,std::allocator< std::shared_ptr< ppc::protocol::INodeInfo > > > const &v){ + swig::setslice(self, i, j, 1, v); + } +SWIGINTERN void std_vector_Sl_std_shared_ptr_Sl_ppc_protocol_INodeInfo_Sg__Sg____delslice__(std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *self,std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::difference_type i,std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::difference_type j){ + swig::delslice(self, i, j, 1); + } +SWIGINTERN void std_vector_Sl_std_shared_ptr_Sl_ppc_protocol_INodeInfo_Sg__Sg____delitem____SWIG_0(std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *self,std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::difference_type i){ + swig::erase(self, swig::getpos(self, i)); + } +SWIGINTERN std::vector< std::shared_ptr< ppc::protocol::INodeInfo >,std::allocator< std::shared_ptr< ppc::protocol::INodeInfo > > > *std_vector_Sl_std_shared_ptr_Sl_ppc_protocol_INodeInfo_Sg__Sg____getitem____SWIG_0(std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *self,SWIGPY_SLICEOBJECT *slice){ + Py_ssize_t i, j, step; + if( !PySlice_Check(slice) ) { + SWIG_Error(SWIG_TypeError, "Slice object expected."); + return NULL; + } + PySlice_GetIndices(slice, (Py_ssize_t)self->size(), &i, &j, &step); + std::vector< std::shared_ptr< ppc::protocol::INodeInfo >,std::allocator< std::shared_ptr< ppc::protocol::INodeInfo > > >::difference_type id = i; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo >,std::allocator< std::shared_ptr< ppc::protocol::INodeInfo > > >::difference_type jd = j; + return swig::getslice(self, id, jd, step); + } +SWIGINTERN void std_vector_Sl_std_shared_ptr_Sl_ppc_protocol_INodeInfo_Sg__Sg____setitem____SWIG_0(std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *self,SWIGPY_SLICEOBJECT *slice,std::vector< std::shared_ptr< ppc::protocol::INodeInfo >,std::allocator< std::shared_ptr< ppc::protocol::INodeInfo > > > const &v){ + Py_ssize_t i, j, step; + if( !PySlice_Check(slice) ) { + SWIG_Error(SWIG_TypeError, "Slice object expected."); + return; + } + PySlice_GetIndices(slice, (Py_ssize_t)self->size(), &i, &j, &step); + std::vector< std::shared_ptr< ppc::protocol::INodeInfo >,std::allocator< std::shared_ptr< ppc::protocol::INodeInfo > > >::difference_type id = i; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo >,std::allocator< std::shared_ptr< ppc::protocol::INodeInfo > > >::difference_type jd = j; + swig::setslice(self, id, jd, step, v); + } +SWIGINTERN void std_vector_Sl_std_shared_ptr_Sl_ppc_protocol_INodeInfo_Sg__Sg____setitem____SWIG_1(std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *self,SWIGPY_SLICEOBJECT *slice){ + Py_ssize_t i, j, step; + if( !PySlice_Check(slice) ) { + SWIG_Error(SWIG_TypeError, "Slice object expected."); + return; + } + PySlice_GetIndices(slice, (Py_ssize_t)self->size(), &i, &j, &step); + std::vector< std::shared_ptr< ppc::protocol::INodeInfo >,std::allocator< std::shared_ptr< ppc::protocol::INodeInfo > > >::difference_type id = i; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo >,std::allocator< std::shared_ptr< ppc::protocol::INodeInfo > > >::difference_type jd = j; + swig::delslice(self, id, jd, step); + } +SWIGINTERN void std_vector_Sl_std_shared_ptr_Sl_ppc_protocol_INodeInfo_Sg__Sg____delitem____SWIG_1(std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *self,SWIGPY_SLICEOBJECT *slice){ + Py_ssize_t i, j, step; + if( !PySlice_Check(slice) ) { + SWIG_Error(SWIG_TypeError, "Slice object expected."); + return; + } + PySlice_GetIndices(slice, (Py_ssize_t)self->size(), &i, &j, &step); + std::vector< std::shared_ptr< ppc::protocol::INodeInfo >,std::allocator< std::shared_ptr< ppc::protocol::INodeInfo > > >::difference_type id = i; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo >,std::allocator< std::shared_ptr< ppc::protocol::INodeInfo > > >::difference_type jd = j; + swig::delslice(self, id, jd, step); + } +SWIGINTERN std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type const &std_vector_Sl_std_shared_ptr_Sl_ppc_protocol_INodeInfo_Sg__Sg____getitem____SWIG_1(std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > const *self,std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::difference_type i){ + return *(swig::cgetpos(self, i)); + } +SWIGINTERN void std_vector_Sl_std_shared_ptr_Sl_ppc_protocol_INodeInfo_Sg__Sg____setitem____SWIG_2(std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *self,std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::difference_type i,std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type const &x){ + *(swig::getpos(self,i)) = x; + } +SWIGINTERN std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type std_vector_Sl_std_shared_ptr_Sl_ppc_protocol_INodeInfo_Sg__Sg__pop(std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *self){ + if (self->size() == 0) + throw std::out_of_range("pop from empty container"); + std::vector< std::shared_ptr< ppc::protocol::INodeInfo >,std::allocator< std::shared_ptr< ppc::protocol::INodeInfo > > >::value_type x = self->back(); + self->pop_back(); + return x; + } +SWIGINTERN void std_vector_Sl_std_shared_ptr_Sl_ppc_protocol_INodeInfo_Sg__Sg__append(std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *self,std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type const &x){ + self->push_back(x); + } +SWIGINTERN std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::iterator std_vector_Sl_std_shared_ptr_Sl_ppc_protocol_INodeInfo_Sg__Sg__erase__SWIG_0(std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *self,std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::iterator pos){ return self->erase(pos); } +SWIGINTERN std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::iterator std_vector_Sl_std_shared_ptr_Sl_ppc_protocol_INodeInfo_Sg__Sg__erase__SWIG_1(std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *self,std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::iterator first,std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::iterator last){ return self->erase(first, last); } +SWIGINTERN std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::iterator std_vector_Sl_std_shared_ptr_Sl_ppc_protocol_INodeInfo_Sg__Sg__insert__SWIG_0(std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *self,std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::iterator pos,std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type const &x){ return self->insert(pos, x); } +SWIGINTERN void std_vector_Sl_std_shared_ptr_Sl_ppc_protocol_INodeInfo_Sg__Sg__insert__SWIG_1(std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *self,std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::iterator pos,std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::size_type n,std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type const &x){ self->insert(pos, n, x); } + + + + +SWIGINTERN int +SWIG_AsVal_int (PyObject * obj, int *val) +{ + long v; + int res = SWIG_AsVal_long (obj, &v); + if (SWIG_IsOK(res)) { + if ((v < INT_MIN || v > INT_MAX)) { + return SWIG_OverflowError; + } else { + if (val) *val = static_cast< int >(v); + } + } + return res; +} + + +struct SWIG_null_deleter { + void operator() (void const *) const { + } +}; +#define SWIG_NO_NULL_DELETER_0 , SWIG_null_deleter() +#define SWIG_NO_NULL_DELETER_1 +#define SWIG_NO_NULL_DELETER_SWIG_POINTER_NEW +#define SWIG_NO_NULL_DELETER_SWIG_POINTER_OWN + + +#define SWIG_NO_NULL_DELETER_SWIG_BUILTIN_INIT + + +SWIGINTERN int +SWIG_AsVal_unsigned_SS_short (PyObject * obj, unsigned short *val) +{ + unsigned long v; + int res = SWIG_AsVal_unsigned_SS_long (obj, &v); + if (SWIG_IsOK(res)) { + if ((v > USHRT_MAX)) { + return SWIG_OverflowError; + } else { + if (val) *val = static_cast< unsigned short >(v); + } + } + return res; +} + + +SWIGINTERNINLINE PyObject * +SWIG_From_unsigned_SS_short (unsigned short value) +{ + return SWIG_From_unsigned_SS_long (value); +} + + +SWIGINTERN int +SWIG_AsVal_bool (PyObject *obj, bool *val) +{ + int r; + if (!PyBool_Check(obj)) + return SWIG_ERROR; + r = PyObject_IsTrue(obj); + if (r == -1) + return SWIG_ERROR; + if (val) *val = r ? true : false; + return SWIG_OK; +} + + +#include + + +SWIGINTERNINLINE PyObject * +SWIG_From_short (short value) +{ + return SWIG_From_long (value); +} + + +SWIGINTERNINLINE PyObject* + SWIG_From_unsigned_SS_int (unsigned int value) +{ + return PyInt_FromSize_t((size_t) value); +} + + +SWIGINTERN int +SWIG_AsVal_short (PyObject * obj, short *val) +{ + long v; + int res = SWIG_AsVal_long (obj, &v); + if (SWIG_IsOK(res)) { + if ((v < SHRT_MIN || v > SHRT_MAX)) { + return SWIG_OverflowError; + } else { + if (val) *val = static_cast< short >(v); + } + } + return res; +} + + + +/* --------------------------------------------------- + * C++ director class methods + * --------------------------------------------------- */ + +#include "wedpr_python_transportPYTHON_wrap.h" + +SwigDirector_ErrorCallback::SwigDirector_ErrorCallback(PyObject *self): ppc::front::ErrorCallback(), Swig::Director(self) { + SWIG_DIRECTOR_RGTR((ppc::front::ErrorCallback *)this, this); +} + + + + +SwigDirector_ErrorCallback::~SwigDirector_ErrorCallback() { +} + +void SwigDirector_ErrorCallback::onError(bcos::Error::Ptr error) { + std::shared_ptr< bcos::Error > *smartarg1 = 0 ; + + swig::SwigVar_PyObject obj0; + + smartarg1 = error ? new std::shared_ptr< bcos::Error >(error) : 0; + obj0 = SWIG_NewPointerObj(SWIG_as_voidptr(smartarg1), SWIGTYPE_p_std__shared_ptrT_bcos__Error_t, SWIG_POINTER_OWN | 0 ); + + if (!swig_get_self()) { + Swig::DirectorException::raise("'self' uninitialized, maybe you forgot to call ErrorCallback.__init__."); + } +#if defined(SWIG_PYTHON_DIRECTOR_VTABLE) + const size_t swig_method_index = 0; + const char *const swig_method_name = "onError"; + PyObject *method = swig_get_method(swig_method_index, swig_method_name); + swig::SwigVar_PyObject result = PyObject_CallFunctionObjArgs(method ,(PyObject *)obj0, NULL); +#else + swig::SwigVar_PyObject swig_method_name = SWIG_Python_str_FromChar("onError"); + swig::SwigVar_PyObject result = PyObject_CallMethodObjArgs(swig_get_self(), (PyObject *) swig_method_name ,(PyObject *)obj0, NULL); +#endif + if (!result) { + PyObject *error = PyErr_Occurred(); + if (error) { + Swig::DirectorMethodException::raise("Error detected when calling 'ErrorCallback.onError'"); + } + } +} + + +SwigDirector_MessageDispatcherHandler::SwigDirector_MessageDispatcherHandler(PyObject *self): ppc::front::MessageDispatcherHandler(), Swig::Director(self) { + SWIG_DIRECTOR_RGTR((ppc::front::MessageDispatcherHandler *)this, this); +} + + + + +SwigDirector_MessageDispatcherHandler::~SwigDirector_MessageDispatcherHandler() { +} + +void SwigDirector_MessageDispatcherHandler::onMessage(ppc::protocol::Message::Ptr msg) { + std::shared_ptr< ppc::protocol::Message > *smartarg1 = 0 ; + + swig::SwigVar_PyObject obj0; + + smartarg1 = msg ? new std::shared_ptr< ppc::protocol::Message >(msg) : 0; + obj0 = SWIG_NewPointerObj(SWIG_as_voidptr(smartarg1), SWIGTYPE_p_std__shared_ptrT_ppc__protocol__Message_t, SWIG_POINTER_OWN | 0 ); + + if (!swig_get_self()) { + Swig::DirectorException::raise("'self' uninitialized, maybe you forgot to call MessageDispatcherHandler.__init__."); + } +#if defined(SWIG_PYTHON_DIRECTOR_VTABLE) + const size_t swig_method_index = 0; + const char *const swig_method_name = "onMessage"; + PyObject *method = swig_get_method(swig_method_index, swig_method_name); + swig::SwigVar_PyObject result = PyObject_CallFunctionObjArgs(method ,(PyObject *)obj0, NULL); +#else + swig::SwigVar_PyObject swig_method_name = SWIG_Python_str_FromChar("onMessage"); + swig::SwigVar_PyObject result = PyObject_CallMethodObjArgs(swig_get_self(), (PyObject *) swig_method_name ,(PyObject *)obj0, NULL); +#endif + if (!result) { + PyObject *error = PyErr_Occurred(); + if (error) { + Swig::DirectorMethodException::raise("Error detected when calling 'MessageDispatcherHandler.onMessage'"); + } + } +} + + +SwigDirector_IMessageHandler::SwigDirector_IMessageHandler(PyObject *self): ppc::front::IMessageHandler(), Swig::Director(self) { + SWIG_DIRECTOR_RGTR((ppc::front::IMessageHandler *)this, this); +} + + + + +SwigDirector_IMessageHandler::~SwigDirector_IMessageHandler() { +} + +void SwigDirector_IMessageHandler::onMessage(bcos::Error::Ptr e,ppc::protocol::Message::Ptr msg,ppc::front::SendResponseHandler sendResponseHandler) { + std::shared_ptr< bcos::Error > *smartarg1 = 0 ; + std::shared_ptr< ppc::protocol::Message > *smartarg2 = 0 ; + + swig::SwigVar_PyObject obj0; + + smartarg1 = e ? new std::shared_ptr< bcos::Error >(e) : 0; + obj0 = SWIG_NewPointerObj(SWIG_as_voidptr(smartarg1), SWIGTYPE_p_std__shared_ptrT_bcos__Error_t, SWIG_POINTER_OWN | 0 ); + + swig::SwigVar_PyObject obj1; + + smartarg2 = msg ? new std::shared_ptr< ppc::protocol::Message >(msg) : 0; + obj1 = SWIG_NewPointerObj(SWIG_as_voidptr(smartarg2), SWIGTYPE_p_std__shared_ptrT_ppc__protocol__Message_t, SWIG_POINTER_OWN | 0 ); + + swig::SwigVar_PyObject obj2; + obj2 = SWIG_NewPointerObj((new ppc::front::SendResponseHandler(SWIG_STD_MOVE(sendResponseHandler))), SWIGTYPE_p_ppc__front__SendResponseHandler, SWIG_POINTER_OWN | 0 ); + if (!swig_get_self()) { + Swig::DirectorException::raise("'self' uninitialized, maybe you forgot to call IMessageHandler.__init__."); + } +#if defined(SWIG_PYTHON_DIRECTOR_VTABLE) + const size_t swig_method_index = 0; + const char *const swig_method_name = "onMessage"; + PyObject *method = swig_get_method(swig_method_index, swig_method_name); + swig::SwigVar_PyObject result = PyObject_CallFunctionObjArgs(method ,(PyObject *)obj0,(PyObject *)obj1,(PyObject *)obj2, NULL); +#else + swig::SwigVar_PyObject swig_method_name = SWIG_Python_str_FromChar("onMessage"); + swig::SwigVar_PyObject result = PyObject_CallMethodObjArgs(swig_get_self(), (PyObject *) swig_method_name ,(PyObject *)obj0,(PyObject *)obj1,(PyObject *)obj2, NULL); +#endif + if (!result) { + PyObject *error = PyErr_Occurred(); + if (error) { + Swig::DirectorMethodException::raise("Error detected when calling 'IMessageHandler.onMessage'"); + } + } +} + + +SwigDirector_GetPeersInfoHandler::SwigDirector_GetPeersInfoHandler(PyObject *self): ppc::front::GetPeersInfoHandler(), Swig::Director(self) { + SWIG_DIRECTOR_RGTR((ppc::front::GetPeersInfoHandler *)this, this); +} + + + + +SwigDirector_GetPeersInfoHandler::~SwigDirector_GetPeersInfoHandler() { +} + +void SwigDirector_GetPeersInfoHandler::onPeersInfo(bcos::Error::Ptr e,std::string const &peersInfo) { + std::shared_ptr< bcos::Error > *smartarg1 = 0 ; + + swig::SwigVar_PyObject obj0; + + smartarg1 = e ? new std::shared_ptr< bcos::Error >(e) : 0; + obj0 = SWIG_NewPointerObj(SWIG_as_voidptr(smartarg1), SWIGTYPE_p_std__shared_ptrT_bcos__Error_t, SWIG_POINTER_OWN | 0 ); + + swig::SwigVar_PyObject obj1; + obj1 = SWIG_From_std_string(static_cast< std::string >(peersInfo)); + if (!swig_get_self()) { + Swig::DirectorException::raise("'self' uninitialized, maybe you forgot to call GetPeersInfoHandler.__init__."); + } +#if defined(SWIG_PYTHON_DIRECTOR_VTABLE) + const size_t swig_method_index = 0; + const char *const swig_method_name = "onPeersInfo"; + PyObject *method = swig_get_method(swig_method_index, swig_method_name); + swig::SwigVar_PyObject result = PyObject_CallFunctionObjArgs(method ,(PyObject *)obj0,(PyObject *)obj1, NULL); +#else + swig::SwigVar_PyObject swig_method_name = SWIG_Python_str_FromChar("onPeersInfo"); + swig::SwigVar_PyObject result = PyObject_CallMethodObjArgs(swig_get_self(), (PyObject *) swig_method_name ,(PyObject *)obj0,(PyObject *)obj1, NULL); +#endif + if (!result) { + PyObject *error = PyErr_Occurred(); + if (error) { + Swig::DirectorMethodException::raise("Error detected when calling 'GetPeersInfoHandler.onPeersInfo'"); + } + } +} + + +#ifdef __cplusplus +extern "C" { +#endif +SWIGINTERN PyObject *_wrap_delete_SwigPyIterator(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + swig::SwigPyIterator *arg1 = (swig::SwigPyIterator *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_swig__SwigPyIterator, SWIG_POINTER_DISOWN | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_SwigPyIterator" "', argument " "1"" of type '" "swig::SwigPyIterator *""'"); + } + arg1 = reinterpret_cast< swig::SwigPyIterator * >(argp1); + delete arg1; + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_SwigPyIterator_value(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + swig::SwigPyIterator *arg1 = (swig::SwigPyIterator *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + PyObject *result = 0 ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_swig__SwigPyIterator, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SwigPyIterator_value" "', argument " "1"" of type '" "swig::SwigPyIterator const *""'"); + } + arg1 = reinterpret_cast< swig::SwigPyIterator * >(argp1); + try { + result = (PyObject *)((swig::SwigPyIterator const *)arg1)->value(); + } catch(swig::stop_iteration &_e) { + { + (void)_e; + SWIG_SetErrorObj(PyExc_StopIteration, SWIG_Py_Void()); + SWIG_fail; + } + } + resultobj = result; + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_SwigPyIterator_incr__SWIG_0(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + swig::SwigPyIterator *arg1 = (swig::SwigPyIterator *) 0 ; + size_t arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + size_t val2 ; + int ecode2 = 0 ; + swig::SwigPyIterator *result = 0 ; + + (void)self; + if ((nobjs < 2) || (nobjs > 2)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_swig__SwigPyIterator, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SwigPyIterator_incr" "', argument " "1"" of type '" "swig::SwigPyIterator *""'"); + } + arg1 = reinterpret_cast< swig::SwigPyIterator * >(argp1); + ecode2 = SWIG_AsVal_size_t(swig_obj[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "SwigPyIterator_incr" "', argument " "2"" of type '" "size_t""'"); + } + arg2 = static_cast< size_t >(val2); + try { + result = (swig::SwigPyIterator *)(arg1)->incr(arg2); + } catch(swig::stop_iteration &_e) { + { + (void)_e; + SWIG_SetErrorObj(PyExc_StopIteration, SWIG_Py_Void()); + SWIG_fail; + } + } + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_swig__SwigPyIterator, 0 | 0 ); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_SwigPyIterator_incr__SWIG_1(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + swig::SwigPyIterator *arg1 = (swig::SwigPyIterator *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + swig::SwigPyIterator *result = 0 ; + + (void)self; + if ((nobjs < 1) || (nobjs > 1)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_swig__SwigPyIterator, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SwigPyIterator_incr" "', argument " "1"" of type '" "swig::SwigPyIterator *""'"); + } + arg1 = reinterpret_cast< swig::SwigPyIterator * >(argp1); + try { + result = (swig::SwigPyIterator *)(arg1)->incr(); + } catch(swig::stop_iteration &_e) { + { + (void)_e; + SWIG_SetErrorObj(PyExc_StopIteration, SWIG_Py_Void()); + SWIG_fail; + } + } + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_swig__SwigPyIterator, 0 | 0 ); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_SwigPyIterator_incr(PyObject *self, PyObject *args) { + Py_ssize_t argc; + PyObject *argv[3] = { + 0 + }; + + if (!(argc = SWIG_Python_UnpackTuple(args, "SwigPyIterator_incr", 0, 2, argv))) SWIG_fail; + --argc; + if (argc == 1) { + int _v = 0; + void *vptr = 0; + int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_swig__SwigPyIterator, 0); + _v = SWIG_CheckState(res); + if (_v) { + return _wrap_SwigPyIterator_incr__SWIG_1(self, argc, argv); + } + } + if (argc == 2) { + int _v = 0; + void *vptr = 0; + int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_swig__SwigPyIterator, 0); + _v = SWIG_CheckState(res); + if (_v) { + { + int res = SWIG_AsVal_size_t(argv[1], NULL); + _v = SWIG_CheckState(res); + } + if (_v) { + return _wrap_SwigPyIterator_incr__SWIG_0(self, argc, argv); + } + } + } + +fail: + SWIG_Python_RaiseOrModifyTypeError("Wrong number or type of arguments for overloaded function 'SwigPyIterator_incr'.\n" + " Possible C/C++ prototypes are:\n" + " swig::SwigPyIterator::incr(size_t)\n" + " swig::SwigPyIterator::incr()\n"); + return 0; +} + + +SWIGINTERN PyObject *_wrap_SwigPyIterator_decr__SWIG_0(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + swig::SwigPyIterator *arg1 = (swig::SwigPyIterator *) 0 ; + size_t arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + size_t val2 ; + int ecode2 = 0 ; + swig::SwigPyIterator *result = 0 ; + + (void)self; + if ((nobjs < 2) || (nobjs > 2)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_swig__SwigPyIterator, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SwigPyIterator_decr" "', argument " "1"" of type '" "swig::SwigPyIterator *""'"); + } + arg1 = reinterpret_cast< swig::SwigPyIterator * >(argp1); + ecode2 = SWIG_AsVal_size_t(swig_obj[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "SwigPyIterator_decr" "', argument " "2"" of type '" "size_t""'"); + } + arg2 = static_cast< size_t >(val2); + try { + result = (swig::SwigPyIterator *)(arg1)->decr(arg2); + } catch(swig::stop_iteration &_e) { + { + (void)_e; + SWIG_SetErrorObj(PyExc_StopIteration, SWIG_Py_Void()); + SWIG_fail; + } + } + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_swig__SwigPyIterator, 0 | 0 ); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_SwigPyIterator_decr__SWIG_1(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + swig::SwigPyIterator *arg1 = (swig::SwigPyIterator *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + swig::SwigPyIterator *result = 0 ; + + (void)self; + if ((nobjs < 1) || (nobjs > 1)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_swig__SwigPyIterator, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SwigPyIterator_decr" "', argument " "1"" of type '" "swig::SwigPyIterator *""'"); + } + arg1 = reinterpret_cast< swig::SwigPyIterator * >(argp1); + try { + result = (swig::SwigPyIterator *)(arg1)->decr(); + } catch(swig::stop_iteration &_e) { + { + (void)_e; + SWIG_SetErrorObj(PyExc_StopIteration, SWIG_Py_Void()); + SWIG_fail; + } + } + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_swig__SwigPyIterator, 0 | 0 ); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_SwigPyIterator_decr(PyObject *self, PyObject *args) { + Py_ssize_t argc; + PyObject *argv[3] = { + 0 + }; + + if (!(argc = SWIG_Python_UnpackTuple(args, "SwigPyIterator_decr", 0, 2, argv))) SWIG_fail; + --argc; + if (argc == 1) { + int _v = 0; + void *vptr = 0; + int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_swig__SwigPyIterator, 0); + _v = SWIG_CheckState(res); + if (_v) { + return _wrap_SwigPyIterator_decr__SWIG_1(self, argc, argv); + } + } + if (argc == 2) { + int _v = 0; + void *vptr = 0; + int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_swig__SwigPyIterator, 0); + _v = SWIG_CheckState(res); + if (_v) { + { + int res = SWIG_AsVal_size_t(argv[1], NULL); + _v = SWIG_CheckState(res); + } + if (_v) { + return _wrap_SwigPyIterator_decr__SWIG_0(self, argc, argv); + } + } + } + +fail: + SWIG_Python_RaiseOrModifyTypeError("Wrong number or type of arguments for overloaded function 'SwigPyIterator_decr'.\n" + " Possible C/C++ prototypes are:\n" + " swig::SwigPyIterator::decr(size_t)\n" + " swig::SwigPyIterator::decr()\n"); + return 0; +} + + +SWIGINTERN PyObject *_wrap_SwigPyIterator_distance(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + swig::SwigPyIterator *arg1 = (swig::SwigPyIterator *) 0 ; + swig::SwigPyIterator *arg2 = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + void *argp2 = 0 ; + int res2 = 0 ; + PyObject *swig_obj[2] ; + ptrdiff_t result; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "SwigPyIterator_distance", 2, 2, swig_obj)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_swig__SwigPyIterator, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SwigPyIterator_distance" "', argument " "1"" of type '" "swig::SwigPyIterator const *""'"); + } + arg1 = reinterpret_cast< swig::SwigPyIterator * >(argp1); + res2 = SWIG_ConvertPtr(swig_obj[1], &argp2, SWIGTYPE_p_swig__SwigPyIterator, 0 | 0); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "SwigPyIterator_distance" "', argument " "2"" of type '" "swig::SwigPyIterator const &""'"); + } + if (!argp2) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "SwigPyIterator_distance" "', argument " "2"" of type '" "swig::SwigPyIterator const &""'"); + } + arg2 = reinterpret_cast< swig::SwigPyIterator * >(argp2); + try { + result = ((swig::SwigPyIterator const *)arg1)->distance((swig::SwigPyIterator const &)*arg2); + } catch(std::invalid_argument &_e) { + SWIG_Python_Raise(SWIG_NewPointerObj((new std::invalid_argument(static_cast< const std::invalid_argument& >(_e))),SWIGTYPE_p_std__invalid_argument,SWIG_POINTER_OWN), "std::invalid_argument", SWIGTYPE_p_std__invalid_argument); SWIG_fail; + } + resultobj = SWIG_From_ptrdiff_t(static_cast< ptrdiff_t >(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_SwigPyIterator_equal(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + swig::SwigPyIterator *arg1 = (swig::SwigPyIterator *) 0 ; + swig::SwigPyIterator *arg2 = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + void *argp2 = 0 ; + int res2 = 0 ; + PyObject *swig_obj[2] ; + bool result; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "SwigPyIterator_equal", 2, 2, swig_obj)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_swig__SwigPyIterator, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SwigPyIterator_equal" "', argument " "1"" of type '" "swig::SwigPyIterator const *""'"); + } + arg1 = reinterpret_cast< swig::SwigPyIterator * >(argp1); + res2 = SWIG_ConvertPtr(swig_obj[1], &argp2, SWIGTYPE_p_swig__SwigPyIterator, 0 | 0); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "SwigPyIterator_equal" "', argument " "2"" of type '" "swig::SwigPyIterator const &""'"); + } + if (!argp2) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "SwigPyIterator_equal" "', argument " "2"" of type '" "swig::SwigPyIterator const &""'"); + } + arg2 = reinterpret_cast< swig::SwigPyIterator * >(argp2); + try { + result = (bool)((swig::SwigPyIterator const *)arg1)->equal((swig::SwigPyIterator const &)*arg2); + } catch(std::invalid_argument &_e) { + SWIG_Python_Raise(SWIG_NewPointerObj((new std::invalid_argument(static_cast< const std::invalid_argument& >(_e))),SWIGTYPE_p_std__invalid_argument,SWIG_POINTER_OWN), "std::invalid_argument", SWIGTYPE_p_std__invalid_argument); SWIG_fail; + } + resultobj = SWIG_From_bool(static_cast< bool >(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_SwigPyIterator_copy(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + swig::SwigPyIterator *arg1 = (swig::SwigPyIterator *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + swig::SwigPyIterator *result = 0 ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_swig__SwigPyIterator, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SwigPyIterator_copy" "', argument " "1"" of type '" "swig::SwigPyIterator const *""'"); + } + arg1 = reinterpret_cast< swig::SwigPyIterator * >(argp1); + result = (swig::SwigPyIterator *)((swig::SwigPyIterator const *)arg1)->copy(); + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_swig__SwigPyIterator, SWIG_POINTER_OWN | 0 ); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_SwigPyIterator_next(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + swig::SwigPyIterator *arg1 = (swig::SwigPyIterator *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + PyObject *result = 0 ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_swig__SwigPyIterator, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SwigPyIterator_next" "', argument " "1"" of type '" "swig::SwigPyIterator *""'"); + } + arg1 = reinterpret_cast< swig::SwigPyIterator * >(argp1); + try { + result = (PyObject *)(arg1)->next(); + } catch(swig::stop_iteration &_e) { + { + (void)_e; + SWIG_SetErrorObj(PyExc_StopIteration, SWIG_Py_Void()); + SWIG_fail; + } + } + resultobj = result; + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_SwigPyIterator___next__(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + swig::SwigPyIterator *arg1 = (swig::SwigPyIterator *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + PyObject *result = 0 ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_swig__SwigPyIterator, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SwigPyIterator___next__" "', argument " "1"" of type '" "swig::SwigPyIterator *""'"); + } + arg1 = reinterpret_cast< swig::SwigPyIterator * >(argp1); + try { + result = (PyObject *)(arg1)->__next__(); + } catch(swig::stop_iteration &_e) { + { + (void)_e; + SWIG_SetErrorObj(PyExc_StopIteration, SWIG_Py_Void()); + SWIG_fail; + } + } + resultobj = result; + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_SwigPyIterator_previous(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + swig::SwigPyIterator *arg1 = (swig::SwigPyIterator *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + PyObject *result = 0 ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_swig__SwigPyIterator, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SwigPyIterator_previous" "', argument " "1"" of type '" "swig::SwigPyIterator *""'"); + } + arg1 = reinterpret_cast< swig::SwigPyIterator * >(argp1); + try { + result = (PyObject *)(arg1)->previous(); + } catch(swig::stop_iteration &_e) { + { + (void)_e; + SWIG_SetErrorObj(PyExc_StopIteration, SWIG_Py_Void()); + SWIG_fail; + } + } + resultobj = result; + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_SwigPyIterator_advance(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + swig::SwigPyIterator *arg1 = (swig::SwigPyIterator *) 0 ; + ptrdiff_t arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + ptrdiff_t val2 ; + int ecode2 = 0 ; + PyObject *swig_obj[2] ; + swig::SwigPyIterator *result = 0 ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "SwigPyIterator_advance", 2, 2, swig_obj)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_swig__SwigPyIterator, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SwigPyIterator_advance" "', argument " "1"" of type '" "swig::SwigPyIterator *""'"); + } + arg1 = reinterpret_cast< swig::SwigPyIterator * >(argp1); + ecode2 = SWIG_AsVal_ptrdiff_t(swig_obj[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "SwigPyIterator_advance" "', argument " "2"" of type '" "ptrdiff_t""'"); + } + arg2 = static_cast< ptrdiff_t >(val2); + try { + result = (swig::SwigPyIterator *)(arg1)->advance(arg2); + } catch(swig::stop_iteration &_e) { + { + (void)_e; + SWIG_SetErrorObj(PyExc_StopIteration, SWIG_Py_Void()); + SWIG_fail; + } + } + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_swig__SwigPyIterator, 0 | 0 ); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_SwigPyIterator___eq__(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + swig::SwigPyIterator *arg1 = (swig::SwigPyIterator *) 0 ; + swig::SwigPyIterator *arg2 = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + void *argp2 = 0 ; + int res2 = 0 ; + PyObject *swig_obj[2] ; + bool result; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "SwigPyIterator___eq__", 2, 2, swig_obj)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_swig__SwigPyIterator, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SwigPyIterator___eq__" "', argument " "1"" of type '" "swig::SwigPyIterator const *""'"); + } + arg1 = reinterpret_cast< swig::SwigPyIterator * >(argp1); + res2 = SWIG_ConvertPtr(swig_obj[1], &argp2, SWIGTYPE_p_swig__SwigPyIterator, 0 | 0); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "SwigPyIterator___eq__" "', argument " "2"" of type '" "swig::SwigPyIterator const &""'"); + } + if (!argp2) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "SwigPyIterator___eq__" "', argument " "2"" of type '" "swig::SwigPyIterator const &""'"); + } + arg2 = reinterpret_cast< swig::SwigPyIterator * >(argp2); + result = (bool)((swig::SwigPyIterator const *)arg1)->operator ==((swig::SwigPyIterator const &)*arg2); + resultobj = SWIG_From_bool(static_cast< bool >(result)); + return resultobj; +fail: + if (PyErr_Occurred() && !PyErr_ExceptionMatches(PyExc_TypeError)) { + return NULL; + } + PyErr_Clear(); + Py_INCREF(Py_NotImplemented); + return Py_NotImplemented; +} + + +SWIGINTERN PyObject *_wrap_SwigPyIterator___ne__(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + swig::SwigPyIterator *arg1 = (swig::SwigPyIterator *) 0 ; + swig::SwigPyIterator *arg2 = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + void *argp2 = 0 ; + int res2 = 0 ; + PyObject *swig_obj[2] ; + bool result; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "SwigPyIterator___ne__", 2, 2, swig_obj)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_swig__SwigPyIterator, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SwigPyIterator___ne__" "', argument " "1"" of type '" "swig::SwigPyIterator const *""'"); + } + arg1 = reinterpret_cast< swig::SwigPyIterator * >(argp1); + res2 = SWIG_ConvertPtr(swig_obj[1], &argp2, SWIGTYPE_p_swig__SwigPyIterator, 0 | 0); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "SwigPyIterator___ne__" "', argument " "2"" of type '" "swig::SwigPyIterator const &""'"); + } + if (!argp2) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "SwigPyIterator___ne__" "', argument " "2"" of type '" "swig::SwigPyIterator const &""'"); + } + arg2 = reinterpret_cast< swig::SwigPyIterator * >(argp2); + result = (bool)((swig::SwigPyIterator const *)arg1)->operator !=((swig::SwigPyIterator const &)*arg2); + resultobj = SWIG_From_bool(static_cast< bool >(result)); + return resultobj; +fail: + if (PyErr_Occurred() && !PyErr_ExceptionMatches(PyExc_TypeError)) { + return NULL; + } + PyErr_Clear(); + Py_INCREF(Py_NotImplemented); + return Py_NotImplemented; +} + + +SWIGINTERN PyObject *_wrap_SwigPyIterator___iadd__(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + swig::SwigPyIterator *arg1 = (swig::SwigPyIterator *) 0 ; + ptrdiff_t arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + ptrdiff_t val2 ; + int ecode2 = 0 ; + PyObject *swig_obj[2] ; + swig::SwigPyIterator *result = 0 ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "SwigPyIterator___iadd__", 2, 2, swig_obj)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_swig__SwigPyIterator, SWIG_POINTER_DISOWN | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SwigPyIterator___iadd__" "', argument " "1"" of type '" "swig::SwigPyIterator *""'"); + } + arg1 = reinterpret_cast< swig::SwigPyIterator * >(argp1); + ecode2 = SWIG_AsVal_ptrdiff_t(swig_obj[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "SwigPyIterator___iadd__" "', argument " "2"" of type '" "ptrdiff_t""'"); + } + arg2 = static_cast< ptrdiff_t >(val2); + try { + result = (swig::SwigPyIterator *) &(arg1)->operator +=(arg2); + } catch(swig::stop_iteration &_e) { + { + (void)_e; + SWIG_SetErrorObj(PyExc_StopIteration, SWIG_Py_Void()); + SWIG_fail; + } + } + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_swig__SwigPyIterator, SWIG_POINTER_OWN | 0 ); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_SwigPyIterator___isub__(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + swig::SwigPyIterator *arg1 = (swig::SwigPyIterator *) 0 ; + ptrdiff_t arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + ptrdiff_t val2 ; + int ecode2 = 0 ; + PyObject *swig_obj[2] ; + swig::SwigPyIterator *result = 0 ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "SwigPyIterator___isub__", 2, 2, swig_obj)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_swig__SwigPyIterator, SWIG_POINTER_DISOWN | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SwigPyIterator___isub__" "', argument " "1"" of type '" "swig::SwigPyIterator *""'"); + } + arg1 = reinterpret_cast< swig::SwigPyIterator * >(argp1); + ecode2 = SWIG_AsVal_ptrdiff_t(swig_obj[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "SwigPyIterator___isub__" "', argument " "2"" of type '" "ptrdiff_t""'"); + } + arg2 = static_cast< ptrdiff_t >(val2); + try { + result = (swig::SwigPyIterator *) &(arg1)->operator -=(arg2); + } catch(swig::stop_iteration &_e) { + { + (void)_e; + SWIG_SetErrorObj(PyExc_StopIteration, SWIG_Py_Void()); + SWIG_fail; + } + } + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_swig__SwigPyIterator, SWIG_POINTER_OWN | 0 ); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_SwigPyIterator___add__(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + swig::SwigPyIterator *arg1 = (swig::SwigPyIterator *) 0 ; + ptrdiff_t arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + ptrdiff_t val2 ; + int ecode2 = 0 ; + PyObject *swig_obj[2] ; + swig::SwigPyIterator *result = 0 ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "SwigPyIterator___add__", 2, 2, swig_obj)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_swig__SwigPyIterator, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SwigPyIterator___add__" "', argument " "1"" of type '" "swig::SwigPyIterator const *""'"); + } + arg1 = reinterpret_cast< swig::SwigPyIterator * >(argp1); + ecode2 = SWIG_AsVal_ptrdiff_t(swig_obj[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "SwigPyIterator___add__" "', argument " "2"" of type '" "ptrdiff_t""'"); + } + arg2 = static_cast< ptrdiff_t >(val2); + try { + result = (swig::SwigPyIterator *)((swig::SwigPyIterator const *)arg1)->operator +(arg2); + } catch(swig::stop_iteration &_e) { + { + (void)_e; + SWIG_SetErrorObj(PyExc_StopIteration, SWIG_Py_Void()); + SWIG_fail; + } + } + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_swig__SwigPyIterator, SWIG_POINTER_OWN | 0 ); + return resultobj; +fail: + if (PyErr_Occurred() && !PyErr_ExceptionMatches(PyExc_TypeError)) { + return NULL; + } + PyErr_Clear(); + Py_INCREF(Py_NotImplemented); + return Py_NotImplemented; +} + + +SWIGINTERN PyObject *_wrap_SwigPyIterator___sub____SWIG_0(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + swig::SwigPyIterator *arg1 = (swig::SwigPyIterator *) 0 ; + ptrdiff_t arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + ptrdiff_t val2 ; + int ecode2 = 0 ; + swig::SwigPyIterator *result = 0 ; + + (void)self; + if ((nobjs < 2) || (nobjs > 2)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_swig__SwigPyIterator, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SwigPyIterator___sub__" "', argument " "1"" of type '" "swig::SwigPyIterator const *""'"); + } + arg1 = reinterpret_cast< swig::SwigPyIterator * >(argp1); + ecode2 = SWIG_AsVal_ptrdiff_t(swig_obj[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "SwigPyIterator___sub__" "', argument " "2"" of type '" "ptrdiff_t""'"); + } + arg2 = static_cast< ptrdiff_t >(val2); + try { + result = (swig::SwigPyIterator *)((swig::SwigPyIterator const *)arg1)->operator -(arg2); + } catch(swig::stop_iteration &_e) { + { + (void)_e; + SWIG_SetErrorObj(PyExc_StopIteration, SWIG_Py_Void()); + SWIG_fail; + } + } + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_swig__SwigPyIterator, SWIG_POINTER_OWN | 0 ); + return resultobj; +fail: + if (PyErr_Occurred() && !PyErr_ExceptionMatches(PyExc_TypeError)) { + return NULL; + } + PyErr_Clear(); + Py_INCREF(Py_NotImplemented); + return Py_NotImplemented; +} + + +SWIGINTERN PyObject *_wrap_SwigPyIterator___sub____SWIG_1(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + swig::SwigPyIterator *arg1 = (swig::SwigPyIterator *) 0 ; + swig::SwigPyIterator *arg2 = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + void *argp2 = 0 ; + int res2 = 0 ; + ptrdiff_t result; + + (void)self; + if ((nobjs < 2) || (nobjs > 2)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_swig__SwigPyIterator, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SwigPyIterator___sub__" "', argument " "1"" of type '" "swig::SwigPyIterator const *""'"); + } + arg1 = reinterpret_cast< swig::SwigPyIterator * >(argp1); + res2 = SWIG_ConvertPtr(swig_obj[1], &argp2, SWIGTYPE_p_swig__SwigPyIterator, 0 | 0); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "SwigPyIterator___sub__" "', argument " "2"" of type '" "swig::SwigPyIterator const &""'"); + } + if (!argp2) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "SwigPyIterator___sub__" "', argument " "2"" of type '" "swig::SwigPyIterator const &""'"); + } + arg2 = reinterpret_cast< swig::SwigPyIterator * >(argp2); + result = ((swig::SwigPyIterator const *)arg1)->operator -((swig::SwigPyIterator const &)*arg2); + resultobj = SWIG_From_ptrdiff_t(static_cast< ptrdiff_t >(result)); + return resultobj; +fail: + if (PyErr_Occurred() && !PyErr_ExceptionMatches(PyExc_TypeError)) { + return NULL; + } + PyErr_Clear(); + Py_INCREF(Py_NotImplemented); + return Py_NotImplemented; +} + + +SWIGINTERN PyObject *_wrap_SwigPyIterator___sub__(PyObject *self, PyObject *args) { + Py_ssize_t argc; + PyObject *argv[3] = { + 0 + }; + + if (!(argc = SWIG_Python_UnpackTuple(args, "SwigPyIterator___sub__", 0, 2, argv))) SWIG_fail; + --argc; + if (argc == 2) { + int _v = 0; + void *vptr = 0; + int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_swig__SwigPyIterator, 0); + _v = SWIG_CheckState(res); + if (_v) { + int res = SWIG_ConvertPtr(argv[1], 0, SWIGTYPE_p_swig__SwigPyIterator, SWIG_POINTER_NO_NULL | 0); + _v = SWIG_CheckState(res); + if (_v) { + return _wrap_SwigPyIterator___sub____SWIG_1(self, argc, argv); + } + } + } + if (argc == 2) { + int _v = 0; + void *vptr = 0; + int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_swig__SwigPyIterator, 0); + _v = SWIG_CheckState(res); + if (_v) { + { + int res = SWIG_AsVal_ptrdiff_t(argv[1], NULL); + _v = SWIG_CheckState(res); + } + if (_v) { + return _wrap_SwigPyIterator___sub____SWIG_0(self, argc, argv); + } + } + } + +fail: + Py_INCREF(Py_NotImplemented); + return Py_NotImplemented; +} + + +SWIGINTERN PyObject *SwigPyIterator_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *obj; + if (!SWIG_Python_UnpackTuple(args, "swigregister", 1, 1, &obj)) return NULL; + SWIG_TypeNewClientData(SWIGTYPE_p_swig__SwigPyIterator, SWIG_NewClientData(obj)); + return SWIG_Py_Void(); +} + +SWIGINTERN PyObject *_wrap_new_SharedBcosError(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::shared_ptr< bcos::Error > *result = 0 ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "new_SharedBcosError", 0, 0, 0)) SWIG_fail; + { + try { + result = (std::shared_ptr< bcos::Error > *)new std::shared_ptr< bcos::Error >(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + { + std::shared_ptr< bcos::Error > *smartresult = (result && *result) ? new std::shared_ptr< bcos::Error >(*result) : 0; + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(smartresult), SWIGTYPE_p_std__shared_ptrT_bcos__Error_t, SWIG_POINTER_OWN); + if (SWIG_POINTER_NEW) delete result; + } + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_delete_SharedBcosError(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::shared_ptr< bcos::Error > *arg1 = (std::shared_ptr< bcos::Error > *) 0 ; + void *argp1 ; + int res1 = 0 ; + std::shared_ptr< bcos::Error > tempshared1 ; + PyObject *swig_obj[1] ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_bcos__Error_t, 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_SharedBcosError" "', argument " "1"" of type '" "std::shared_ptr< bcos::Error > *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + if (argp1) tempshared1 = *reinterpret_cast< std::shared_ptr< bcos::Error > * >(argp1); + delete reinterpret_cast< std::shared_ptr< bcos::Error > * >(argp1); + arg1 = &tempshared1; + } else { + arg1 = (argp1) ? reinterpret_cast< std::shared_ptr< bcos::Error > * >(argp1) : &tempshared1; + } + } + { + try { + delete arg1; + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *SharedBcosError_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *obj; + if (!SWIG_Python_UnpackTuple(args, "swigregister", 1, 1, &obj)) return NULL; + SWIG_TypeNewClientData(SWIGTYPE_p_std__shared_ptrT_bcos__Error_t, SWIG_NewClientData(obj)); + return SWIG_Py_Void(); +} + +SWIGINTERN PyObject *SharedBcosError_swiginit(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + return SWIG_Python_InitShadowInstance(args); +} + +SWIGINTERN PyObject *_wrap_new_SharedFrontConfig(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::shared_ptr< ppc::front::FrontConfig > *result = 0 ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "new_SharedFrontConfig", 0, 0, 0)) SWIG_fail; + { + try { + result = (std::shared_ptr< ppc::front::FrontConfig > *)new std::shared_ptr< ppc::front::FrontConfig >(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + { + std::shared_ptr< ppc::front::FrontConfig > *smartresult = (result && *result) ? new std::shared_ptr< ppc::front::FrontConfig >(*result) : 0; + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(smartresult), SWIGTYPE_p_std__shared_ptrT_ppc__front__FrontConfig_t, SWIG_POINTER_OWN); + if (SWIG_POINTER_NEW) delete result; + } + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_delete_SharedFrontConfig(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::shared_ptr< ppc::front::FrontConfig > *arg1 = (std::shared_ptr< ppc::front::FrontConfig > *) 0 ; + void *argp1 ; + int res1 = 0 ; + std::shared_ptr< ppc::front::FrontConfig > tempshared1 ; + PyObject *swig_obj[1] ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__front__FrontConfig_t, 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_SharedFrontConfig" "', argument " "1"" of type '" "std::shared_ptr< ppc::front::FrontConfig > *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + if (argp1) tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::front::FrontConfig > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::front::FrontConfig > * >(argp1); + arg1 = &tempshared1; + } else { + arg1 = (argp1) ? reinterpret_cast< std::shared_ptr< ppc::front::FrontConfig > * >(argp1) : &tempshared1; + } + } + { + try { + delete arg1; + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *SharedFrontConfig_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *obj; + if (!SWIG_Python_UnpackTuple(args, "swigregister", 1, 1, &obj)) return NULL; + SWIG_TypeNewClientData(SWIGTYPE_p_std__shared_ptrT_ppc__front__FrontConfig_t, SWIG_NewClientData(obj)); + return SWIG_Py_Void(); +} + +SWIGINTERN PyObject *SharedFrontConfig_swiginit(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + return SWIG_Python_InitShadowInstance(args); +} + +SWIGINTERN PyObject *_wrap_new_SharedGrpcConfig(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::shared_ptr< ppc::protocol::GrpcConfig > *result = 0 ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "new_SharedGrpcConfig", 0, 0, 0)) SWIG_fail; + { + try { + result = (std::shared_ptr< ppc::protocol::GrpcConfig > *)new std::shared_ptr< ppc::protocol::GrpcConfig >(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + { + std::shared_ptr< ppc::protocol::GrpcConfig > *smartresult = (result && *result) ? new std::shared_ptr< ppc::protocol::GrpcConfig >(*result) : 0; + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(smartresult), SWIGTYPE_p_std__shared_ptrT_ppc__protocol__GrpcConfig_t, SWIG_POINTER_OWN); + if (SWIG_POINTER_NEW) delete result; + } + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_delete_SharedGrpcConfig(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::shared_ptr< ppc::protocol::GrpcConfig > *arg1 = (std::shared_ptr< ppc::protocol::GrpcConfig > *) 0 ; + void *argp1 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::GrpcConfig > tempshared1 ; + PyObject *swig_obj[1] ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__GrpcConfig_t, 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_SharedGrpcConfig" "', argument " "1"" of type '" "std::shared_ptr< ppc::protocol::GrpcConfig > *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + if (argp1) tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::protocol::GrpcConfig > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::protocol::GrpcConfig > * >(argp1); + arg1 = &tempshared1; + } else { + arg1 = (argp1) ? reinterpret_cast< std::shared_ptr< ppc::protocol::GrpcConfig > * >(argp1) : &tempshared1; + } + } + { + try { + delete arg1; + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *SharedGrpcConfig_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *obj; + if (!SWIG_Python_UnpackTuple(args, "swigregister", 1, 1, &obj)) return NULL; + SWIG_TypeNewClientData(SWIGTYPE_p_std__shared_ptrT_ppc__protocol__GrpcConfig_t, SWIG_NewClientData(obj)); + return SWIG_Py_Void(); +} + +SWIGINTERN PyObject *SharedGrpcConfig_swiginit(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + return SWIG_Python_InitShadowInstance(args); +} + +SWIGINTERN PyObject *_wrap_new_SharedFront(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::shared_ptr< ppc::front::IFront > *result = 0 ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "new_SharedFront", 0, 0, 0)) SWIG_fail; + { + try { + result = (std::shared_ptr< ppc::front::IFront > *)new std::shared_ptr< ppc::front::IFront >(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + { + std::shared_ptr< ppc::front::IFront > *smartresult = (result && *result) ? new std::shared_ptr< ppc::front::IFront >(*result) : 0; + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(smartresult), SWIGTYPE_p_std__shared_ptrT_ppc__front__IFront_t, SWIG_POINTER_OWN); + if (SWIG_POINTER_NEW) delete result; + } + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_delete_SharedFront(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::shared_ptr< ppc::front::IFront > *arg1 = (std::shared_ptr< ppc::front::IFront > *) 0 ; + void *argp1 ; + int res1 = 0 ; + std::shared_ptr< ppc::front::IFront > tempshared1 ; + PyObject *swig_obj[1] ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__front__IFront_t, 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_SharedFront" "', argument " "1"" of type '" "std::shared_ptr< ppc::front::IFront > *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + if (argp1) tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::front::IFront > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::front::IFront > * >(argp1); + arg1 = &tempshared1; + } else { + arg1 = (argp1) ? reinterpret_cast< std::shared_ptr< ppc::front::IFront > * >(argp1) : &tempshared1; + } + } + { + try { + delete arg1; + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *SharedFront_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *obj; + if (!SWIG_Python_UnpackTuple(args, "swigregister", 1, 1, &obj)) return NULL; + SWIG_TypeNewClientData(SWIGTYPE_p_std__shared_ptrT_ppc__front__IFront_t, SWIG_NewClientData(obj)); + return SWIG_Py_Void(); +} + +SWIGINTERN PyObject *SharedFront_swiginit(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + return SWIG_Python_InitShadowInstance(args); +} + +SWIGINTERN PyObject *_wrap_new_SharedNodeDiscovery(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::shared_ptr< ppc::front::INodeDiscovery > *result = 0 ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "new_SharedNodeDiscovery", 0, 0, 0)) SWIG_fail; + { + try { + result = (std::shared_ptr< ppc::front::INodeDiscovery > *)new std::shared_ptr< ppc::front::INodeDiscovery >(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + { + std::shared_ptr< ppc::front::INodeDiscovery > *smartresult = (result && *result) ? new std::shared_ptr< ppc::front::INodeDiscovery >(*result) : 0; + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(smartresult), SWIGTYPE_p_std__shared_ptrT_ppc__front__INodeDiscovery_t, SWIG_POINTER_OWN); + if (SWIG_POINTER_NEW) delete result; + } + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_delete_SharedNodeDiscovery(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::shared_ptr< ppc::front::INodeDiscovery > *arg1 = (std::shared_ptr< ppc::front::INodeDiscovery > *) 0 ; + void *argp1 ; + int res1 = 0 ; + std::shared_ptr< ppc::front::INodeDiscovery > tempshared1 ; + PyObject *swig_obj[1] ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__front__INodeDiscovery_t, 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_SharedNodeDiscovery" "', argument " "1"" of type '" "std::shared_ptr< ppc::front::INodeDiscovery > *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + if (argp1) tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::front::INodeDiscovery > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::front::INodeDiscovery > * >(argp1); + arg1 = &tempshared1; + } else { + arg1 = (argp1) ? reinterpret_cast< std::shared_ptr< ppc::front::INodeDiscovery > * >(argp1) : &tempshared1; + } + } + { + try { + delete arg1; + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *SharedNodeDiscovery_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *obj; + if (!SWIG_Python_UnpackTuple(args, "swigregister", 1, 1, &obj)) return NULL; + SWIG_TypeNewClientData(SWIGTYPE_p_std__shared_ptrT_ppc__front__INodeDiscovery_t, SWIG_NewClientData(obj)); + return SWIG_Py_Void(); +} + +SWIGINTERN PyObject *SharedNodeDiscovery_swiginit(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + return SWIG_Python_InitShadowInstance(args); +} + +SWIGINTERN PyObject *_wrap_new_SharedNodeInfo(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::shared_ptr< ppc::protocol::INodeInfo > *result = 0 ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "new_SharedNodeInfo", 0, 0, 0)) SWIG_fail; + { + try { + result = (std::shared_ptr< ppc::protocol::INodeInfo > *)new std::shared_ptr< ppc::protocol::INodeInfo >(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + { + std::shared_ptr< ppc::protocol::INodeInfo > *smartresult = (result && *result) ? new std::shared_ptr< ppc::protocol::INodeInfo >(*result) : 0; + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(smartresult), SWIGTYPE_p_std__shared_ptrT_ppc__protocol__INodeInfo_t, SWIG_POINTER_OWN); + if (SWIG_POINTER_NEW) delete result; + } + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_delete_SharedNodeInfo(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::shared_ptr< ppc::protocol::INodeInfo > *arg1 = (std::shared_ptr< ppc::protocol::INodeInfo > *) 0 ; + void *argp1 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::INodeInfo > tempshared1 ; + PyObject *swig_obj[1] ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__INodeInfo_t, 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_SharedNodeInfo" "', argument " "1"" of type '" "std::shared_ptr< ppc::protocol::INodeInfo > *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + if (argp1) tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::protocol::INodeInfo > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::protocol::INodeInfo > * >(argp1); + arg1 = &tempshared1; + } else { + arg1 = (argp1) ? reinterpret_cast< std::shared_ptr< ppc::protocol::INodeInfo > * >(argp1) : &tempshared1; + } + } + { + try { + delete arg1; + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *SharedNodeInfo_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *obj; + if (!SWIG_Python_UnpackTuple(args, "swigregister", 1, 1, &obj)) return NULL; + SWIG_TypeNewClientData(SWIGTYPE_p_std__shared_ptrT_ppc__protocol__INodeInfo_t, SWIG_NewClientData(obj)); + return SWIG_Py_Void(); +} + +SWIGINTERN PyObject *SharedNodeInfo_swiginit(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + return SWIG_Python_InitShadowInstance(args); +} + +SWIGINTERN PyObject *_wrap_new_SharedFrontClient(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::shared_ptr< ppc::front::IFrontClient > *result = 0 ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "new_SharedFrontClient", 0, 0, 0)) SWIG_fail; + { + try { + result = (std::shared_ptr< ppc::front::IFrontClient > *)new std::shared_ptr< ppc::front::IFrontClient >(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + { + std::shared_ptr< ppc::front::IFrontClient > *smartresult = (result && *result) ? new std::shared_ptr< ppc::front::IFrontClient >(*result) : 0; + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(smartresult), SWIGTYPE_p_std__shared_ptrT_ppc__front__IFrontClient_t, SWIG_POINTER_OWN); + if (SWIG_POINTER_NEW) delete result; + } + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_delete_SharedFrontClient(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::shared_ptr< ppc::front::IFrontClient > *arg1 = (std::shared_ptr< ppc::front::IFrontClient > *) 0 ; + void *argp1 ; + int res1 = 0 ; + std::shared_ptr< ppc::front::IFrontClient > tempshared1 ; + PyObject *swig_obj[1] ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__front__IFrontClient_t, 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_SharedFrontClient" "', argument " "1"" of type '" "std::shared_ptr< ppc::front::IFrontClient > *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + if (argp1) tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::front::IFrontClient > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::front::IFrontClient > * >(argp1); + arg1 = &tempshared1; + } else { + arg1 = (argp1) ? reinterpret_cast< std::shared_ptr< ppc::front::IFrontClient > * >(argp1) : &tempshared1; + } + } + { + try { + delete arg1; + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *SharedFrontClient_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *obj; + if (!SWIG_Python_UnpackTuple(args, "swigregister", 1, 1, &obj)) return NULL; + SWIG_TypeNewClientData(SWIGTYPE_p_std__shared_ptrT_ppc__front__IFrontClient_t, SWIG_NewClientData(obj)); + return SWIG_Py_Void(); +} + +SWIGINTERN PyObject *SharedFrontClient_swiginit(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + return SWIG_Python_InitShadowInstance(args); +} + +SWIGINTERN PyObject *_wrap_new_SharedErrorCallback(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::shared_ptr< ppc::front::ErrorCallback > *result = 0 ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "new_SharedErrorCallback", 0, 0, 0)) SWIG_fail; + { + try { + result = (std::shared_ptr< ppc::front::ErrorCallback > *)new std::shared_ptr< ppc::front::ErrorCallback >(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + { + std::shared_ptr< ppc::front::ErrorCallback > *smartresult = (result && *result) ? new std::shared_ptr< ppc::front::ErrorCallback >(*result) : 0; + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(smartresult), SWIGTYPE_p_std__shared_ptrT_ppc__front__ErrorCallback_t, SWIG_POINTER_OWN); + if (SWIG_POINTER_NEW) delete result; + } + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_delete_SharedErrorCallback(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::shared_ptr< ppc::front::ErrorCallback > *arg1 = (std::shared_ptr< ppc::front::ErrorCallback > *) 0 ; + void *argp1 ; + int res1 = 0 ; + std::shared_ptr< ppc::front::ErrorCallback > tempshared1 ; + PyObject *swig_obj[1] ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__front__ErrorCallback_t, 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_SharedErrorCallback" "', argument " "1"" of type '" "std::shared_ptr< ppc::front::ErrorCallback > *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + if (argp1) tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::front::ErrorCallback > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::front::ErrorCallback > * >(argp1); + arg1 = &tempshared1; + } else { + arg1 = (argp1) ? reinterpret_cast< std::shared_ptr< ppc::front::ErrorCallback > * >(argp1) : &tempshared1; + } + } + { + try { + delete arg1; + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *SharedErrorCallback_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *obj; + if (!SWIG_Python_UnpackTuple(args, "swigregister", 1, 1, &obj)) return NULL; + SWIG_TypeNewClientData(SWIGTYPE_p_std__shared_ptrT_ppc__front__ErrorCallback_t, SWIG_NewClientData(obj)); + return SWIG_Py_Void(); +} + +SWIGINTERN PyObject *SharedErrorCallback_swiginit(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + return SWIG_Python_InitShadowInstance(args); +} + +SWIGINTERN PyObject *_wrap_new_SharedMessageDispatcherHandler(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::shared_ptr< ppc::front::MessageDispatcherHandler > *result = 0 ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "new_SharedMessageDispatcherHandler", 0, 0, 0)) SWIG_fail; + { + try { + result = (std::shared_ptr< ppc::front::MessageDispatcherHandler > *)new std::shared_ptr< ppc::front::MessageDispatcherHandler >(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + { + std::shared_ptr< ppc::front::MessageDispatcherHandler > *smartresult = (result && *result) ? new std::shared_ptr< ppc::front::MessageDispatcherHandler >(*result) : 0; + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(smartresult), SWIGTYPE_p_std__shared_ptrT_ppc__front__MessageDispatcherHandler_t, SWIG_POINTER_OWN); + if (SWIG_POINTER_NEW) delete result; + } + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_delete_SharedMessageDispatcherHandler(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::shared_ptr< ppc::front::MessageDispatcherHandler > *arg1 = (std::shared_ptr< ppc::front::MessageDispatcherHandler > *) 0 ; + void *argp1 ; + int res1 = 0 ; + std::shared_ptr< ppc::front::MessageDispatcherHandler > tempshared1 ; + PyObject *swig_obj[1] ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__front__MessageDispatcherHandler_t, 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_SharedMessageDispatcherHandler" "', argument " "1"" of type '" "std::shared_ptr< ppc::front::MessageDispatcherHandler > *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + if (argp1) tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::front::MessageDispatcherHandler > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::front::MessageDispatcherHandler > * >(argp1); + arg1 = &tempshared1; + } else { + arg1 = (argp1) ? reinterpret_cast< std::shared_ptr< ppc::front::MessageDispatcherHandler > * >(argp1) : &tempshared1; + } + } + { + try { + delete arg1; + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *SharedMessageDispatcherHandler_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *obj; + if (!SWIG_Python_UnpackTuple(args, "swigregister", 1, 1, &obj)) return NULL; + SWIG_TypeNewClientData(SWIGTYPE_p_std__shared_ptrT_ppc__front__MessageDispatcherHandler_t, SWIG_NewClientData(obj)); + return SWIG_Py_Void(); +} + +SWIGINTERN PyObject *SharedMessageDispatcherHandler_swiginit(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + return SWIG_Python_InitShadowInstance(args); +} + +SWIGINTERN PyObject *_wrap_new_SharedIMessageHandler(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::shared_ptr< ppc::front::IMessageHandler > *result = 0 ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "new_SharedIMessageHandler", 0, 0, 0)) SWIG_fail; + { + try { + result = (std::shared_ptr< ppc::front::IMessageHandler > *)new std::shared_ptr< ppc::front::IMessageHandler >(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + { + std::shared_ptr< ppc::front::IMessageHandler > *smartresult = (result && *result) ? new std::shared_ptr< ppc::front::IMessageHandler >(*result) : 0; + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(smartresult), SWIGTYPE_p_std__shared_ptrT_ppc__front__IMessageHandler_t, SWIG_POINTER_OWN); + if (SWIG_POINTER_NEW) delete result; + } + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_delete_SharedIMessageHandler(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::shared_ptr< ppc::front::IMessageHandler > *arg1 = (std::shared_ptr< ppc::front::IMessageHandler > *) 0 ; + void *argp1 ; + int res1 = 0 ; + std::shared_ptr< ppc::front::IMessageHandler > tempshared1 ; + PyObject *swig_obj[1] ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__front__IMessageHandler_t, 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_SharedIMessageHandler" "', argument " "1"" of type '" "std::shared_ptr< ppc::front::IMessageHandler > *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + if (argp1) tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::front::IMessageHandler > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::front::IMessageHandler > * >(argp1); + arg1 = &tempshared1; + } else { + arg1 = (argp1) ? reinterpret_cast< std::shared_ptr< ppc::front::IMessageHandler > * >(argp1) : &tempshared1; + } + } + { + try { + delete arg1; + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *SharedIMessageHandler_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *obj; + if (!SWIG_Python_UnpackTuple(args, "swigregister", 1, 1, &obj)) return NULL; + SWIG_TypeNewClientData(SWIGTYPE_p_std__shared_ptrT_ppc__front__IMessageHandler_t, SWIG_NewClientData(obj)); + return SWIG_Py_Void(); +} + +SWIGINTERN PyObject *SharedIMessageHandler_swiginit(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + return SWIG_Python_InitShadowInstance(args); +} + +SWIGINTERN PyObject *_wrap_new_SharedGetPeersInfoHandler(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::shared_ptr< ppc::front::GetPeersInfoHandler > *result = 0 ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "new_SharedGetPeersInfoHandler", 0, 0, 0)) SWIG_fail; + { + try { + result = (std::shared_ptr< ppc::front::GetPeersInfoHandler > *)new std::shared_ptr< ppc::front::GetPeersInfoHandler >(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + { + std::shared_ptr< ppc::front::GetPeersInfoHandler > *smartresult = (result && *result) ? new std::shared_ptr< ppc::front::GetPeersInfoHandler >(*result) : 0; + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(smartresult), SWIGTYPE_p_std__shared_ptrT_ppc__front__GetPeersInfoHandler_t, SWIG_POINTER_OWN); + if (SWIG_POINTER_NEW) delete result; + } + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_delete_SharedGetPeersInfoHandler(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::shared_ptr< ppc::front::GetPeersInfoHandler > *arg1 = (std::shared_ptr< ppc::front::GetPeersInfoHandler > *) 0 ; + void *argp1 ; + int res1 = 0 ; + std::shared_ptr< ppc::front::GetPeersInfoHandler > tempshared1 ; + PyObject *swig_obj[1] ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__front__GetPeersInfoHandler_t, 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_SharedGetPeersInfoHandler" "', argument " "1"" of type '" "std::shared_ptr< ppc::front::GetPeersInfoHandler > *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + if (argp1) tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::front::GetPeersInfoHandler > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::front::GetPeersInfoHandler > * >(argp1); + arg1 = &tempshared1; + } else { + arg1 = (argp1) ? reinterpret_cast< std::shared_ptr< ppc::front::GetPeersInfoHandler > * >(argp1) : &tempshared1; + } + } + { + try { + delete arg1; + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *SharedGetPeersInfoHandler_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *obj; + if (!SWIG_Python_UnpackTuple(args, "swigregister", 1, 1, &obj)) return NULL; + SWIG_TypeNewClientData(SWIGTYPE_p_std__shared_ptrT_ppc__front__GetPeersInfoHandler_t, SWIG_NewClientData(obj)); + return SWIG_Py_Void(); +} + +SWIGINTERN PyObject *SharedGetPeersInfoHandler_swiginit(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + return SWIG_Python_InitShadowInstance(args); +} + +SWIGINTERN PyObject *_wrap_new_SharedGateway(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::shared_ptr< ppc::gateway::IGateway > *result = 0 ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "new_SharedGateway", 0, 0, 0)) SWIG_fail; + { + try { + result = (std::shared_ptr< ppc::gateway::IGateway > *)new std::shared_ptr< ppc::gateway::IGateway >(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + { + std::shared_ptr< ppc::gateway::IGateway > *smartresult = (result && *result) ? new std::shared_ptr< ppc::gateway::IGateway >(*result) : 0; + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(smartresult), SWIGTYPE_p_std__shared_ptrT_ppc__gateway__IGateway_t, SWIG_POINTER_OWN); + if (SWIG_POINTER_NEW) delete result; + } + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_delete_SharedGateway(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::shared_ptr< ppc::gateway::IGateway > *arg1 = (std::shared_ptr< ppc::gateway::IGateway > *) 0 ; + void *argp1 ; + int res1 = 0 ; + std::shared_ptr< ppc::gateway::IGateway > tempshared1 ; + PyObject *swig_obj[1] ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__gateway__IGateway_t, 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_SharedGateway" "', argument " "1"" of type '" "std::shared_ptr< ppc::gateway::IGateway > *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + if (argp1) tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::gateway::IGateway > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::gateway::IGateway > * >(argp1); + arg1 = &tempshared1; + } else { + arg1 = (argp1) ? reinterpret_cast< std::shared_ptr< ppc::gateway::IGateway > * >(argp1) : &tempshared1; + } + } + { + try { + delete arg1; + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *SharedGateway_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *obj; + if (!SWIG_Python_UnpackTuple(args, "swigregister", 1, 1, &obj)) return NULL; + SWIG_TypeNewClientData(SWIGTYPE_p_std__shared_ptrT_ppc__gateway__IGateway_t, SWIG_NewClientData(obj)); + return SWIG_Py_Void(); +} + +SWIGINTERN PyObject *SharedGateway_swiginit(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + return SWIG_Python_InitShadowInstance(args); +} + +SWIGINTERN PyObject *_wrap_new_SharedMessage(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::shared_ptr< ppc::protocol::Message > *result = 0 ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "new_SharedMessage", 0, 0, 0)) SWIG_fail; + { + try { + result = (std::shared_ptr< ppc::protocol::Message > *)new std::shared_ptr< ppc::protocol::Message >(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + { + std::shared_ptr< ppc::protocol::Message > *smartresult = (result && *result) ? new std::shared_ptr< ppc::protocol::Message >(*result) : 0; + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(smartresult), SWIGTYPE_p_std__shared_ptrT_ppc__protocol__Message_t, SWIG_POINTER_OWN); + if (SWIG_POINTER_NEW) delete result; + } + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_delete_SharedMessage(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::shared_ptr< ppc::protocol::Message > *arg1 = (std::shared_ptr< ppc::protocol::Message > *) 0 ; + void *argp1 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::Message > tempshared1 ; + PyObject *swig_obj[1] ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__Message_t, 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_SharedMessage" "', argument " "1"" of type '" "std::shared_ptr< ppc::protocol::Message > *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + if (argp1) tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::protocol::Message > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::protocol::Message > * >(argp1); + arg1 = &tempshared1; + } else { + arg1 = (argp1) ? reinterpret_cast< std::shared_ptr< ppc::protocol::Message > * >(argp1) : &tempshared1; + } + } + { + try { + delete arg1; + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *SharedMessage_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *obj; + if (!SWIG_Python_UnpackTuple(args, "swigregister", 1, 1, &obj)) return NULL; + SWIG_TypeNewClientData(SWIGTYPE_p_std__shared_ptrT_ppc__protocol__Message_t, SWIG_NewClientData(obj)); + return SWIG_Py_Void(); +} + +SWIGINTERN PyObject *SharedMessage_swiginit(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + return SWIG_Python_InitShadowInstance(args); +} + +SWIGINTERN PyObject *_wrap_new_SharedMessageHeader(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::shared_ptr< ppc::protocol::MessageHeader > *result = 0 ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "new_SharedMessageHeader", 0, 0, 0)) SWIG_fail; + { + try { + result = (std::shared_ptr< ppc::protocol::MessageHeader > *)new std::shared_ptr< ppc::protocol::MessageHeader >(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + { + std::shared_ptr< ppc::protocol::MessageHeader > *smartresult = (result && *result) ? new std::shared_ptr< ppc::protocol::MessageHeader >(*result) : 0; + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(smartresult), SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageHeader_t, SWIG_POINTER_OWN); + if (SWIG_POINTER_NEW) delete result; + } + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_delete_SharedMessageHeader(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::shared_ptr< ppc::protocol::MessageHeader > *arg1 = (std::shared_ptr< ppc::protocol::MessageHeader > *) 0 ; + void *argp1 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::MessageHeader > tempshared1 ; + PyObject *swig_obj[1] ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageHeader_t, 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_SharedMessageHeader" "', argument " "1"" of type '" "std::shared_ptr< ppc::protocol::MessageHeader > *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + if (argp1) tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::protocol::MessageHeader > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::protocol::MessageHeader > * >(argp1); + arg1 = &tempshared1; + } else { + arg1 = (argp1) ? reinterpret_cast< std::shared_ptr< ppc::protocol::MessageHeader > * >(argp1) : &tempshared1; + } + } + { + try { + delete arg1; + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *SharedMessageHeader_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *obj; + if (!SWIG_Python_UnpackTuple(args, "swigregister", 1, 1, &obj)) return NULL; + SWIG_TypeNewClientData(SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageHeader_t, SWIG_NewClientData(obj)); + return SWIG_Py_Void(); +} + +SWIGINTERN PyObject *SharedMessageHeader_swiginit(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + return SWIG_Python_InitShadowInstance(args); +} + +SWIGINTERN PyObject *_wrap_new_SharedMessagePayload(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::shared_ptr< ppc::protocol::MessagePayload > *result = 0 ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "new_SharedMessagePayload", 0, 0, 0)) SWIG_fail; + { + try { + result = (std::shared_ptr< ppc::protocol::MessagePayload > *)new std::shared_ptr< ppc::protocol::MessagePayload >(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + { + std::shared_ptr< ppc::protocol::MessagePayload > *smartresult = (result && *result) ? new std::shared_ptr< ppc::protocol::MessagePayload >(*result) : 0; + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(smartresult), SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessagePayload_t, SWIG_POINTER_OWN); + if (SWIG_POINTER_NEW) delete result; + } + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_delete_SharedMessagePayload(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::shared_ptr< ppc::protocol::MessagePayload > *arg1 = (std::shared_ptr< ppc::protocol::MessagePayload > *) 0 ; + void *argp1 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::MessagePayload > tempshared1 ; + PyObject *swig_obj[1] ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessagePayload_t, 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_SharedMessagePayload" "', argument " "1"" of type '" "std::shared_ptr< ppc::protocol::MessagePayload > *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + if (argp1) tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::protocol::MessagePayload > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::protocol::MessagePayload > * >(argp1); + arg1 = &tempshared1; + } else { + arg1 = (argp1) ? reinterpret_cast< std::shared_ptr< ppc::protocol::MessagePayload > * >(argp1) : &tempshared1; + } + } + { + try { + delete arg1; + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *SharedMessagePayload_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *obj; + if (!SWIG_Python_UnpackTuple(args, "swigregister", 1, 1, &obj)) return NULL; + SWIG_TypeNewClientData(SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessagePayload_t, SWIG_NewClientData(obj)); + return SWIG_Py_Void(); +} + +SWIGINTERN PyObject *SharedMessagePayload_swiginit(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + return SWIG_Python_InitShadowInstance(args); +} + +SWIGINTERN PyObject *_wrap_new_SharedRouteInfo(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::shared_ptr< ppc::protocol::MessageOptionalHeader > *result = 0 ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "new_SharedRouteInfo", 0, 0, 0)) SWIG_fail; + { + try { + result = (std::shared_ptr< ppc::protocol::MessageOptionalHeader > *)new std::shared_ptr< ppc::protocol::MessageOptionalHeader >(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + { + std::shared_ptr< ppc::protocol::MessageOptionalHeader > *smartresult = (result && *result) ? new std::shared_ptr< ppc::protocol::MessageOptionalHeader >(*result) : 0; + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(smartresult), SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageOptionalHeader_t, SWIG_POINTER_OWN); + if (SWIG_POINTER_NEW) delete result; + } + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_delete_SharedRouteInfo(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::shared_ptr< ppc::protocol::MessageOptionalHeader > *arg1 = (std::shared_ptr< ppc::protocol::MessageOptionalHeader > *) 0 ; + void *argp1 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::MessageOptionalHeader > tempshared1 ; + PyObject *swig_obj[1] ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageOptionalHeader_t, 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_SharedRouteInfo" "', argument " "1"" of type '" "std::shared_ptr< ppc::protocol::MessageOptionalHeader > *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + if (argp1) tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::protocol::MessageOptionalHeader > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::protocol::MessageOptionalHeader > * >(argp1); + arg1 = &tempshared1; + } else { + arg1 = (argp1) ? reinterpret_cast< std::shared_ptr< ppc::protocol::MessageOptionalHeader > * >(argp1) : &tempshared1; + } + } + { + try { + delete arg1; + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *SharedRouteInfo_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *obj; + if (!SWIG_Python_UnpackTuple(args, "swigregister", 1, 1, &obj)) return NULL; + SWIG_TypeNewClientData(SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageOptionalHeader_t, SWIG_NewClientData(obj)); + return SWIG_Py_Void(); +} + +SWIGINTERN PyObject *SharedRouteInfo_swiginit(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + return SWIG_Python_InitShadowInstance(args); +} + +SWIGINTERN PyObject *_wrap_new_SharedMessageBuilder(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::shared_ptr< ppc::protocol::MessageBuilder > *result = 0 ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "new_SharedMessageBuilder", 0, 0, 0)) SWIG_fail; + { + try { + result = (std::shared_ptr< ppc::protocol::MessageBuilder > *)new std::shared_ptr< ppc::protocol::MessageBuilder >(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + { + std::shared_ptr< ppc::protocol::MessageBuilder > *smartresult = (result && *result) ? new std::shared_ptr< ppc::protocol::MessageBuilder >(*result) : 0; + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(smartresult), SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageBuilder_t, SWIG_POINTER_OWN); + if (SWIG_POINTER_NEW) delete result; + } + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_delete_SharedMessageBuilder(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::shared_ptr< ppc::protocol::MessageBuilder > *arg1 = (std::shared_ptr< ppc::protocol::MessageBuilder > *) 0 ; + void *argp1 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::MessageBuilder > tempshared1 ; + PyObject *swig_obj[1] ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageBuilder_t, 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_SharedMessageBuilder" "', argument " "1"" of type '" "std::shared_ptr< ppc::protocol::MessageBuilder > *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + if (argp1) tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::protocol::MessageBuilder > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::protocol::MessageBuilder > * >(argp1); + arg1 = &tempshared1; + } else { + arg1 = (argp1) ? reinterpret_cast< std::shared_ptr< ppc::protocol::MessageBuilder > * >(argp1) : &tempshared1; + } + } + { + try { + delete arg1; + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *SharedMessageBuilder_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *obj; + if (!SWIG_Python_UnpackTuple(args, "swigregister", 1, 1, &obj)) return NULL; + SWIG_TypeNewClientData(SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageBuilder_t, SWIG_NewClientData(obj)); + return SWIG_Py_Void(); +} + +SWIGINTERN PyObject *SharedMessageBuilder_swiginit(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + return SWIG_Python_InitShadowInstance(args); +} + +SWIGINTERN PyObject *_wrap_new_SharedMessageHeaderBuilder(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::shared_ptr< ppc::protocol::MessageHeaderBuilder > *result = 0 ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "new_SharedMessageHeaderBuilder", 0, 0, 0)) SWIG_fail; + { + try { + result = (std::shared_ptr< ppc::protocol::MessageHeaderBuilder > *)new std::shared_ptr< ppc::protocol::MessageHeaderBuilder >(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + { + std::shared_ptr< ppc::protocol::MessageHeaderBuilder > *smartresult = (result && *result) ? new std::shared_ptr< ppc::protocol::MessageHeaderBuilder >(*result) : 0; + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(smartresult), SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageHeaderBuilder_t, SWIG_POINTER_OWN); + if (SWIG_POINTER_NEW) delete result; + } + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_delete_SharedMessageHeaderBuilder(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::shared_ptr< ppc::protocol::MessageHeaderBuilder > *arg1 = (std::shared_ptr< ppc::protocol::MessageHeaderBuilder > *) 0 ; + void *argp1 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::MessageHeaderBuilder > tempshared1 ; + PyObject *swig_obj[1] ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageHeaderBuilder_t, 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_SharedMessageHeaderBuilder" "', argument " "1"" of type '" "std::shared_ptr< ppc::protocol::MessageHeaderBuilder > *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + if (argp1) tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::protocol::MessageHeaderBuilder > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::protocol::MessageHeaderBuilder > * >(argp1); + arg1 = &tempshared1; + } else { + arg1 = (argp1) ? reinterpret_cast< std::shared_ptr< ppc::protocol::MessageHeaderBuilder > * >(argp1) : &tempshared1; + } + } + { + try { + delete arg1; + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *SharedMessageHeaderBuilder_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *obj; + if (!SWIG_Python_UnpackTuple(args, "swigregister", 1, 1, &obj)) return NULL; + SWIG_TypeNewClientData(SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageHeaderBuilder_t, SWIG_NewClientData(obj)); + return SWIG_Py_Void(); +} + +SWIGINTERN PyObject *SharedMessageHeaderBuilder_swiginit(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + return SWIG_Python_InitShadowInstance(args); +} + +SWIGINTERN PyObject *_wrap_new_SharedMessagePayloadBuilder(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::shared_ptr< ppc::protocol::MessagePayloadBuilder > *result = 0 ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "new_SharedMessagePayloadBuilder", 0, 0, 0)) SWIG_fail; + { + try { + result = (std::shared_ptr< ppc::protocol::MessagePayloadBuilder > *)new std::shared_ptr< ppc::protocol::MessagePayloadBuilder >(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + { + std::shared_ptr< ppc::protocol::MessagePayloadBuilder > *smartresult = (result && *result) ? new std::shared_ptr< ppc::protocol::MessagePayloadBuilder >(*result) : 0; + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(smartresult), SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessagePayloadBuilder_t, SWIG_POINTER_OWN); + if (SWIG_POINTER_NEW) delete result; + } + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_delete_SharedMessagePayloadBuilder(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::shared_ptr< ppc::protocol::MessagePayloadBuilder > *arg1 = (std::shared_ptr< ppc::protocol::MessagePayloadBuilder > *) 0 ; + void *argp1 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::MessagePayloadBuilder > tempshared1 ; + PyObject *swig_obj[1] ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessagePayloadBuilder_t, 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_SharedMessagePayloadBuilder" "', argument " "1"" of type '" "std::shared_ptr< ppc::protocol::MessagePayloadBuilder > *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + if (argp1) tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::protocol::MessagePayloadBuilder > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::protocol::MessagePayloadBuilder > * >(argp1); + arg1 = &tempshared1; + } else { + arg1 = (argp1) ? reinterpret_cast< std::shared_ptr< ppc::protocol::MessagePayloadBuilder > * >(argp1) : &tempshared1; + } + } + { + try { + delete arg1; + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *SharedMessagePayloadBuilder_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *obj; + if (!SWIG_Python_UnpackTuple(args, "swigregister", 1, 1, &obj)) return NULL; + SWIG_TypeNewClientData(SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessagePayloadBuilder_t, SWIG_NewClientData(obj)); + return SWIG_Py_Void(); +} + +SWIGINTERN PyObject *SharedMessagePayloadBuilder_swiginit(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + return SWIG_Python_InitShadowInstance(args); +} + +SWIGINTERN PyObject *_wrap_new_SharedRouteInfoBuilder(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::shared_ptr< ppc::protocol::MessageOptionalHeaderBuilder > *result = 0 ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "new_SharedRouteInfoBuilder", 0, 0, 0)) SWIG_fail; + { + try { + result = (std::shared_ptr< ppc::protocol::MessageOptionalHeaderBuilder > *)new std::shared_ptr< ppc::protocol::MessageOptionalHeaderBuilder >(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + { + std::shared_ptr< ppc::protocol::MessageOptionalHeaderBuilder > *smartresult = (result && *result) ? new std::shared_ptr< ppc::protocol::MessageOptionalHeaderBuilder >(*result) : 0; + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(smartresult), SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageOptionalHeaderBuilder_t, SWIG_POINTER_OWN); + if (SWIG_POINTER_NEW) delete result; + } + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_delete_SharedRouteInfoBuilder(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::shared_ptr< ppc::protocol::MessageOptionalHeaderBuilder > *arg1 = (std::shared_ptr< ppc::protocol::MessageOptionalHeaderBuilder > *) 0 ; + void *argp1 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::MessageOptionalHeaderBuilder > tempshared1 ; + PyObject *swig_obj[1] ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageOptionalHeaderBuilder_t, 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_SharedRouteInfoBuilder" "', argument " "1"" of type '" "std::shared_ptr< ppc::protocol::MessageOptionalHeaderBuilder > *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + if (argp1) tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::protocol::MessageOptionalHeaderBuilder > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::protocol::MessageOptionalHeaderBuilder > * >(argp1); + arg1 = &tempshared1; + } else { + arg1 = (argp1) ? reinterpret_cast< std::shared_ptr< ppc::protocol::MessageOptionalHeaderBuilder > * >(argp1) : &tempshared1; + } + } + { + try { + delete arg1; + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *SharedRouteInfoBuilder_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *obj; + if (!SWIG_Python_UnpackTuple(args, "swigregister", 1, 1, &obj)) return NULL; + SWIG_TypeNewClientData(SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageOptionalHeaderBuilder_t, SWIG_NewClientData(obj)); + return SWIG_Py_Void(); +} + +SWIGINTERN PyObject *SharedRouteInfoBuilder_swiginit(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + return SWIG_Python_InitShadowInstance(args); +} + +SWIGINTERN PyObject *_wrap_ubytes_iterator(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< uint8_t > *arg1 = (std::vector< uint8_t > *) 0 ; + PyObject **arg2 = (PyObject **) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + swig::SwigPyIterator *result = 0 ; + + arg2 = &swig_obj[0]; + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_uint8_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ubytes_iterator" "', argument " "1"" of type '" "std::vector< uint8_t > *""'"); + } + arg1 = reinterpret_cast< std::vector< uint8_t > * >(argp1); + result = (swig::SwigPyIterator *)std_vector_Sl_uint8_t_Sg__iterator(arg1,arg2); + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_swig__SwigPyIterator, SWIG_POINTER_OWN | 0 ); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ubytes___nonzero__(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< uint8_t > *arg1 = (std::vector< uint8_t > *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + bool result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_uint8_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ubytes___nonzero__" "', argument " "1"" of type '" "std::vector< uint8_t > const *""'"); + } + arg1 = reinterpret_cast< std::vector< uint8_t > * >(argp1); + result = (bool)std_vector_Sl_uint8_t_Sg____nonzero__((std::vector< unsigned char > const *)arg1); + resultobj = SWIG_From_bool(static_cast< bool >(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ubytes___bool__(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< uint8_t > *arg1 = (std::vector< uint8_t > *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + bool result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_uint8_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ubytes___bool__" "', argument " "1"" of type '" "std::vector< uint8_t > const *""'"); + } + arg1 = reinterpret_cast< std::vector< uint8_t > * >(argp1); + result = (bool)std_vector_Sl_uint8_t_Sg____bool__((std::vector< unsigned char > const *)arg1); + resultobj = SWIG_From_bool(static_cast< bool >(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ubytes___len__(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< uint8_t > *arg1 = (std::vector< uint8_t > *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + std::vector< unsigned char >::size_type result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_uint8_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ubytes___len__" "', argument " "1"" of type '" "std::vector< uint8_t > const *""'"); + } + arg1 = reinterpret_cast< std::vector< uint8_t > * >(argp1); + result = std_vector_Sl_uint8_t_Sg____len__((std::vector< unsigned char > const *)arg1); + resultobj = SWIG_From_size_t(static_cast< size_t >(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ubytes___getslice__(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< uint8_t > *arg1 = (std::vector< uint8_t > *) 0 ; + std::vector< unsigned char >::difference_type arg2 ; + std::vector< unsigned char >::difference_type arg3 ; + void *argp1 = 0 ; + int res1 = 0 ; + ptrdiff_t val2 ; + int ecode2 = 0 ; + ptrdiff_t val3 ; + int ecode3 = 0 ; + PyObject *swig_obj[3] ; + std::vector< unsigned char,std::allocator< unsigned char > > *result = 0 ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "ubytes___getslice__", 3, 3, swig_obj)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_uint8_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ubytes___getslice__" "', argument " "1"" of type '" "std::vector< uint8_t > *""'"); + } + arg1 = reinterpret_cast< std::vector< uint8_t > * >(argp1); + ecode2 = SWIG_AsVal_ptrdiff_t(swig_obj[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ubytes___getslice__" "', argument " "2"" of type '" "std::vector< unsigned char >::difference_type""'"); + } + arg2 = static_cast< std::vector< unsigned char >::difference_type >(val2); + ecode3 = SWIG_AsVal_ptrdiff_t(swig_obj[2], &val3); + if (!SWIG_IsOK(ecode3)) { + SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "ubytes___getslice__" "', argument " "3"" of type '" "std::vector< unsigned char >::difference_type""'"); + } + arg3 = static_cast< std::vector< unsigned char >::difference_type >(val3); + try { + result = (std::vector< unsigned char,std::allocator< unsigned char > > *)std_vector_Sl_uint8_t_Sg____getslice__(arg1,SWIG_STD_MOVE(arg2),SWIG_STD_MOVE(arg3)); + } catch(std::out_of_range &_e) { + SWIG_exception_fail(SWIG_IndexError, (&_e)->what()); + } catch(std::invalid_argument &_e) { + SWIG_exception_fail(SWIG_ValueError, (&_e)->what()); + } + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorT_uint8_t_t, SWIG_POINTER_OWN | 0 ); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ubytes___setslice____SWIG_0(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + std::vector< uint8_t > *arg1 = (std::vector< uint8_t > *) 0 ; + std::vector< unsigned char >::difference_type arg2 ; + std::vector< unsigned char >::difference_type arg3 ; + void *argp1 = 0 ; + int res1 = 0 ; + ptrdiff_t val2 ; + int ecode2 = 0 ; + ptrdiff_t val3 ; + int ecode3 = 0 ; + + (void)self; + if ((nobjs < 3) || (nobjs > 3)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_uint8_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ubytes___setslice__" "', argument " "1"" of type '" "std::vector< uint8_t > *""'"); + } + arg1 = reinterpret_cast< std::vector< uint8_t > * >(argp1); + ecode2 = SWIG_AsVal_ptrdiff_t(swig_obj[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ubytes___setslice__" "', argument " "2"" of type '" "std::vector< unsigned char >::difference_type""'"); + } + arg2 = static_cast< std::vector< unsigned char >::difference_type >(val2); + ecode3 = SWIG_AsVal_ptrdiff_t(swig_obj[2], &val3); + if (!SWIG_IsOK(ecode3)) { + SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "ubytes___setslice__" "', argument " "3"" of type '" "std::vector< unsigned char >::difference_type""'"); + } + arg3 = static_cast< std::vector< unsigned char >::difference_type >(val3); + try { + std_vector_Sl_uint8_t_Sg____setslice____SWIG_0(arg1,SWIG_STD_MOVE(arg2),SWIG_STD_MOVE(arg3)); + } catch(std::out_of_range &_e) { + SWIG_exception_fail(SWIG_IndexError, (&_e)->what()); + } catch(std::invalid_argument &_e) { + SWIG_exception_fail(SWIG_ValueError, (&_e)->what()); + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ubytes___setslice____SWIG_1(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + std::vector< uint8_t > *arg1 = (std::vector< uint8_t > *) 0 ; + std::vector< unsigned char >::difference_type arg2 ; + std::vector< unsigned char >::difference_type arg3 ; + std::vector< unsigned char,std::allocator< unsigned char > > *arg4 = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + ptrdiff_t val2 ; + int ecode2 = 0 ; + ptrdiff_t val3 ; + int ecode3 = 0 ; + int res4 = SWIG_OLDOBJ ; + + (void)self; + if ((nobjs < 4) || (nobjs > 4)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_uint8_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ubytes___setslice__" "', argument " "1"" of type '" "std::vector< uint8_t > *""'"); + } + arg1 = reinterpret_cast< std::vector< uint8_t > * >(argp1); + ecode2 = SWIG_AsVal_ptrdiff_t(swig_obj[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ubytes___setslice__" "', argument " "2"" of type '" "std::vector< unsigned char >::difference_type""'"); + } + arg2 = static_cast< std::vector< unsigned char >::difference_type >(val2); + ecode3 = SWIG_AsVal_ptrdiff_t(swig_obj[2], &val3); + if (!SWIG_IsOK(ecode3)) { + SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "ubytes___setslice__" "', argument " "3"" of type '" "std::vector< unsigned char >::difference_type""'"); + } + arg3 = static_cast< std::vector< unsigned char >::difference_type >(val3); + { + std::vector< unsigned char,std::allocator< unsigned char > > *ptr = (std::vector< unsigned char,std::allocator< unsigned char > > *)0; + res4 = swig::asptr(swig_obj[3], &ptr); + if (!SWIG_IsOK(res4)) { + SWIG_exception_fail(SWIG_ArgError(res4), "in method '" "ubytes___setslice__" "', argument " "4"" of type '" "std::vector< unsigned char,std::allocator< unsigned char > > const &""'"); + } + if (!ptr) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "ubytes___setslice__" "', argument " "4"" of type '" "std::vector< unsigned char,std::allocator< unsigned char > > const &""'"); + } + arg4 = ptr; + } + try { + std_vector_Sl_uint8_t_Sg____setslice____SWIG_1(arg1,SWIG_STD_MOVE(arg2),SWIG_STD_MOVE(arg3),(std::vector< unsigned char,std::allocator< unsigned char > > const &)*arg4); + } catch(std::out_of_range &_e) { + SWIG_exception_fail(SWIG_IndexError, (&_e)->what()); + } catch(std::invalid_argument &_e) { + SWIG_exception_fail(SWIG_ValueError, (&_e)->what()); + } + resultobj = SWIG_Py_Void(); + if (SWIG_IsNewObj(res4)) delete arg4; + return resultobj; +fail: + if (SWIG_IsNewObj(res4)) delete arg4; + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ubytes___setslice__(PyObject *self, PyObject *args) { + Py_ssize_t argc; + PyObject *argv[5] = { + 0 + }; + + if (!(argc = SWIG_Python_UnpackTuple(args, "ubytes___setslice__", 0, 4, argv))) SWIG_fail; + --argc; + if (argc == 3) { + int _v = 0; + int res = swig::asptr(argv[0], (std::vector< unsigned char,std::allocator< unsigned char > >**)(0)); + _v = SWIG_CheckState(res); + if (_v) { + { + int res = SWIG_AsVal_ptrdiff_t(argv[1], NULL); + _v = SWIG_CheckState(res); + } + if (_v) { + { + int res = SWIG_AsVal_ptrdiff_t(argv[2], NULL); + _v = SWIG_CheckState(res); + } + if (_v) { + return _wrap_ubytes___setslice____SWIG_0(self, argc, argv); + } + } + } + } + if (argc == 4) { + int _v = 0; + int res = swig::asptr(argv[0], (std::vector< unsigned char,std::allocator< unsigned char > >**)(0)); + _v = SWIG_CheckState(res); + if (_v) { + { + int res = SWIG_AsVal_ptrdiff_t(argv[1], NULL); + _v = SWIG_CheckState(res); + } + if (_v) { + { + int res = SWIG_AsVal_ptrdiff_t(argv[2], NULL); + _v = SWIG_CheckState(res); + } + if (_v) { + int res = swig::asptr(argv[3], (std::vector< unsigned char,std::allocator< unsigned char > >**)(0)); + _v = SWIG_CheckState(res); + if (_v) { + return _wrap_ubytes___setslice____SWIG_1(self, argc, argv); + } + } + } + } + } + +fail: + SWIG_Python_RaiseOrModifyTypeError("Wrong number or type of arguments for overloaded function 'ubytes___setslice__'.\n" + " Possible C/C++ prototypes are:\n" + " std::vector< uint8_t >::__setslice__(std::vector< unsigned char >::difference_type,std::vector< unsigned char >::difference_type)\n" + " std::vector< uint8_t >::__setslice__(std::vector< unsigned char >::difference_type,std::vector< unsigned char >::difference_type,std::vector< unsigned char,std::allocator< unsigned char > > const &)\n"); + return 0; +} + + +SWIGINTERN PyObject *_wrap_ubytes___delslice__(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< uint8_t > *arg1 = (std::vector< uint8_t > *) 0 ; + std::vector< unsigned char >::difference_type arg2 ; + std::vector< unsigned char >::difference_type arg3 ; + void *argp1 = 0 ; + int res1 = 0 ; + ptrdiff_t val2 ; + int ecode2 = 0 ; + ptrdiff_t val3 ; + int ecode3 = 0 ; + PyObject *swig_obj[3] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "ubytes___delslice__", 3, 3, swig_obj)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_uint8_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ubytes___delslice__" "', argument " "1"" of type '" "std::vector< uint8_t > *""'"); + } + arg1 = reinterpret_cast< std::vector< uint8_t > * >(argp1); + ecode2 = SWIG_AsVal_ptrdiff_t(swig_obj[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ubytes___delslice__" "', argument " "2"" of type '" "std::vector< unsigned char >::difference_type""'"); + } + arg2 = static_cast< std::vector< unsigned char >::difference_type >(val2); + ecode3 = SWIG_AsVal_ptrdiff_t(swig_obj[2], &val3); + if (!SWIG_IsOK(ecode3)) { + SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "ubytes___delslice__" "', argument " "3"" of type '" "std::vector< unsigned char >::difference_type""'"); + } + arg3 = static_cast< std::vector< unsigned char >::difference_type >(val3); + try { + std_vector_Sl_uint8_t_Sg____delslice__(arg1,SWIG_STD_MOVE(arg2),SWIG_STD_MOVE(arg3)); + } catch(std::out_of_range &_e) { + SWIG_exception_fail(SWIG_IndexError, (&_e)->what()); + } catch(std::invalid_argument &_e) { + SWIG_exception_fail(SWIG_ValueError, (&_e)->what()); + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ubytes___delitem____SWIG_0(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + std::vector< uint8_t > *arg1 = (std::vector< uint8_t > *) 0 ; + std::vector< unsigned char >::difference_type arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + ptrdiff_t val2 ; + int ecode2 = 0 ; + + (void)self; + if ((nobjs < 2) || (nobjs > 2)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_uint8_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ubytes___delitem__" "', argument " "1"" of type '" "std::vector< uint8_t > *""'"); + } + arg1 = reinterpret_cast< std::vector< uint8_t > * >(argp1); + ecode2 = SWIG_AsVal_ptrdiff_t(swig_obj[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ubytes___delitem__" "', argument " "2"" of type '" "std::vector< unsigned char >::difference_type""'"); + } + arg2 = static_cast< std::vector< unsigned char >::difference_type >(val2); + try { + std_vector_Sl_uint8_t_Sg____delitem____SWIG_0(arg1,SWIG_STD_MOVE(arg2)); + } catch(std::out_of_range &_e) { + SWIG_exception_fail(SWIG_IndexError, (&_e)->what()); + } catch(std::invalid_argument &_e) { + SWIG_exception_fail(SWIG_ValueError, (&_e)->what()); + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ubytes___getitem____SWIG_0(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + std::vector< uint8_t > *arg1 = (std::vector< uint8_t > *) 0 ; + SWIGPY_SLICEOBJECT *arg2 = (SWIGPY_SLICEOBJECT *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::vector< unsigned char,std::allocator< unsigned char > > *result = 0 ; + + (void)self; + if ((nobjs < 2) || (nobjs > 2)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_uint8_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ubytes___getitem__" "', argument " "1"" of type '" "std::vector< uint8_t > *""'"); + } + arg1 = reinterpret_cast< std::vector< uint8_t > * >(argp1); + { + if (!PySlice_Check(swig_obj[1])) { + SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "ubytes___getitem__" "', argument " "2"" of type '" "SWIGPY_SLICEOBJECT *""'"); + } + arg2 = (SWIGPY_SLICEOBJECT *) swig_obj[1]; + } + try { + result = (std::vector< unsigned char,std::allocator< unsigned char > > *)std_vector_Sl_uint8_t_Sg____getitem____SWIG_0(arg1,arg2); + } catch(std::out_of_range &_e) { + SWIG_exception_fail(SWIG_IndexError, (&_e)->what()); + } catch(std::invalid_argument &_e) { + SWIG_exception_fail(SWIG_ValueError, (&_e)->what()); + } + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorT_uint8_t_t, SWIG_POINTER_OWN | 0 ); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ubytes___setitem____SWIG_0(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + std::vector< uint8_t > *arg1 = (std::vector< uint8_t > *) 0 ; + SWIGPY_SLICEOBJECT *arg2 = (SWIGPY_SLICEOBJECT *) 0 ; + std::vector< unsigned char,std::allocator< unsigned char > > *arg3 = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + int res3 = SWIG_OLDOBJ ; + + (void)self; + if ((nobjs < 3) || (nobjs > 3)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_uint8_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ubytes___setitem__" "', argument " "1"" of type '" "std::vector< uint8_t > *""'"); + } + arg1 = reinterpret_cast< std::vector< uint8_t > * >(argp1); + { + if (!PySlice_Check(swig_obj[1])) { + SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "ubytes___setitem__" "', argument " "2"" of type '" "SWIGPY_SLICEOBJECT *""'"); + } + arg2 = (SWIGPY_SLICEOBJECT *) swig_obj[1]; + } + { + std::vector< unsigned char,std::allocator< unsigned char > > *ptr = (std::vector< unsigned char,std::allocator< unsigned char > > *)0; + res3 = swig::asptr(swig_obj[2], &ptr); + if (!SWIG_IsOK(res3)) { + SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "ubytes___setitem__" "', argument " "3"" of type '" "std::vector< unsigned char,std::allocator< unsigned char > > const &""'"); + } + if (!ptr) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "ubytes___setitem__" "', argument " "3"" of type '" "std::vector< unsigned char,std::allocator< unsigned char > > const &""'"); + } + arg3 = ptr; + } + try { + std_vector_Sl_uint8_t_Sg____setitem____SWIG_0(arg1,arg2,(std::vector< unsigned char,std::allocator< unsigned char > > const &)*arg3); + } catch(std::out_of_range &_e) { + SWIG_exception_fail(SWIG_IndexError, (&_e)->what()); + } catch(std::invalid_argument &_e) { + SWIG_exception_fail(SWIG_ValueError, (&_e)->what()); + } + resultobj = SWIG_Py_Void(); + if (SWIG_IsNewObj(res3)) delete arg3; + return resultobj; +fail: + if (SWIG_IsNewObj(res3)) delete arg3; + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ubytes___setitem____SWIG_1(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + std::vector< uint8_t > *arg1 = (std::vector< uint8_t > *) 0 ; + SWIGPY_SLICEOBJECT *arg2 = (SWIGPY_SLICEOBJECT *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + + (void)self; + if ((nobjs < 2) || (nobjs > 2)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_uint8_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ubytes___setitem__" "', argument " "1"" of type '" "std::vector< uint8_t > *""'"); + } + arg1 = reinterpret_cast< std::vector< uint8_t > * >(argp1); + { + if (!PySlice_Check(swig_obj[1])) { + SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "ubytes___setitem__" "', argument " "2"" of type '" "SWIGPY_SLICEOBJECT *""'"); + } + arg2 = (SWIGPY_SLICEOBJECT *) swig_obj[1]; + } + try { + std_vector_Sl_uint8_t_Sg____setitem____SWIG_1(arg1,arg2); + } catch(std::out_of_range &_e) { + SWIG_exception_fail(SWIG_IndexError, (&_e)->what()); + } catch(std::invalid_argument &_e) { + SWIG_exception_fail(SWIG_ValueError, (&_e)->what()); + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ubytes___delitem____SWIG_1(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + std::vector< uint8_t > *arg1 = (std::vector< uint8_t > *) 0 ; + SWIGPY_SLICEOBJECT *arg2 = (SWIGPY_SLICEOBJECT *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + + (void)self; + if ((nobjs < 2) || (nobjs > 2)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_uint8_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ubytes___delitem__" "', argument " "1"" of type '" "std::vector< uint8_t > *""'"); + } + arg1 = reinterpret_cast< std::vector< uint8_t > * >(argp1); + { + if (!PySlice_Check(swig_obj[1])) { + SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "ubytes___delitem__" "', argument " "2"" of type '" "SWIGPY_SLICEOBJECT *""'"); + } + arg2 = (SWIGPY_SLICEOBJECT *) swig_obj[1]; + } + try { + std_vector_Sl_uint8_t_Sg____delitem____SWIG_1(arg1,arg2); + } catch(std::out_of_range &_e) { + SWIG_exception_fail(SWIG_IndexError, (&_e)->what()); + } catch(std::invalid_argument &_e) { + SWIG_exception_fail(SWIG_ValueError, (&_e)->what()); + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ubytes___delitem__(PyObject *self, PyObject *args) { + Py_ssize_t argc; + PyObject *argv[3] = { + 0 + }; + + if (!(argc = SWIG_Python_UnpackTuple(args, "ubytes___delitem__", 0, 2, argv))) SWIG_fail; + --argc; + if (argc == 2) { + int _v = 0; + int res = swig::asptr(argv[0], (std::vector< unsigned char,std::allocator< unsigned char > >**)(0)); + _v = SWIG_CheckState(res); + if (_v) { + { + _v = PySlice_Check(argv[1]); + } + if (_v) { + return _wrap_ubytes___delitem____SWIG_1(self, argc, argv); + } + } + } + if (argc == 2) { + int _v = 0; + int res = swig::asptr(argv[0], (std::vector< unsigned char,std::allocator< unsigned char > >**)(0)); + _v = SWIG_CheckState(res); + if (_v) { + { + int res = SWIG_AsVal_ptrdiff_t(argv[1], NULL); + _v = SWIG_CheckState(res); + } + if (_v) { + return _wrap_ubytes___delitem____SWIG_0(self, argc, argv); + } + } + } + +fail: + SWIG_Python_RaiseOrModifyTypeError("Wrong number or type of arguments for overloaded function 'ubytes___delitem__'.\n" + " Possible C/C++ prototypes are:\n" + " std::vector< uint8_t >::__delitem__(std::vector< unsigned char >::difference_type)\n" + " std::vector< uint8_t >::__delitem__(SWIGPY_SLICEOBJECT *)\n"); + return 0; +} + + +SWIGINTERN PyObject *_wrap_ubytes___getitem____SWIG_1(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + std::vector< uint8_t > *arg1 = (std::vector< uint8_t > *) 0 ; + std::vector< unsigned char >::difference_type arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + ptrdiff_t val2 ; + int ecode2 = 0 ; + std::vector< unsigned char >::value_type *result = 0 ; + + (void)self; + if ((nobjs < 2) || (nobjs > 2)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_uint8_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ubytes___getitem__" "', argument " "1"" of type '" "std::vector< uint8_t > const *""'"); + } + arg1 = reinterpret_cast< std::vector< uint8_t > * >(argp1); + ecode2 = SWIG_AsVal_ptrdiff_t(swig_obj[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ubytes___getitem__" "', argument " "2"" of type '" "std::vector< unsigned char >::difference_type""'"); + } + arg2 = static_cast< std::vector< unsigned char >::difference_type >(val2); + try { + result = (std::vector< unsigned char >::value_type *) &std_vector_Sl_uint8_t_Sg____getitem____SWIG_1((std::vector< unsigned char > const *)arg1,SWIG_STD_MOVE(arg2)); + } catch(std::out_of_range &_e) { + SWIG_exception_fail(SWIG_IndexError, (&_e)->what()); + } + resultobj = SWIG_From_unsigned_SS_char(static_cast< unsigned char >(*result)); + (void)swig::container_owner::value_type>::category>::back_reference(resultobj, swig_obj[0]); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ubytes___getitem__(PyObject *self, PyObject *args) { + Py_ssize_t argc; + PyObject *argv[3] = { + 0 + }; + + if (!(argc = SWIG_Python_UnpackTuple(args, "ubytes___getitem__", 0, 2, argv))) SWIG_fail; + --argc; + if (argc == 2) { + int _v = 0; + int res = swig::asptr(argv[0], (std::vector< unsigned char,std::allocator< unsigned char > >**)(0)); + _v = SWIG_CheckState(res); + if (_v) { + { + _v = PySlice_Check(argv[1]); + } + if (_v) { + return _wrap_ubytes___getitem____SWIG_0(self, argc, argv); + } + } + } + if (argc == 2) { + int _v = 0; + int res = swig::asptr(argv[0], (std::vector< unsigned char,std::allocator< unsigned char > >**)(0)); + _v = SWIG_CheckState(res); + if (_v) { + { + int res = SWIG_AsVal_ptrdiff_t(argv[1], NULL); + _v = SWIG_CheckState(res); + } + if (_v) { + return _wrap_ubytes___getitem____SWIG_1(self, argc, argv); + } + } + } + +fail: + SWIG_Python_RaiseOrModifyTypeError("Wrong number or type of arguments for overloaded function 'ubytes___getitem__'.\n" + " Possible C/C++ prototypes are:\n" + " std::vector< uint8_t >::__getitem__(SWIGPY_SLICEOBJECT *)\n" + " std::vector< uint8_t >::__getitem__(std::vector< unsigned char >::difference_type) const\n"); + return 0; +} + + +SWIGINTERN PyObject *_wrap_ubytes___setitem____SWIG_2(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + std::vector< uint8_t > *arg1 = (std::vector< uint8_t > *) 0 ; + std::vector< unsigned char >::difference_type arg2 ; + std::vector< unsigned char >::value_type *arg3 = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + ptrdiff_t val2 ; + int ecode2 = 0 ; + std::vector< unsigned char >::value_type temp3 ; + unsigned char val3 ; + int ecode3 = 0 ; + + (void)self; + if ((nobjs < 3) || (nobjs > 3)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_uint8_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ubytes___setitem__" "', argument " "1"" of type '" "std::vector< uint8_t > *""'"); + } + arg1 = reinterpret_cast< std::vector< uint8_t > * >(argp1); + ecode2 = SWIG_AsVal_ptrdiff_t(swig_obj[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ubytes___setitem__" "', argument " "2"" of type '" "std::vector< unsigned char >::difference_type""'"); + } + arg2 = static_cast< std::vector< unsigned char >::difference_type >(val2); + ecode3 = SWIG_AsVal_unsigned_SS_char(swig_obj[2], &val3); + if (!SWIG_IsOK(ecode3)) { + SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "ubytes___setitem__" "', argument " "3"" of type '" "std::vector< unsigned char >::value_type""'"); + } + temp3 = static_cast< std::vector< unsigned char >::value_type >(val3); + arg3 = &temp3; + try { + std_vector_Sl_uint8_t_Sg____setitem____SWIG_2(arg1,SWIG_STD_MOVE(arg2),(unsigned char const &)*arg3); + } catch(std::out_of_range &_e) { + SWIG_exception_fail(SWIG_IndexError, (&_e)->what()); + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ubytes___setitem__(PyObject *self, PyObject *args) { + Py_ssize_t argc; + PyObject *argv[4] = { + 0 + }; + + if (!(argc = SWIG_Python_UnpackTuple(args, "ubytes___setitem__", 0, 3, argv))) SWIG_fail; + --argc; + if (argc == 2) { + int _v = 0; + int res = swig::asptr(argv[0], (std::vector< unsigned char,std::allocator< unsigned char > >**)(0)); + _v = SWIG_CheckState(res); + if (_v) { + { + _v = PySlice_Check(argv[1]); + } + if (_v) { + return _wrap_ubytes___setitem____SWIG_1(self, argc, argv); + } + } + } + if (argc == 3) { + int _v = 0; + int res = swig::asptr(argv[0], (std::vector< unsigned char,std::allocator< unsigned char > >**)(0)); + _v = SWIG_CheckState(res); + if (_v) { + { + _v = PySlice_Check(argv[1]); + } + if (_v) { + int res = swig::asptr(argv[2], (std::vector< unsigned char,std::allocator< unsigned char > >**)(0)); + _v = SWIG_CheckState(res); + if (_v) { + return _wrap_ubytes___setitem____SWIG_0(self, argc, argv); + } + } + } + } + if (argc == 3) { + int _v = 0; + int res = swig::asptr(argv[0], (std::vector< unsigned char,std::allocator< unsigned char > >**)(0)); + _v = SWIG_CheckState(res); + if (_v) { + { + int res = SWIG_AsVal_ptrdiff_t(argv[1], NULL); + _v = SWIG_CheckState(res); + } + if (_v) { + { + int res = SWIG_AsVal_unsigned_SS_char(argv[2], NULL); + _v = SWIG_CheckState(res); + } + if (_v) { + return _wrap_ubytes___setitem____SWIG_2(self, argc, argv); + } + } + } + } + +fail: + SWIG_Python_RaiseOrModifyTypeError("Wrong number or type of arguments for overloaded function 'ubytes___setitem__'.\n" + " Possible C/C++ prototypes are:\n" + " std::vector< uint8_t >::__setitem__(SWIGPY_SLICEOBJECT *,std::vector< unsigned char,std::allocator< unsigned char > > const &)\n" + " std::vector< uint8_t >::__setitem__(SWIGPY_SLICEOBJECT *)\n" + " std::vector< uint8_t >::__setitem__(std::vector< unsigned char >::difference_type,std::vector< unsigned char >::value_type const &)\n"); + return 0; +} + + +SWIGINTERN PyObject *_wrap_ubytes_pop(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< uint8_t > *arg1 = (std::vector< uint8_t > *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + std::vector< unsigned char >::value_type result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_uint8_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ubytes_pop" "', argument " "1"" of type '" "std::vector< uint8_t > *""'"); + } + arg1 = reinterpret_cast< std::vector< uint8_t > * >(argp1); + try { + result = (std::vector< unsigned char >::value_type)std_vector_Sl_uint8_t_Sg__pop(arg1); + } catch(std::out_of_range &_e) { + SWIG_exception_fail(SWIG_IndexError, (&_e)->what()); + } + resultobj = SWIG_From_unsigned_SS_char(static_cast< unsigned char >(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ubytes_append(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< uint8_t > *arg1 = (std::vector< uint8_t > *) 0 ; + std::vector< unsigned char >::value_type *arg2 = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::vector< unsigned char >::value_type temp2 ; + unsigned char val2 ; + int ecode2 = 0 ; + PyObject *swig_obj[2] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "ubytes_append", 2, 2, swig_obj)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_uint8_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ubytes_append" "', argument " "1"" of type '" "std::vector< uint8_t > *""'"); + } + arg1 = reinterpret_cast< std::vector< uint8_t > * >(argp1); + ecode2 = SWIG_AsVal_unsigned_SS_char(swig_obj[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ubytes_append" "', argument " "2"" of type '" "std::vector< unsigned char >::value_type""'"); + } + temp2 = static_cast< std::vector< unsigned char >::value_type >(val2); + arg2 = &temp2; + std_vector_Sl_uint8_t_Sg__append(arg1,(unsigned char const &)*arg2); + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_new_ubytes__SWIG_0(PyObject *self, Py_ssize_t nobjs, PyObject **SWIGUNUSEDPARM(swig_obj)) { + PyObject *resultobj = 0; + std::vector< uint8_t > *result = 0 ; + + (void)self; + if ((nobjs < 0) || (nobjs > 0)) SWIG_fail; + result = (std::vector< uint8_t > *)new std::vector< uint8_t >(); + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorT_uint8_t_t, SWIG_POINTER_NEW | 0 ); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_new_ubytes__SWIG_1(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + std::vector< uint8_t > *arg1 = 0 ; + int res1 = SWIG_OLDOBJ ; + std::vector< uint8_t > *result = 0 ; + + (void)self; + if ((nobjs < 1) || (nobjs > 1)) SWIG_fail; + { + std::vector< unsigned char,std::allocator< unsigned char > > *ptr = (std::vector< unsigned char,std::allocator< unsigned char > > *)0; + res1 = swig::asptr(swig_obj[0], &ptr); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "new_ubytes" "', argument " "1"" of type '" "std::vector< uint8_t > const &""'"); + } + if (!ptr) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_ubytes" "', argument " "1"" of type '" "std::vector< uint8_t > const &""'"); + } + arg1 = ptr; + } + result = (std::vector< uint8_t > *)new std::vector< uint8_t >((std::vector< uint8_t > const &)*arg1); + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorT_uint8_t_t, SWIG_POINTER_NEW | 0 ); + if (SWIG_IsNewObj(res1)) delete arg1; + return resultobj; +fail: + if (SWIG_IsNewObj(res1)) delete arg1; + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ubytes_empty(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< uint8_t > *arg1 = (std::vector< uint8_t > *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + bool result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_uint8_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ubytes_empty" "', argument " "1"" of type '" "std::vector< uint8_t > const *""'"); + } + arg1 = reinterpret_cast< std::vector< uint8_t > * >(argp1); + result = (bool)((std::vector< uint8_t > const *)arg1)->empty(); + resultobj = SWIG_From_bool(static_cast< bool >(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ubytes_size(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< uint8_t > *arg1 = (std::vector< uint8_t > *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + std::vector< unsigned char >::size_type result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_uint8_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ubytes_size" "', argument " "1"" of type '" "std::vector< uint8_t > const *""'"); + } + arg1 = reinterpret_cast< std::vector< uint8_t > * >(argp1); + result = ((std::vector< uint8_t > const *)arg1)->size(); + resultobj = SWIG_From_size_t(static_cast< size_t >(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ubytes_swap(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< uint8_t > *arg1 = (std::vector< uint8_t > *) 0 ; + std::vector< uint8_t > *arg2 = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + void *argp2 = 0 ; + int res2 = 0 ; + PyObject *swig_obj[2] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "ubytes_swap", 2, 2, swig_obj)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_uint8_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ubytes_swap" "', argument " "1"" of type '" "std::vector< uint8_t > *""'"); + } + arg1 = reinterpret_cast< std::vector< uint8_t > * >(argp1); + res2 = SWIG_ConvertPtr(swig_obj[1], &argp2, SWIGTYPE_p_std__vectorT_uint8_t_t, 0 ); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "ubytes_swap" "', argument " "2"" of type '" "std::vector< uint8_t > &""'"); + } + if (!argp2) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "ubytes_swap" "', argument " "2"" of type '" "std::vector< uint8_t > &""'"); + } + arg2 = reinterpret_cast< std::vector< uint8_t > * >(argp2); + (arg1)->swap(*arg2); + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ubytes_begin(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< uint8_t > *arg1 = (std::vector< uint8_t > *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + SwigValueWrapper< std::vector< unsigned char >::iterator > result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_uint8_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ubytes_begin" "', argument " "1"" of type '" "std::vector< uint8_t > *""'"); + } + arg1 = reinterpret_cast< std::vector< uint8_t > * >(argp1); + result = (arg1)->begin(); + resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector< unsigned char >::iterator & >(result)), + swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ubytes_end(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< uint8_t > *arg1 = (std::vector< uint8_t > *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + SwigValueWrapper< std::vector< unsigned char >::iterator > result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_uint8_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ubytes_end" "', argument " "1"" of type '" "std::vector< uint8_t > *""'"); + } + arg1 = reinterpret_cast< std::vector< uint8_t > * >(argp1); + result = (arg1)->end(); + resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector< unsigned char >::iterator & >(result)), + swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ubytes_rbegin(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< uint8_t > *arg1 = (std::vector< uint8_t > *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + SwigValueWrapper< std::vector< unsigned char >::reverse_iterator > result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_uint8_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ubytes_rbegin" "', argument " "1"" of type '" "std::vector< uint8_t > *""'"); + } + arg1 = reinterpret_cast< std::vector< uint8_t > * >(argp1); + result = (arg1)->rbegin(); + resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector< unsigned char >::reverse_iterator & >(result)), + swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ubytes_rend(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< uint8_t > *arg1 = (std::vector< uint8_t > *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + SwigValueWrapper< std::vector< unsigned char >::reverse_iterator > result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_uint8_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ubytes_rend" "', argument " "1"" of type '" "std::vector< uint8_t > *""'"); + } + arg1 = reinterpret_cast< std::vector< uint8_t > * >(argp1); + result = (arg1)->rend(); + resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector< unsigned char >::reverse_iterator & >(result)), + swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ubytes_clear(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< uint8_t > *arg1 = (std::vector< uint8_t > *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_uint8_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ubytes_clear" "', argument " "1"" of type '" "std::vector< uint8_t > *""'"); + } + arg1 = reinterpret_cast< std::vector< uint8_t > * >(argp1); + (arg1)->clear(); + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ubytes_get_allocator(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< uint8_t > *arg1 = (std::vector< uint8_t > *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + SwigValueWrapper< std::allocator< unsigned char > > result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_uint8_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ubytes_get_allocator" "', argument " "1"" of type '" "std::vector< uint8_t > const *""'"); + } + arg1 = reinterpret_cast< std::vector< uint8_t > * >(argp1); + result = ((std::vector< uint8_t > const *)arg1)->get_allocator(); + resultobj = SWIG_NewPointerObj((new std::vector< unsigned char >::allocator_type(result)), SWIGTYPE_p_std__allocatorT_unsigned_char_t, SWIG_POINTER_OWN | 0 ); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_new_ubytes__SWIG_2(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + std::vector< unsigned char >::size_type arg1 ; + size_t val1 ; + int ecode1 = 0 ; + std::vector< uint8_t > *result = 0 ; + + (void)self; + if ((nobjs < 1) || (nobjs > 1)) SWIG_fail; + ecode1 = SWIG_AsVal_size_t(swig_obj[0], &val1); + if (!SWIG_IsOK(ecode1)) { + SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "new_ubytes" "', argument " "1"" of type '" "std::vector< unsigned char >::size_type""'"); + } + arg1 = static_cast< std::vector< unsigned char >::size_type >(val1); + result = (std::vector< uint8_t > *)new std::vector< uint8_t >(arg1); + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorT_uint8_t_t, SWIG_POINTER_NEW | 0 ); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ubytes_pop_back(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< uint8_t > *arg1 = (std::vector< uint8_t > *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_uint8_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ubytes_pop_back" "', argument " "1"" of type '" "std::vector< uint8_t > *""'"); + } + arg1 = reinterpret_cast< std::vector< uint8_t > * >(argp1); + (arg1)->pop_back(); + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ubytes_resize__SWIG_0(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + std::vector< uint8_t > *arg1 = (std::vector< uint8_t > *) 0 ; + std::vector< unsigned char >::size_type arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + size_t val2 ; + int ecode2 = 0 ; + + (void)self; + if ((nobjs < 2) || (nobjs > 2)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_uint8_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ubytes_resize" "', argument " "1"" of type '" "std::vector< uint8_t > *""'"); + } + arg1 = reinterpret_cast< std::vector< uint8_t > * >(argp1); + ecode2 = SWIG_AsVal_size_t(swig_obj[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ubytes_resize" "', argument " "2"" of type '" "std::vector< unsigned char >::size_type""'"); + } + arg2 = static_cast< std::vector< unsigned char >::size_type >(val2); + (arg1)->resize(arg2); + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ubytes_erase__SWIG_0(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + std::vector< uint8_t > *arg1 = (std::vector< uint8_t > *) 0 ; + SwigValueWrapper< std::vector< unsigned char >::iterator > arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + swig::SwigPyIterator *iter2 = 0 ; + int res2 ; + SwigValueWrapper< std::vector< unsigned char >::iterator > result; + + (void)self; + if ((nobjs < 2) || (nobjs > 2)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_uint8_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ubytes_erase" "', argument " "1"" of type '" "std::vector< uint8_t > *""'"); + } + arg1 = reinterpret_cast< std::vector< uint8_t > * >(argp1); + res2 = SWIG_ConvertPtr(swig_obj[1], SWIG_as_voidptrptr(&iter2), swig::SwigPyIterator::descriptor(), 0); + if (!SWIG_IsOK(res2) || !iter2) { + SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "ubytes_erase" "', argument " "2"" of type '" "std::vector< unsigned char >::iterator""'"); + } else { + swig::SwigPyIterator_T::iterator > *iter_t = dynamic_cast::iterator > *>(iter2); + if (iter_t) { + arg2 = iter_t->get_current(); + } else { + SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "ubytes_erase" "', argument " "2"" of type '" "std::vector< unsigned char >::iterator""'"); + } + } + result = std_vector_Sl_uint8_t_Sg__erase__SWIG_0(arg1,SWIG_STD_MOVE(arg2)); + resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector< unsigned char >::iterator & >(result)), + swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ubytes_erase__SWIG_1(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + std::vector< uint8_t > *arg1 = (std::vector< uint8_t > *) 0 ; + SwigValueWrapper< std::vector< unsigned char >::iterator > arg2 ; + SwigValueWrapper< std::vector< unsigned char >::iterator > arg3 ; + void *argp1 = 0 ; + int res1 = 0 ; + swig::SwigPyIterator *iter2 = 0 ; + int res2 ; + swig::SwigPyIterator *iter3 = 0 ; + int res3 ; + SwigValueWrapper< std::vector< unsigned char >::iterator > result; + + (void)self; + if ((nobjs < 3) || (nobjs > 3)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_uint8_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ubytes_erase" "', argument " "1"" of type '" "std::vector< uint8_t > *""'"); + } + arg1 = reinterpret_cast< std::vector< uint8_t > * >(argp1); + res2 = SWIG_ConvertPtr(swig_obj[1], SWIG_as_voidptrptr(&iter2), swig::SwigPyIterator::descriptor(), 0); + if (!SWIG_IsOK(res2) || !iter2) { + SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "ubytes_erase" "', argument " "2"" of type '" "std::vector< unsigned char >::iterator""'"); + } else { + swig::SwigPyIterator_T::iterator > *iter_t = dynamic_cast::iterator > *>(iter2); + if (iter_t) { + arg2 = iter_t->get_current(); + } else { + SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "ubytes_erase" "', argument " "2"" of type '" "std::vector< unsigned char >::iterator""'"); + } + } + res3 = SWIG_ConvertPtr(swig_obj[2], SWIG_as_voidptrptr(&iter3), swig::SwigPyIterator::descriptor(), 0); + if (!SWIG_IsOK(res3) || !iter3) { + SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "ubytes_erase" "', argument " "3"" of type '" "std::vector< unsigned char >::iterator""'"); + } else { + swig::SwigPyIterator_T::iterator > *iter_t = dynamic_cast::iterator > *>(iter3); + if (iter_t) { + arg3 = iter_t->get_current(); + } else { + SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "ubytes_erase" "', argument " "3"" of type '" "std::vector< unsigned char >::iterator""'"); + } + } + result = std_vector_Sl_uint8_t_Sg__erase__SWIG_1(arg1,SWIG_STD_MOVE(arg2),SWIG_STD_MOVE(arg3)); + resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector< unsigned char >::iterator & >(result)), + swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ubytes_erase(PyObject *self, PyObject *args) { + Py_ssize_t argc; + PyObject *argv[4] = { + 0 + }; + + if (!(argc = SWIG_Python_UnpackTuple(args, "ubytes_erase", 0, 3, argv))) SWIG_fail; + --argc; + if (argc == 2) { + int _v = 0; + int res = swig::asptr(argv[0], (std::vector< unsigned char,std::allocator< unsigned char > >**)(0)); + _v = SWIG_CheckState(res); + if (_v) { + swig::SwigPyIterator *iter = 0; + int res = SWIG_ConvertPtr(argv[1], SWIG_as_voidptrptr(&iter), swig::SwigPyIterator::descriptor(), 0); + _v = (SWIG_IsOK(res) && iter && (dynamic_cast::iterator > *>(iter) != 0)); + if (_v) { + return _wrap_ubytes_erase__SWIG_0(self, argc, argv); + } + } + } + if (argc == 3) { + int _v = 0; + int res = swig::asptr(argv[0], (std::vector< unsigned char,std::allocator< unsigned char > >**)(0)); + _v = SWIG_CheckState(res); + if (_v) { + swig::SwigPyIterator *iter = 0; + int res = SWIG_ConvertPtr(argv[1], SWIG_as_voidptrptr(&iter), swig::SwigPyIterator::descriptor(), 0); + _v = (SWIG_IsOK(res) && iter && (dynamic_cast::iterator > *>(iter) != 0)); + if (_v) { + swig::SwigPyIterator *iter = 0; + int res = SWIG_ConvertPtr(argv[2], SWIG_as_voidptrptr(&iter), swig::SwigPyIterator::descriptor(), 0); + _v = (SWIG_IsOK(res) && iter && (dynamic_cast::iterator > *>(iter) != 0)); + if (_v) { + return _wrap_ubytes_erase__SWIG_1(self, argc, argv); + } + } + } + } + +fail: + SWIG_Python_RaiseOrModifyTypeError("Wrong number or type of arguments for overloaded function 'ubytes_erase'.\n" + " Possible C/C++ prototypes are:\n" + " std::vector< uint8_t >::erase(std::vector< unsigned char >::iterator)\n" + " std::vector< uint8_t >::erase(std::vector< unsigned char >::iterator,std::vector< unsigned char >::iterator)\n"); + return 0; +} + + +SWIGINTERN PyObject *_wrap_new_ubytes__SWIG_3(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + std::vector< unsigned char >::size_type arg1 ; + std::vector< unsigned char >::value_type *arg2 = 0 ; + size_t val1 ; + int ecode1 = 0 ; + std::vector< unsigned char >::value_type temp2 ; + unsigned char val2 ; + int ecode2 = 0 ; + std::vector< uint8_t > *result = 0 ; + + (void)self; + if ((nobjs < 2) || (nobjs > 2)) SWIG_fail; + ecode1 = SWIG_AsVal_size_t(swig_obj[0], &val1); + if (!SWIG_IsOK(ecode1)) { + SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "new_ubytes" "', argument " "1"" of type '" "std::vector< unsigned char >::size_type""'"); + } + arg1 = static_cast< std::vector< unsigned char >::size_type >(val1); + ecode2 = SWIG_AsVal_unsigned_SS_char(swig_obj[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "new_ubytes" "', argument " "2"" of type '" "std::vector< unsigned char >::value_type""'"); + } + temp2 = static_cast< std::vector< unsigned char >::value_type >(val2); + arg2 = &temp2; + result = (std::vector< uint8_t > *)new std::vector< uint8_t >(arg1,(std::vector< unsigned char >::value_type const &)*arg2); + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorT_uint8_t_t, SWIG_POINTER_NEW | 0 ); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_new_ubytes(PyObject *self, PyObject *args) { + Py_ssize_t argc; + PyObject *argv[3] = { + 0 + }; + + if (!(argc = SWIG_Python_UnpackTuple(args, "new_ubytes", 0, 2, argv))) SWIG_fail; + --argc; + if (argc == 0) { + return _wrap_new_ubytes__SWIG_0(self, argc, argv); + } + if (argc == 1) { + int _v = 0; + { + int res = SWIG_AsVal_size_t(argv[0], NULL); + _v = SWIG_CheckState(res); + } + if (_v) { + return _wrap_new_ubytes__SWIG_2(self, argc, argv); + } + } + if (argc == 1) { + int _v = 0; + int res = swig::asptr(argv[0], (std::vector< unsigned char,std::allocator< unsigned char > >**)(0)); + _v = SWIG_CheckState(res); + if (_v) { + return _wrap_new_ubytes__SWIG_1(self, argc, argv); + } + } + if (argc == 2) { + int _v = 0; + { + int res = SWIG_AsVal_size_t(argv[0], NULL); + _v = SWIG_CheckState(res); + } + if (_v) { + { + int res = SWIG_AsVal_unsigned_SS_char(argv[1], NULL); + _v = SWIG_CheckState(res); + } + if (_v) { + return _wrap_new_ubytes__SWIG_3(self, argc, argv); + } + } + } + +fail: + SWIG_Python_RaiseOrModifyTypeError("Wrong number or type of arguments for overloaded function 'new_ubytes'.\n" + " Possible C/C++ prototypes are:\n" + " std::vector< uint8_t >::vector()\n" + " std::vector< uint8_t >::vector(std::vector< uint8_t > const &)\n" + " std::vector< uint8_t >::vector(std::vector< unsigned char >::size_type)\n" + " std::vector< uint8_t >::vector(std::vector< unsigned char >::size_type,std::vector< unsigned char >::value_type const &)\n"); + return 0; +} + + +SWIGINTERN PyObject *_wrap_ubytes_push_back(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< uint8_t > *arg1 = (std::vector< uint8_t > *) 0 ; + std::vector< unsigned char >::value_type *arg2 = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::vector< unsigned char >::value_type temp2 ; + unsigned char val2 ; + int ecode2 = 0 ; + PyObject *swig_obj[2] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "ubytes_push_back", 2, 2, swig_obj)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_uint8_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ubytes_push_back" "', argument " "1"" of type '" "std::vector< uint8_t > *""'"); + } + arg1 = reinterpret_cast< std::vector< uint8_t > * >(argp1); + ecode2 = SWIG_AsVal_unsigned_SS_char(swig_obj[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ubytes_push_back" "', argument " "2"" of type '" "std::vector< unsigned char >::value_type""'"); + } + temp2 = static_cast< std::vector< unsigned char >::value_type >(val2); + arg2 = &temp2; + (arg1)->push_back((std::vector< unsigned char >::value_type const &)*arg2); + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ubytes_front(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< uint8_t > *arg1 = (std::vector< uint8_t > *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + std::vector< unsigned char >::value_type *result = 0 ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_uint8_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ubytes_front" "', argument " "1"" of type '" "std::vector< uint8_t > const *""'"); + } + arg1 = reinterpret_cast< std::vector< uint8_t > * >(argp1); + result = (std::vector< unsigned char >::value_type *) &((std::vector< uint8_t > const *)arg1)->front(); + resultobj = SWIG_From_unsigned_SS_char(static_cast< unsigned char >(*result)); + (void)swig::container_owner::value_type>::category>::back_reference(resultobj, swig_obj[0]); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ubytes_back(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< uint8_t > *arg1 = (std::vector< uint8_t > *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + std::vector< unsigned char >::value_type *result = 0 ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_uint8_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ubytes_back" "', argument " "1"" of type '" "std::vector< uint8_t > const *""'"); + } + arg1 = reinterpret_cast< std::vector< uint8_t > * >(argp1); + result = (std::vector< unsigned char >::value_type *) &((std::vector< uint8_t > const *)arg1)->back(); + resultobj = SWIG_From_unsigned_SS_char(static_cast< unsigned char >(*result)); + (void)swig::container_owner::value_type>::category>::back_reference(resultobj, swig_obj[0]); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ubytes_assign(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< uint8_t > *arg1 = (std::vector< uint8_t > *) 0 ; + std::vector< unsigned char >::size_type arg2 ; + std::vector< unsigned char >::value_type *arg3 = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + size_t val2 ; + int ecode2 = 0 ; + std::vector< unsigned char >::value_type temp3 ; + unsigned char val3 ; + int ecode3 = 0 ; + PyObject *swig_obj[3] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "ubytes_assign", 3, 3, swig_obj)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_uint8_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ubytes_assign" "', argument " "1"" of type '" "std::vector< uint8_t > *""'"); + } + arg1 = reinterpret_cast< std::vector< uint8_t > * >(argp1); + ecode2 = SWIG_AsVal_size_t(swig_obj[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ubytes_assign" "', argument " "2"" of type '" "std::vector< unsigned char >::size_type""'"); + } + arg2 = static_cast< std::vector< unsigned char >::size_type >(val2); + ecode3 = SWIG_AsVal_unsigned_SS_char(swig_obj[2], &val3); + if (!SWIG_IsOK(ecode3)) { + SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "ubytes_assign" "', argument " "3"" of type '" "std::vector< unsigned char >::value_type""'"); + } + temp3 = static_cast< std::vector< unsigned char >::value_type >(val3); + arg3 = &temp3; + (arg1)->assign(arg2,(std::vector< unsigned char >::value_type const &)*arg3); + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ubytes_resize__SWIG_1(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + std::vector< uint8_t > *arg1 = (std::vector< uint8_t > *) 0 ; + std::vector< unsigned char >::size_type arg2 ; + std::vector< unsigned char >::value_type *arg3 = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + size_t val2 ; + int ecode2 = 0 ; + std::vector< unsigned char >::value_type temp3 ; + unsigned char val3 ; + int ecode3 = 0 ; + + (void)self; + if ((nobjs < 3) || (nobjs > 3)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_uint8_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ubytes_resize" "', argument " "1"" of type '" "std::vector< uint8_t > *""'"); + } + arg1 = reinterpret_cast< std::vector< uint8_t > * >(argp1); + ecode2 = SWIG_AsVal_size_t(swig_obj[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ubytes_resize" "', argument " "2"" of type '" "std::vector< unsigned char >::size_type""'"); + } + arg2 = static_cast< std::vector< unsigned char >::size_type >(val2); + ecode3 = SWIG_AsVal_unsigned_SS_char(swig_obj[2], &val3); + if (!SWIG_IsOK(ecode3)) { + SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "ubytes_resize" "', argument " "3"" of type '" "std::vector< unsigned char >::value_type""'"); + } + temp3 = static_cast< std::vector< unsigned char >::value_type >(val3); + arg3 = &temp3; + (arg1)->resize(arg2,(std::vector< unsigned char >::value_type const &)*arg3); + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ubytes_resize(PyObject *self, PyObject *args) { + Py_ssize_t argc; + PyObject *argv[4] = { + 0 + }; + + if (!(argc = SWIG_Python_UnpackTuple(args, "ubytes_resize", 0, 3, argv))) SWIG_fail; + --argc; + if (argc == 2) { + int _v = 0; + int res = swig::asptr(argv[0], (std::vector< unsigned char,std::allocator< unsigned char > >**)(0)); + _v = SWIG_CheckState(res); + if (_v) { + { + int res = SWIG_AsVal_size_t(argv[1], NULL); + _v = SWIG_CheckState(res); + } + if (_v) { + return _wrap_ubytes_resize__SWIG_0(self, argc, argv); + } + } + } + if (argc == 3) { + int _v = 0; + int res = swig::asptr(argv[0], (std::vector< unsigned char,std::allocator< unsigned char > >**)(0)); + _v = SWIG_CheckState(res); + if (_v) { + { + int res = SWIG_AsVal_size_t(argv[1], NULL); + _v = SWIG_CheckState(res); + } + if (_v) { + { + int res = SWIG_AsVal_unsigned_SS_char(argv[2], NULL); + _v = SWIG_CheckState(res); + } + if (_v) { + return _wrap_ubytes_resize__SWIG_1(self, argc, argv); + } + } + } + } + +fail: + SWIG_Python_RaiseOrModifyTypeError("Wrong number or type of arguments for overloaded function 'ubytes_resize'.\n" + " Possible C/C++ prototypes are:\n" + " std::vector< uint8_t >::resize(std::vector< unsigned char >::size_type)\n" + " std::vector< uint8_t >::resize(std::vector< unsigned char >::size_type,std::vector< unsigned char >::value_type const &)\n"); + return 0; +} + + +SWIGINTERN PyObject *_wrap_ubytes_insert__SWIG_0(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + std::vector< uint8_t > *arg1 = (std::vector< uint8_t > *) 0 ; + SwigValueWrapper< std::vector< unsigned char >::iterator > arg2 ; + std::vector< unsigned char >::value_type *arg3 = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + swig::SwigPyIterator *iter2 = 0 ; + int res2 ; + std::vector< unsigned char >::value_type temp3 ; + unsigned char val3 ; + int ecode3 = 0 ; + SwigValueWrapper< std::vector< unsigned char >::iterator > result; + + (void)self; + if ((nobjs < 3) || (nobjs > 3)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_uint8_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ubytes_insert" "', argument " "1"" of type '" "std::vector< uint8_t > *""'"); + } + arg1 = reinterpret_cast< std::vector< uint8_t > * >(argp1); + res2 = SWIG_ConvertPtr(swig_obj[1], SWIG_as_voidptrptr(&iter2), swig::SwigPyIterator::descriptor(), 0); + if (!SWIG_IsOK(res2) || !iter2) { + SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "ubytes_insert" "', argument " "2"" of type '" "std::vector< unsigned char >::iterator""'"); + } else { + swig::SwigPyIterator_T::iterator > *iter_t = dynamic_cast::iterator > *>(iter2); + if (iter_t) { + arg2 = iter_t->get_current(); + } else { + SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "ubytes_insert" "', argument " "2"" of type '" "std::vector< unsigned char >::iterator""'"); + } + } + ecode3 = SWIG_AsVal_unsigned_SS_char(swig_obj[2], &val3); + if (!SWIG_IsOK(ecode3)) { + SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "ubytes_insert" "', argument " "3"" of type '" "std::vector< unsigned char >::value_type""'"); + } + temp3 = static_cast< std::vector< unsigned char >::value_type >(val3); + arg3 = &temp3; + result = std_vector_Sl_uint8_t_Sg__insert__SWIG_0(arg1,SWIG_STD_MOVE(arg2),(unsigned char const &)*arg3); + resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector< unsigned char >::iterator & >(result)), + swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ubytes_insert__SWIG_1(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + std::vector< uint8_t > *arg1 = (std::vector< uint8_t > *) 0 ; + SwigValueWrapper< std::vector< unsigned char >::iterator > arg2 ; + std::vector< unsigned char >::size_type arg3 ; + std::vector< unsigned char >::value_type *arg4 = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + swig::SwigPyIterator *iter2 = 0 ; + int res2 ; + size_t val3 ; + int ecode3 = 0 ; + std::vector< unsigned char >::value_type temp4 ; + unsigned char val4 ; + int ecode4 = 0 ; + + (void)self; + if ((nobjs < 4) || (nobjs > 4)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_uint8_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ubytes_insert" "', argument " "1"" of type '" "std::vector< uint8_t > *""'"); + } + arg1 = reinterpret_cast< std::vector< uint8_t > * >(argp1); + res2 = SWIG_ConvertPtr(swig_obj[1], SWIG_as_voidptrptr(&iter2), swig::SwigPyIterator::descriptor(), 0); + if (!SWIG_IsOK(res2) || !iter2) { + SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "ubytes_insert" "', argument " "2"" of type '" "std::vector< unsigned char >::iterator""'"); + } else { + swig::SwigPyIterator_T::iterator > *iter_t = dynamic_cast::iterator > *>(iter2); + if (iter_t) { + arg2 = iter_t->get_current(); + } else { + SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "ubytes_insert" "', argument " "2"" of type '" "std::vector< unsigned char >::iterator""'"); + } + } + ecode3 = SWIG_AsVal_size_t(swig_obj[2], &val3); + if (!SWIG_IsOK(ecode3)) { + SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "ubytes_insert" "', argument " "3"" of type '" "std::vector< unsigned char >::size_type""'"); + } + arg3 = static_cast< std::vector< unsigned char >::size_type >(val3); + ecode4 = SWIG_AsVal_unsigned_SS_char(swig_obj[3], &val4); + if (!SWIG_IsOK(ecode4)) { + SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "ubytes_insert" "', argument " "4"" of type '" "std::vector< unsigned char >::value_type""'"); + } + temp4 = static_cast< std::vector< unsigned char >::value_type >(val4); + arg4 = &temp4; + std_vector_Sl_uint8_t_Sg__insert__SWIG_1(arg1,SWIG_STD_MOVE(arg2),SWIG_STD_MOVE(arg3),(unsigned char const &)*arg4); + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ubytes_insert(PyObject *self, PyObject *args) { + Py_ssize_t argc; + PyObject *argv[5] = { + 0 + }; + + if (!(argc = SWIG_Python_UnpackTuple(args, "ubytes_insert", 0, 4, argv))) SWIG_fail; + --argc; + if (argc == 3) { + int _v = 0; + int res = swig::asptr(argv[0], (std::vector< unsigned char,std::allocator< unsigned char > >**)(0)); + _v = SWIG_CheckState(res); + if (_v) { + swig::SwigPyIterator *iter = 0; + int res = SWIG_ConvertPtr(argv[1], SWIG_as_voidptrptr(&iter), swig::SwigPyIterator::descriptor(), 0); + _v = (SWIG_IsOK(res) && iter && (dynamic_cast::iterator > *>(iter) != 0)); + if (_v) { + { + int res = SWIG_AsVal_unsigned_SS_char(argv[2], NULL); + _v = SWIG_CheckState(res); + } + if (_v) { + return _wrap_ubytes_insert__SWIG_0(self, argc, argv); + } + } + } + } + if (argc == 4) { + int _v = 0; + int res = swig::asptr(argv[0], (std::vector< unsigned char,std::allocator< unsigned char > >**)(0)); + _v = SWIG_CheckState(res); + if (_v) { + swig::SwigPyIterator *iter = 0; + int res = SWIG_ConvertPtr(argv[1], SWIG_as_voidptrptr(&iter), swig::SwigPyIterator::descriptor(), 0); + _v = (SWIG_IsOK(res) && iter && (dynamic_cast::iterator > *>(iter) != 0)); + if (_v) { + { + int res = SWIG_AsVal_size_t(argv[2], NULL); + _v = SWIG_CheckState(res); + } + if (_v) { + { + int res = SWIG_AsVal_unsigned_SS_char(argv[3], NULL); + _v = SWIG_CheckState(res); + } + if (_v) { + return _wrap_ubytes_insert__SWIG_1(self, argc, argv); + } + } + } + } + } + +fail: + SWIG_Python_RaiseOrModifyTypeError("Wrong number or type of arguments for overloaded function 'ubytes_insert'.\n" + " Possible C/C++ prototypes are:\n" + " std::vector< uint8_t >::insert(std::vector< unsigned char >::iterator,std::vector< unsigned char >::value_type const &)\n" + " std::vector< uint8_t >::insert(std::vector< unsigned char >::iterator,std::vector< unsigned char >::size_type,std::vector< unsigned char >::value_type const &)\n"); + return 0; +} + + +SWIGINTERN PyObject *_wrap_ubytes_reserve(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< uint8_t > *arg1 = (std::vector< uint8_t > *) 0 ; + std::vector< unsigned char >::size_type arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + size_t val2 ; + int ecode2 = 0 ; + PyObject *swig_obj[2] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "ubytes_reserve", 2, 2, swig_obj)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_uint8_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ubytes_reserve" "', argument " "1"" of type '" "std::vector< uint8_t > *""'"); + } + arg1 = reinterpret_cast< std::vector< uint8_t > * >(argp1); + ecode2 = SWIG_AsVal_size_t(swig_obj[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ubytes_reserve" "', argument " "2"" of type '" "std::vector< unsigned char >::size_type""'"); + } + arg2 = static_cast< std::vector< unsigned char >::size_type >(val2); + (arg1)->reserve(arg2); + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ubytes_capacity(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< uint8_t > *arg1 = (std::vector< uint8_t > *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + std::vector< unsigned char >::size_type result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_uint8_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ubytes_capacity" "', argument " "1"" of type '" "std::vector< uint8_t > const *""'"); + } + arg1 = reinterpret_cast< std::vector< uint8_t > * >(argp1); + result = ((std::vector< uint8_t > const *)arg1)->capacity(); + resultobj = SWIG_From_size_t(static_cast< size_t >(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_delete_ubytes(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< uint8_t > *arg1 = (std::vector< uint8_t > *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_uint8_t_t, SWIG_POINTER_DISOWN | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_ubytes" "', argument " "1"" of type '" "std::vector< uint8_t > *""'"); + } + arg1 = reinterpret_cast< std::vector< uint8_t > * >(argp1); + { + try { + delete arg1; + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *ubytes_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *obj; + if (!SWIG_Python_UnpackTuple(args, "swigregister", 1, 1, &obj)) return NULL; + SWIG_TypeNewClientData(SWIGTYPE_p_std__vectorT_uint8_t_t, SWIG_NewClientData(obj)); + return SWIG_Py_Void(); +} + +SWIGINTERN PyObject *ubytes_swiginit(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + return SWIG_Python_InitShadowInstance(args); +} + +SWIGINTERN PyObject *_wrap_ibytes_iterator(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< int8_t > *arg1 = (std::vector< int8_t > *) 0 ; + PyObject **arg2 = (PyObject **) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + swig::SwigPyIterator *result = 0 ; + + arg2 = &swig_obj[0]; + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_int8_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ibytes_iterator" "', argument " "1"" of type '" "std::vector< int8_t > *""'"); + } + arg1 = reinterpret_cast< std::vector< int8_t > * >(argp1); + result = (swig::SwigPyIterator *)std_vector_Sl_int8_t_Sg__iterator(arg1,arg2); + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_swig__SwigPyIterator, SWIG_POINTER_OWN | 0 ); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ibytes___nonzero__(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< int8_t > *arg1 = (std::vector< int8_t > *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + bool result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_int8_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ibytes___nonzero__" "', argument " "1"" of type '" "std::vector< int8_t > const *""'"); + } + arg1 = reinterpret_cast< std::vector< int8_t > * >(argp1); + result = (bool)std_vector_Sl_int8_t_Sg____nonzero__((std::vector< signed char > const *)arg1); + resultobj = SWIG_From_bool(static_cast< bool >(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ibytes___bool__(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< int8_t > *arg1 = (std::vector< int8_t > *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + bool result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_int8_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ibytes___bool__" "', argument " "1"" of type '" "std::vector< int8_t > const *""'"); + } + arg1 = reinterpret_cast< std::vector< int8_t > * >(argp1); + result = (bool)std_vector_Sl_int8_t_Sg____bool__((std::vector< signed char > const *)arg1); + resultobj = SWIG_From_bool(static_cast< bool >(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ibytes___len__(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< int8_t > *arg1 = (std::vector< int8_t > *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + std::vector< signed char >::size_type result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_int8_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ibytes___len__" "', argument " "1"" of type '" "std::vector< int8_t > const *""'"); + } + arg1 = reinterpret_cast< std::vector< int8_t > * >(argp1); + result = std_vector_Sl_int8_t_Sg____len__((std::vector< signed char > const *)arg1); + resultobj = SWIG_From_size_t(static_cast< size_t >(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ibytes___getslice__(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< int8_t > *arg1 = (std::vector< int8_t > *) 0 ; + std::vector< signed char >::difference_type arg2 ; + std::vector< signed char >::difference_type arg3 ; + void *argp1 = 0 ; + int res1 = 0 ; + ptrdiff_t val2 ; + int ecode2 = 0 ; + ptrdiff_t val3 ; + int ecode3 = 0 ; + PyObject *swig_obj[3] ; + std::vector< signed char,std::allocator< signed char > > *result = 0 ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "ibytes___getslice__", 3, 3, swig_obj)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_int8_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ibytes___getslice__" "', argument " "1"" of type '" "std::vector< int8_t > *""'"); + } + arg1 = reinterpret_cast< std::vector< int8_t > * >(argp1); + ecode2 = SWIG_AsVal_ptrdiff_t(swig_obj[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ibytes___getslice__" "', argument " "2"" of type '" "std::vector< signed char >::difference_type""'"); + } + arg2 = static_cast< std::vector< signed char >::difference_type >(val2); + ecode3 = SWIG_AsVal_ptrdiff_t(swig_obj[2], &val3); + if (!SWIG_IsOK(ecode3)) { + SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "ibytes___getslice__" "', argument " "3"" of type '" "std::vector< signed char >::difference_type""'"); + } + arg3 = static_cast< std::vector< signed char >::difference_type >(val3); + try { + result = (std::vector< signed char,std::allocator< signed char > > *)std_vector_Sl_int8_t_Sg____getslice__(arg1,SWIG_STD_MOVE(arg2),SWIG_STD_MOVE(arg3)); + } catch(std::out_of_range &_e) { + SWIG_exception_fail(SWIG_IndexError, (&_e)->what()); + } catch(std::invalid_argument &_e) { + SWIG_exception_fail(SWIG_ValueError, (&_e)->what()); + } + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorT_int8_t_t, SWIG_POINTER_OWN | 0 ); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ibytes___setslice____SWIG_0(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + std::vector< int8_t > *arg1 = (std::vector< int8_t > *) 0 ; + std::vector< signed char >::difference_type arg2 ; + std::vector< signed char >::difference_type arg3 ; + void *argp1 = 0 ; + int res1 = 0 ; + ptrdiff_t val2 ; + int ecode2 = 0 ; + ptrdiff_t val3 ; + int ecode3 = 0 ; + + (void)self; + if ((nobjs < 3) || (nobjs > 3)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_int8_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ibytes___setslice__" "', argument " "1"" of type '" "std::vector< int8_t > *""'"); + } + arg1 = reinterpret_cast< std::vector< int8_t > * >(argp1); + ecode2 = SWIG_AsVal_ptrdiff_t(swig_obj[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ibytes___setslice__" "', argument " "2"" of type '" "std::vector< signed char >::difference_type""'"); + } + arg2 = static_cast< std::vector< signed char >::difference_type >(val2); + ecode3 = SWIG_AsVal_ptrdiff_t(swig_obj[2], &val3); + if (!SWIG_IsOK(ecode3)) { + SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "ibytes___setslice__" "', argument " "3"" of type '" "std::vector< signed char >::difference_type""'"); + } + arg3 = static_cast< std::vector< signed char >::difference_type >(val3); + try { + std_vector_Sl_int8_t_Sg____setslice____SWIG_0(arg1,SWIG_STD_MOVE(arg2),SWIG_STD_MOVE(arg3)); + } catch(std::out_of_range &_e) { + SWIG_exception_fail(SWIG_IndexError, (&_e)->what()); + } catch(std::invalid_argument &_e) { + SWIG_exception_fail(SWIG_ValueError, (&_e)->what()); + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ibytes___setslice____SWIG_1(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + std::vector< int8_t > *arg1 = (std::vector< int8_t > *) 0 ; + std::vector< signed char >::difference_type arg2 ; + std::vector< signed char >::difference_type arg3 ; + std::vector< signed char,std::allocator< signed char > > *arg4 = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + ptrdiff_t val2 ; + int ecode2 = 0 ; + ptrdiff_t val3 ; + int ecode3 = 0 ; + int res4 = SWIG_OLDOBJ ; + + (void)self; + if ((nobjs < 4) || (nobjs > 4)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_int8_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ibytes___setslice__" "', argument " "1"" of type '" "std::vector< int8_t > *""'"); + } + arg1 = reinterpret_cast< std::vector< int8_t > * >(argp1); + ecode2 = SWIG_AsVal_ptrdiff_t(swig_obj[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ibytes___setslice__" "', argument " "2"" of type '" "std::vector< signed char >::difference_type""'"); + } + arg2 = static_cast< std::vector< signed char >::difference_type >(val2); + ecode3 = SWIG_AsVal_ptrdiff_t(swig_obj[2], &val3); + if (!SWIG_IsOK(ecode3)) { + SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "ibytes___setslice__" "', argument " "3"" of type '" "std::vector< signed char >::difference_type""'"); + } + arg3 = static_cast< std::vector< signed char >::difference_type >(val3); + { + std::vector< signed char,std::allocator< signed char > > *ptr = (std::vector< signed char,std::allocator< signed char > > *)0; + res4 = swig::asptr(swig_obj[3], &ptr); + if (!SWIG_IsOK(res4)) { + SWIG_exception_fail(SWIG_ArgError(res4), "in method '" "ibytes___setslice__" "', argument " "4"" of type '" "std::vector< signed char,std::allocator< signed char > > const &""'"); + } + if (!ptr) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "ibytes___setslice__" "', argument " "4"" of type '" "std::vector< signed char,std::allocator< signed char > > const &""'"); + } + arg4 = ptr; + } + try { + std_vector_Sl_int8_t_Sg____setslice____SWIG_1(arg1,SWIG_STD_MOVE(arg2),SWIG_STD_MOVE(arg3),(std::vector< signed char,std::allocator< signed char > > const &)*arg4); + } catch(std::out_of_range &_e) { + SWIG_exception_fail(SWIG_IndexError, (&_e)->what()); + } catch(std::invalid_argument &_e) { + SWIG_exception_fail(SWIG_ValueError, (&_e)->what()); + } + resultobj = SWIG_Py_Void(); + if (SWIG_IsNewObj(res4)) delete arg4; + return resultobj; +fail: + if (SWIG_IsNewObj(res4)) delete arg4; + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ibytes___setslice__(PyObject *self, PyObject *args) { + Py_ssize_t argc; + PyObject *argv[5] = { + 0 + }; + + if (!(argc = SWIG_Python_UnpackTuple(args, "ibytes___setslice__", 0, 4, argv))) SWIG_fail; + --argc; + if (argc == 3) { + int _v = 0; + int res = swig::asptr(argv[0], (std::vector< signed char,std::allocator< signed char > >**)(0)); + _v = SWIG_CheckState(res); + if (_v) { + { + int res = SWIG_AsVal_ptrdiff_t(argv[1], NULL); + _v = SWIG_CheckState(res); + } + if (_v) { + { + int res = SWIG_AsVal_ptrdiff_t(argv[2], NULL); + _v = SWIG_CheckState(res); + } + if (_v) { + return _wrap_ibytes___setslice____SWIG_0(self, argc, argv); + } + } + } + } + if (argc == 4) { + int _v = 0; + int res = swig::asptr(argv[0], (std::vector< signed char,std::allocator< signed char > >**)(0)); + _v = SWIG_CheckState(res); + if (_v) { + { + int res = SWIG_AsVal_ptrdiff_t(argv[1], NULL); + _v = SWIG_CheckState(res); + } + if (_v) { + { + int res = SWIG_AsVal_ptrdiff_t(argv[2], NULL); + _v = SWIG_CheckState(res); + } + if (_v) { + int res = swig::asptr(argv[3], (std::vector< signed char,std::allocator< signed char > >**)(0)); + _v = SWIG_CheckState(res); + if (_v) { + return _wrap_ibytes___setslice____SWIG_1(self, argc, argv); + } + } + } + } + } + +fail: + SWIG_Python_RaiseOrModifyTypeError("Wrong number or type of arguments for overloaded function 'ibytes___setslice__'.\n" + " Possible C/C++ prototypes are:\n" + " std::vector< int8_t >::__setslice__(std::vector< signed char >::difference_type,std::vector< signed char >::difference_type)\n" + " std::vector< int8_t >::__setslice__(std::vector< signed char >::difference_type,std::vector< signed char >::difference_type,std::vector< signed char,std::allocator< signed char > > const &)\n"); + return 0; +} + + +SWIGINTERN PyObject *_wrap_ibytes___delslice__(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< int8_t > *arg1 = (std::vector< int8_t > *) 0 ; + std::vector< signed char >::difference_type arg2 ; + std::vector< signed char >::difference_type arg3 ; + void *argp1 = 0 ; + int res1 = 0 ; + ptrdiff_t val2 ; + int ecode2 = 0 ; + ptrdiff_t val3 ; + int ecode3 = 0 ; + PyObject *swig_obj[3] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "ibytes___delslice__", 3, 3, swig_obj)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_int8_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ibytes___delslice__" "', argument " "1"" of type '" "std::vector< int8_t > *""'"); + } + arg1 = reinterpret_cast< std::vector< int8_t > * >(argp1); + ecode2 = SWIG_AsVal_ptrdiff_t(swig_obj[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ibytes___delslice__" "', argument " "2"" of type '" "std::vector< signed char >::difference_type""'"); + } + arg2 = static_cast< std::vector< signed char >::difference_type >(val2); + ecode3 = SWIG_AsVal_ptrdiff_t(swig_obj[2], &val3); + if (!SWIG_IsOK(ecode3)) { + SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "ibytes___delslice__" "', argument " "3"" of type '" "std::vector< signed char >::difference_type""'"); + } + arg3 = static_cast< std::vector< signed char >::difference_type >(val3); + try { + std_vector_Sl_int8_t_Sg____delslice__(arg1,SWIG_STD_MOVE(arg2),SWIG_STD_MOVE(arg3)); + } catch(std::out_of_range &_e) { + SWIG_exception_fail(SWIG_IndexError, (&_e)->what()); + } catch(std::invalid_argument &_e) { + SWIG_exception_fail(SWIG_ValueError, (&_e)->what()); + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ibytes___delitem____SWIG_0(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + std::vector< int8_t > *arg1 = (std::vector< int8_t > *) 0 ; + std::vector< signed char >::difference_type arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + ptrdiff_t val2 ; + int ecode2 = 0 ; + + (void)self; + if ((nobjs < 2) || (nobjs > 2)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_int8_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ibytes___delitem__" "', argument " "1"" of type '" "std::vector< int8_t > *""'"); + } + arg1 = reinterpret_cast< std::vector< int8_t > * >(argp1); + ecode2 = SWIG_AsVal_ptrdiff_t(swig_obj[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ibytes___delitem__" "', argument " "2"" of type '" "std::vector< signed char >::difference_type""'"); + } + arg2 = static_cast< std::vector< signed char >::difference_type >(val2); + try { + std_vector_Sl_int8_t_Sg____delitem____SWIG_0(arg1,SWIG_STD_MOVE(arg2)); + } catch(std::out_of_range &_e) { + SWIG_exception_fail(SWIG_IndexError, (&_e)->what()); + } catch(std::invalid_argument &_e) { + SWIG_exception_fail(SWIG_ValueError, (&_e)->what()); + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ibytes___getitem____SWIG_0(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + std::vector< int8_t > *arg1 = (std::vector< int8_t > *) 0 ; + SWIGPY_SLICEOBJECT *arg2 = (SWIGPY_SLICEOBJECT *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::vector< signed char,std::allocator< signed char > > *result = 0 ; + + (void)self; + if ((nobjs < 2) || (nobjs > 2)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_int8_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ibytes___getitem__" "', argument " "1"" of type '" "std::vector< int8_t > *""'"); + } + arg1 = reinterpret_cast< std::vector< int8_t > * >(argp1); + { + if (!PySlice_Check(swig_obj[1])) { + SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "ibytes___getitem__" "', argument " "2"" of type '" "SWIGPY_SLICEOBJECT *""'"); + } + arg2 = (SWIGPY_SLICEOBJECT *) swig_obj[1]; + } + try { + result = (std::vector< signed char,std::allocator< signed char > > *)std_vector_Sl_int8_t_Sg____getitem____SWIG_0(arg1,arg2); + } catch(std::out_of_range &_e) { + SWIG_exception_fail(SWIG_IndexError, (&_e)->what()); + } catch(std::invalid_argument &_e) { + SWIG_exception_fail(SWIG_ValueError, (&_e)->what()); + } + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorT_int8_t_t, SWIG_POINTER_OWN | 0 ); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ibytes___setitem____SWIG_0(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + std::vector< int8_t > *arg1 = (std::vector< int8_t > *) 0 ; + SWIGPY_SLICEOBJECT *arg2 = (SWIGPY_SLICEOBJECT *) 0 ; + std::vector< signed char,std::allocator< signed char > > *arg3 = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + int res3 = SWIG_OLDOBJ ; + + (void)self; + if ((nobjs < 3) || (nobjs > 3)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_int8_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ibytes___setitem__" "', argument " "1"" of type '" "std::vector< int8_t > *""'"); + } + arg1 = reinterpret_cast< std::vector< int8_t > * >(argp1); + { + if (!PySlice_Check(swig_obj[1])) { + SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "ibytes___setitem__" "', argument " "2"" of type '" "SWIGPY_SLICEOBJECT *""'"); + } + arg2 = (SWIGPY_SLICEOBJECT *) swig_obj[1]; + } + { + std::vector< signed char,std::allocator< signed char > > *ptr = (std::vector< signed char,std::allocator< signed char > > *)0; + res3 = swig::asptr(swig_obj[2], &ptr); + if (!SWIG_IsOK(res3)) { + SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "ibytes___setitem__" "', argument " "3"" of type '" "std::vector< signed char,std::allocator< signed char > > const &""'"); + } + if (!ptr) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "ibytes___setitem__" "', argument " "3"" of type '" "std::vector< signed char,std::allocator< signed char > > const &""'"); + } + arg3 = ptr; + } + try { + std_vector_Sl_int8_t_Sg____setitem____SWIG_0(arg1,arg2,(std::vector< signed char,std::allocator< signed char > > const &)*arg3); + } catch(std::out_of_range &_e) { + SWIG_exception_fail(SWIG_IndexError, (&_e)->what()); + } catch(std::invalid_argument &_e) { + SWIG_exception_fail(SWIG_ValueError, (&_e)->what()); + } + resultobj = SWIG_Py_Void(); + if (SWIG_IsNewObj(res3)) delete arg3; + return resultobj; +fail: + if (SWIG_IsNewObj(res3)) delete arg3; + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ibytes___setitem____SWIG_1(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + std::vector< int8_t > *arg1 = (std::vector< int8_t > *) 0 ; + SWIGPY_SLICEOBJECT *arg2 = (SWIGPY_SLICEOBJECT *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + + (void)self; + if ((nobjs < 2) || (nobjs > 2)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_int8_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ibytes___setitem__" "', argument " "1"" of type '" "std::vector< int8_t > *""'"); + } + arg1 = reinterpret_cast< std::vector< int8_t > * >(argp1); + { + if (!PySlice_Check(swig_obj[1])) { + SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "ibytes___setitem__" "', argument " "2"" of type '" "SWIGPY_SLICEOBJECT *""'"); + } + arg2 = (SWIGPY_SLICEOBJECT *) swig_obj[1]; + } + try { + std_vector_Sl_int8_t_Sg____setitem____SWIG_1(arg1,arg2); + } catch(std::out_of_range &_e) { + SWIG_exception_fail(SWIG_IndexError, (&_e)->what()); + } catch(std::invalid_argument &_e) { + SWIG_exception_fail(SWIG_ValueError, (&_e)->what()); + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ibytes___delitem____SWIG_1(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + std::vector< int8_t > *arg1 = (std::vector< int8_t > *) 0 ; + SWIGPY_SLICEOBJECT *arg2 = (SWIGPY_SLICEOBJECT *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + + (void)self; + if ((nobjs < 2) || (nobjs > 2)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_int8_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ibytes___delitem__" "', argument " "1"" of type '" "std::vector< int8_t > *""'"); + } + arg1 = reinterpret_cast< std::vector< int8_t > * >(argp1); + { + if (!PySlice_Check(swig_obj[1])) { + SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "ibytes___delitem__" "', argument " "2"" of type '" "SWIGPY_SLICEOBJECT *""'"); + } + arg2 = (SWIGPY_SLICEOBJECT *) swig_obj[1]; + } + try { + std_vector_Sl_int8_t_Sg____delitem____SWIG_1(arg1,arg2); + } catch(std::out_of_range &_e) { + SWIG_exception_fail(SWIG_IndexError, (&_e)->what()); + } catch(std::invalid_argument &_e) { + SWIG_exception_fail(SWIG_ValueError, (&_e)->what()); + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ibytes___delitem__(PyObject *self, PyObject *args) { + Py_ssize_t argc; + PyObject *argv[3] = { + 0 + }; + + if (!(argc = SWIG_Python_UnpackTuple(args, "ibytes___delitem__", 0, 2, argv))) SWIG_fail; + --argc; + if (argc == 2) { + int _v = 0; + int res = swig::asptr(argv[0], (std::vector< signed char,std::allocator< signed char > >**)(0)); + _v = SWIG_CheckState(res); + if (_v) { + { + _v = PySlice_Check(argv[1]); + } + if (_v) { + return _wrap_ibytes___delitem____SWIG_1(self, argc, argv); + } + } + } + if (argc == 2) { + int _v = 0; + int res = swig::asptr(argv[0], (std::vector< signed char,std::allocator< signed char > >**)(0)); + _v = SWIG_CheckState(res); + if (_v) { + { + int res = SWIG_AsVal_ptrdiff_t(argv[1], NULL); + _v = SWIG_CheckState(res); + } + if (_v) { + return _wrap_ibytes___delitem____SWIG_0(self, argc, argv); + } + } + } + +fail: + SWIG_Python_RaiseOrModifyTypeError("Wrong number or type of arguments for overloaded function 'ibytes___delitem__'.\n" + " Possible C/C++ prototypes are:\n" + " std::vector< int8_t >::__delitem__(std::vector< signed char >::difference_type)\n" + " std::vector< int8_t >::__delitem__(SWIGPY_SLICEOBJECT *)\n"); + return 0; +} + + +SWIGINTERN PyObject *_wrap_ibytes___getitem____SWIG_1(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + std::vector< int8_t > *arg1 = (std::vector< int8_t > *) 0 ; + std::vector< signed char >::difference_type arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + ptrdiff_t val2 ; + int ecode2 = 0 ; + std::vector< signed char >::value_type *result = 0 ; + + (void)self; + if ((nobjs < 2) || (nobjs > 2)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_int8_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ibytes___getitem__" "', argument " "1"" of type '" "std::vector< int8_t > const *""'"); + } + arg1 = reinterpret_cast< std::vector< int8_t > * >(argp1); + ecode2 = SWIG_AsVal_ptrdiff_t(swig_obj[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ibytes___getitem__" "', argument " "2"" of type '" "std::vector< signed char >::difference_type""'"); + } + arg2 = static_cast< std::vector< signed char >::difference_type >(val2); + try { + result = (std::vector< signed char >::value_type *) &std_vector_Sl_int8_t_Sg____getitem____SWIG_1((std::vector< signed char > const *)arg1,SWIG_STD_MOVE(arg2)); + } catch(std::out_of_range &_e) { + SWIG_exception_fail(SWIG_IndexError, (&_e)->what()); + } + resultobj = SWIG_From_signed_SS_char(static_cast< signed char >(*result)); + (void)swig::container_owner::value_type>::category>::back_reference(resultobj, swig_obj[0]); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ibytes___getitem__(PyObject *self, PyObject *args) { + Py_ssize_t argc; + PyObject *argv[3] = { + 0 + }; + + if (!(argc = SWIG_Python_UnpackTuple(args, "ibytes___getitem__", 0, 2, argv))) SWIG_fail; + --argc; + if (argc == 2) { + int _v = 0; + int res = swig::asptr(argv[0], (std::vector< signed char,std::allocator< signed char > >**)(0)); + _v = SWIG_CheckState(res); + if (_v) { + { + _v = PySlice_Check(argv[1]); + } + if (_v) { + return _wrap_ibytes___getitem____SWIG_0(self, argc, argv); + } + } + } + if (argc == 2) { + int _v = 0; + int res = swig::asptr(argv[0], (std::vector< signed char,std::allocator< signed char > >**)(0)); + _v = SWIG_CheckState(res); + if (_v) { + { + int res = SWIG_AsVal_ptrdiff_t(argv[1], NULL); + _v = SWIG_CheckState(res); + } + if (_v) { + return _wrap_ibytes___getitem____SWIG_1(self, argc, argv); + } + } + } + +fail: + SWIG_Python_RaiseOrModifyTypeError("Wrong number or type of arguments for overloaded function 'ibytes___getitem__'.\n" + " Possible C/C++ prototypes are:\n" + " std::vector< int8_t >::__getitem__(SWIGPY_SLICEOBJECT *)\n" + " std::vector< int8_t >::__getitem__(std::vector< signed char >::difference_type) const\n"); + return 0; +} + + +SWIGINTERN PyObject *_wrap_ibytes___setitem____SWIG_2(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + std::vector< int8_t > *arg1 = (std::vector< int8_t > *) 0 ; + std::vector< signed char >::difference_type arg2 ; + std::vector< signed char >::value_type *arg3 = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + ptrdiff_t val2 ; + int ecode2 = 0 ; + std::vector< signed char >::value_type temp3 ; + signed char val3 ; + int ecode3 = 0 ; + + (void)self; + if ((nobjs < 3) || (nobjs > 3)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_int8_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ibytes___setitem__" "', argument " "1"" of type '" "std::vector< int8_t > *""'"); + } + arg1 = reinterpret_cast< std::vector< int8_t > * >(argp1); + ecode2 = SWIG_AsVal_ptrdiff_t(swig_obj[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ibytes___setitem__" "', argument " "2"" of type '" "std::vector< signed char >::difference_type""'"); + } + arg2 = static_cast< std::vector< signed char >::difference_type >(val2); + ecode3 = SWIG_AsVal_signed_SS_char(swig_obj[2], &val3); + if (!SWIG_IsOK(ecode3)) { + SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "ibytes___setitem__" "', argument " "3"" of type '" "std::vector< signed char >::value_type""'"); + } + temp3 = static_cast< std::vector< signed char >::value_type >(val3); + arg3 = &temp3; + try { + std_vector_Sl_int8_t_Sg____setitem____SWIG_2(arg1,SWIG_STD_MOVE(arg2),(signed char const &)*arg3); + } catch(std::out_of_range &_e) { + SWIG_exception_fail(SWIG_IndexError, (&_e)->what()); + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ibytes___setitem__(PyObject *self, PyObject *args) { + Py_ssize_t argc; + PyObject *argv[4] = { + 0 + }; + + if (!(argc = SWIG_Python_UnpackTuple(args, "ibytes___setitem__", 0, 3, argv))) SWIG_fail; + --argc; + if (argc == 2) { + int _v = 0; + int res = swig::asptr(argv[0], (std::vector< signed char,std::allocator< signed char > >**)(0)); + _v = SWIG_CheckState(res); + if (_v) { + { + _v = PySlice_Check(argv[1]); + } + if (_v) { + return _wrap_ibytes___setitem____SWIG_1(self, argc, argv); + } + } + } + if (argc == 3) { + int _v = 0; + int res = swig::asptr(argv[0], (std::vector< signed char,std::allocator< signed char > >**)(0)); + _v = SWIG_CheckState(res); + if (_v) { + { + _v = PySlice_Check(argv[1]); + } + if (_v) { + int res = swig::asptr(argv[2], (std::vector< signed char,std::allocator< signed char > >**)(0)); + _v = SWIG_CheckState(res); + if (_v) { + return _wrap_ibytes___setitem____SWIG_0(self, argc, argv); + } + } + } + } + if (argc == 3) { + int _v = 0; + int res = swig::asptr(argv[0], (std::vector< signed char,std::allocator< signed char > >**)(0)); + _v = SWIG_CheckState(res); + if (_v) { + { + int res = SWIG_AsVal_ptrdiff_t(argv[1], NULL); + _v = SWIG_CheckState(res); + } + if (_v) { + { + int res = SWIG_AsVal_signed_SS_char(argv[2], NULL); + _v = SWIG_CheckState(res); + } + if (_v) { + return _wrap_ibytes___setitem____SWIG_2(self, argc, argv); + } + } + } + } + +fail: + SWIG_Python_RaiseOrModifyTypeError("Wrong number or type of arguments for overloaded function 'ibytes___setitem__'.\n" + " Possible C/C++ prototypes are:\n" + " std::vector< int8_t >::__setitem__(SWIGPY_SLICEOBJECT *,std::vector< signed char,std::allocator< signed char > > const &)\n" + " std::vector< int8_t >::__setitem__(SWIGPY_SLICEOBJECT *)\n" + " std::vector< int8_t >::__setitem__(std::vector< signed char >::difference_type,std::vector< signed char >::value_type const &)\n"); + return 0; +} + + +SWIGINTERN PyObject *_wrap_ibytes_pop(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< int8_t > *arg1 = (std::vector< int8_t > *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + std::vector< signed char >::value_type result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_int8_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ibytes_pop" "', argument " "1"" of type '" "std::vector< int8_t > *""'"); + } + arg1 = reinterpret_cast< std::vector< int8_t > * >(argp1); + try { + result = (std::vector< signed char >::value_type)std_vector_Sl_int8_t_Sg__pop(arg1); + } catch(std::out_of_range &_e) { + SWIG_exception_fail(SWIG_IndexError, (&_e)->what()); + } + resultobj = SWIG_From_signed_SS_char(static_cast< signed char >(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ibytes_append(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< int8_t > *arg1 = (std::vector< int8_t > *) 0 ; + std::vector< signed char >::value_type *arg2 = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::vector< signed char >::value_type temp2 ; + signed char val2 ; + int ecode2 = 0 ; + PyObject *swig_obj[2] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "ibytes_append", 2, 2, swig_obj)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_int8_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ibytes_append" "', argument " "1"" of type '" "std::vector< int8_t > *""'"); + } + arg1 = reinterpret_cast< std::vector< int8_t > * >(argp1); + ecode2 = SWIG_AsVal_signed_SS_char(swig_obj[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ibytes_append" "', argument " "2"" of type '" "std::vector< signed char >::value_type""'"); + } + temp2 = static_cast< std::vector< signed char >::value_type >(val2); + arg2 = &temp2; + std_vector_Sl_int8_t_Sg__append(arg1,(signed char const &)*arg2); + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_new_ibytes__SWIG_0(PyObject *self, Py_ssize_t nobjs, PyObject **SWIGUNUSEDPARM(swig_obj)) { + PyObject *resultobj = 0; + std::vector< int8_t > *result = 0 ; + + (void)self; + if ((nobjs < 0) || (nobjs > 0)) SWIG_fail; + result = (std::vector< int8_t > *)new std::vector< int8_t >(); + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorT_int8_t_t, SWIG_POINTER_NEW | 0 ); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_new_ibytes__SWIG_1(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + std::vector< int8_t > *arg1 = 0 ; + int res1 = SWIG_OLDOBJ ; + std::vector< int8_t > *result = 0 ; + + (void)self; + if ((nobjs < 1) || (nobjs > 1)) SWIG_fail; + { + std::vector< signed char,std::allocator< signed char > > *ptr = (std::vector< signed char,std::allocator< signed char > > *)0; + res1 = swig::asptr(swig_obj[0], &ptr); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "new_ibytes" "', argument " "1"" of type '" "std::vector< int8_t > const &""'"); + } + if (!ptr) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_ibytes" "', argument " "1"" of type '" "std::vector< int8_t > const &""'"); + } + arg1 = ptr; + } + result = (std::vector< int8_t > *)new std::vector< int8_t >((std::vector< int8_t > const &)*arg1); + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorT_int8_t_t, SWIG_POINTER_NEW | 0 ); + if (SWIG_IsNewObj(res1)) delete arg1; + return resultobj; +fail: + if (SWIG_IsNewObj(res1)) delete arg1; + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ibytes_empty(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< int8_t > *arg1 = (std::vector< int8_t > *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + bool result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_int8_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ibytes_empty" "', argument " "1"" of type '" "std::vector< int8_t > const *""'"); + } + arg1 = reinterpret_cast< std::vector< int8_t > * >(argp1); + result = (bool)((std::vector< int8_t > const *)arg1)->empty(); + resultobj = SWIG_From_bool(static_cast< bool >(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ibytes_size(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< int8_t > *arg1 = (std::vector< int8_t > *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + std::vector< signed char >::size_type result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_int8_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ibytes_size" "', argument " "1"" of type '" "std::vector< int8_t > const *""'"); + } + arg1 = reinterpret_cast< std::vector< int8_t > * >(argp1); + result = ((std::vector< int8_t > const *)arg1)->size(); + resultobj = SWIG_From_size_t(static_cast< size_t >(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ibytes_swap(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< int8_t > *arg1 = (std::vector< int8_t > *) 0 ; + std::vector< int8_t > *arg2 = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + void *argp2 = 0 ; + int res2 = 0 ; + PyObject *swig_obj[2] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "ibytes_swap", 2, 2, swig_obj)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_int8_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ibytes_swap" "', argument " "1"" of type '" "std::vector< int8_t > *""'"); + } + arg1 = reinterpret_cast< std::vector< int8_t > * >(argp1); + res2 = SWIG_ConvertPtr(swig_obj[1], &argp2, SWIGTYPE_p_std__vectorT_int8_t_t, 0 ); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "ibytes_swap" "', argument " "2"" of type '" "std::vector< int8_t > &""'"); + } + if (!argp2) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "ibytes_swap" "', argument " "2"" of type '" "std::vector< int8_t > &""'"); + } + arg2 = reinterpret_cast< std::vector< int8_t > * >(argp2); + (arg1)->swap(*arg2); + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ibytes_begin(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< int8_t > *arg1 = (std::vector< int8_t > *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + SwigValueWrapper< std::vector< signed char >::iterator > result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_int8_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ibytes_begin" "', argument " "1"" of type '" "std::vector< int8_t > *""'"); + } + arg1 = reinterpret_cast< std::vector< int8_t > * >(argp1); + result = (arg1)->begin(); + resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector< signed char >::iterator & >(result)), + swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ibytes_end(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< int8_t > *arg1 = (std::vector< int8_t > *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + SwigValueWrapper< std::vector< signed char >::iterator > result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_int8_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ibytes_end" "', argument " "1"" of type '" "std::vector< int8_t > *""'"); + } + arg1 = reinterpret_cast< std::vector< int8_t > * >(argp1); + result = (arg1)->end(); + resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector< signed char >::iterator & >(result)), + swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ibytes_rbegin(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< int8_t > *arg1 = (std::vector< int8_t > *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + SwigValueWrapper< std::vector< signed char >::reverse_iterator > result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_int8_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ibytes_rbegin" "', argument " "1"" of type '" "std::vector< int8_t > *""'"); + } + arg1 = reinterpret_cast< std::vector< int8_t > * >(argp1); + result = (arg1)->rbegin(); + resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector< signed char >::reverse_iterator & >(result)), + swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ibytes_rend(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< int8_t > *arg1 = (std::vector< int8_t > *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + SwigValueWrapper< std::vector< signed char >::reverse_iterator > result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_int8_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ibytes_rend" "', argument " "1"" of type '" "std::vector< int8_t > *""'"); + } + arg1 = reinterpret_cast< std::vector< int8_t > * >(argp1); + result = (arg1)->rend(); + resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector< signed char >::reverse_iterator & >(result)), + swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ibytes_clear(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< int8_t > *arg1 = (std::vector< int8_t > *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_int8_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ibytes_clear" "', argument " "1"" of type '" "std::vector< int8_t > *""'"); + } + arg1 = reinterpret_cast< std::vector< int8_t > * >(argp1); + (arg1)->clear(); + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ibytes_get_allocator(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< int8_t > *arg1 = (std::vector< int8_t > *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + SwigValueWrapper< std::allocator< signed char > > result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_int8_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ibytes_get_allocator" "', argument " "1"" of type '" "std::vector< int8_t > const *""'"); + } + arg1 = reinterpret_cast< std::vector< int8_t > * >(argp1); + result = ((std::vector< int8_t > const *)arg1)->get_allocator(); + resultobj = SWIG_NewPointerObj((new std::vector< signed char >::allocator_type(result)), SWIGTYPE_p_std__allocatorT_signed_char_t, SWIG_POINTER_OWN | 0 ); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_new_ibytes__SWIG_2(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + std::vector< signed char >::size_type arg1 ; + size_t val1 ; + int ecode1 = 0 ; + std::vector< int8_t > *result = 0 ; + + (void)self; + if ((nobjs < 1) || (nobjs > 1)) SWIG_fail; + ecode1 = SWIG_AsVal_size_t(swig_obj[0], &val1); + if (!SWIG_IsOK(ecode1)) { + SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "new_ibytes" "', argument " "1"" of type '" "std::vector< signed char >::size_type""'"); + } + arg1 = static_cast< std::vector< signed char >::size_type >(val1); + result = (std::vector< int8_t > *)new std::vector< int8_t >(arg1); + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorT_int8_t_t, SWIG_POINTER_NEW | 0 ); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ibytes_pop_back(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< int8_t > *arg1 = (std::vector< int8_t > *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_int8_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ibytes_pop_back" "', argument " "1"" of type '" "std::vector< int8_t > *""'"); + } + arg1 = reinterpret_cast< std::vector< int8_t > * >(argp1); + (arg1)->pop_back(); + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ibytes_resize__SWIG_0(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + std::vector< int8_t > *arg1 = (std::vector< int8_t > *) 0 ; + std::vector< signed char >::size_type arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + size_t val2 ; + int ecode2 = 0 ; + + (void)self; + if ((nobjs < 2) || (nobjs > 2)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_int8_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ibytes_resize" "', argument " "1"" of type '" "std::vector< int8_t > *""'"); + } + arg1 = reinterpret_cast< std::vector< int8_t > * >(argp1); + ecode2 = SWIG_AsVal_size_t(swig_obj[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ibytes_resize" "', argument " "2"" of type '" "std::vector< signed char >::size_type""'"); + } + arg2 = static_cast< std::vector< signed char >::size_type >(val2); + (arg1)->resize(arg2); + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ibytes_erase__SWIG_0(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + std::vector< int8_t > *arg1 = (std::vector< int8_t > *) 0 ; + SwigValueWrapper< std::vector< signed char >::iterator > arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + swig::SwigPyIterator *iter2 = 0 ; + int res2 ; + SwigValueWrapper< std::vector< signed char >::iterator > result; + + (void)self; + if ((nobjs < 2) || (nobjs > 2)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_int8_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ibytes_erase" "', argument " "1"" of type '" "std::vector< int8_t > *""'"); + } + arg1 = reinterpret_cast< std::vector< int8_t > * >(argp1); + res2 = SWIG_ConvertPtr(swig_obj[1], SWIG_as_voidptrptr(&iter2), swig::SwigPyIterator::descriptor(), 0); + if (!SWIG_IsOK(res2) || !iter2) { + SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "ibytes_erase" "', argument " "2"" of type '" "std::vector< signed char >::iterator""'"); + } else { + swig::SwigPyIterator_T::iterator > *iter_t = dynamic_cast::iterator > *>(iter2); + if (iter_t) { + arg2 = iter_t->get_current(); + } else { + SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "ibytes_erase" "', argument " "2"" of type '" "std::vector< signed char >::iterator""'"); + } + } + result = std_vector_Sl_int8_t_Sg__erase__SWIG_0(arg1,SWIG_STD_MOVE(arg2)); + resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector< signed char >::iterator & >(result)), + swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ibytes_erase__SWIG_1(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + std::vector< int8_t > *arg1 = (std::vector< int8_t > *) 0 ; + SwigValueWrapper< std::vector< signed char >::iterator > arg2 ; + SwigValueWrapper< std::vector< signed char >::iterator > arg3 ; + void *argp1 = 0 ; + int res1 = 0 ; + swig::SwigPyIterator *iter2 = 0 ; + int res2 ; + swig::SwigPyIterator *iter3 = 0 ; + int res3 ; + SwigValueWrapper< std::vector< signed char >::iterator > result; + + (void)self; + if ((nobjs < 3) || (nobjs > 3)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_int8_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ibytes_erase" "', argument " "1"" of type '" "std::vector< int8_t > *""'"); + } + arg1 = reinterpret_cast< std::vector< int8_t > * >(argp1); + res2 = SWIG_ConvertPtr(swig_obj[1], SWIG_as_voidptrptr(&iter2), swig::SwigPyIterator::descriptor(), 0); + if (!SWIG_IsOK(res2) || !iter2) { + SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "ibytes_erase" "', argument " "2"" of type '" "std::vector< signed char >::iterator""'"); + } else { + swig::SwigPyIterator_T::iterator > *iter_t = dynamic_cast::iterator > *>(iter2); + if (iter_t) { + arg2 = iter_t->get_current(); + } else { + SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "ibytes_erase" "', argument " "2"" of type '" "std::vector< signed char >::iterator""'"); + } + } + res3 = SWIG_ConvertPtr(swig_obj[2], SWIG_as_voidptrptr(&iter3), swig::SwigPyIterator::descriptor(), 0); + if (!SWIG_IsOK(res3) || !iter3) { + SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "ibytes_erase" "', argument " "3"" of type '" "std::vector< signed char >::iterator""'"); + } else { + swig::SwigPyIterator_T::iterator > *iter_t = dynamic_cast::iterator > *>(iter3); + if (iter_t) { + arg3 = iter_t->get_current(); + } else { + SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "ibytes_erase" "', argument " "3"" of type '" "std::vector< signed char >::iterator""'"); + } + } + result = std_vector_Sl_int8_t_Sg__erase__SWIG_1(arg1,SWIG_STD_MOVE(arg2),SWIG_STD_MOVE(arg3)); + resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector< signed char >::iterator & >(result)), + swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ibytes_erase(PyObject *self, PyObject *args) { + Py_ssize_t argc; + PyObject *argv[4] = { + 0 + }; + + if (!(argc = SWIG_Python_UnpackTuple(args, "ibytes_erase", 0, 3, argv))) SWIG_fail; + --argc; + if (argc == 2) { + int _v = 0; + int res = swig::asptr(argv[0], (std::vector< signed char,std::allocator< signed char > >**)(0)); + _v = SWIG_CheckState(res); + if (_v) { + swig::SwigPyIterator *iter = 0; + int res = SWIG_ConvertPtr(argv[1], SWIG_as_voidptrptr(&iter), swig::SwigPyIterator::descriptor(), 0); + _v = (SWIG_IsOK(res) && iter && (dynamic_cast::iterator > *>(iter) != 0)); + if (_v) { + return _wrap_ibytes_erase__SWIG_0(self, argc, argv); + } + } + } + if (argc == 3) { + int _v = 0; + int res = swig::asptr(argv[0], (std::vector< signed char,std::allocator< signed char > >**)(0)); + _v = SWIG_CheckState(res); + if (_v) { + swig::SwigPyIterator *iter = 0; + int res = SWIG_ConvertPtr(argv[1], SWIG_as_voidptrptr(&iter), swig::SwigPyIterator::descriptor(), 0); + _v = (SWIG_IsOK(res) && iter && (dynamic_cast::iterator > *>(iter) != 0)); + if (_v) { + swig::SwigPyIterator *iter = 0; + int res = SWIG_ConvertPtr(argv[2], SWIG_as_voidptrptr(&iter), swig::SwigPyIterator::descriptor(), 0); + _v = (SWIG_IsOK(res) && iter && (dynamic_cast::iterator > *>(iter) != 0)); + if (_v) { + return _wrap_ibytes_erase__SWIG_1(self, argc, argv); + } + } + } + } + +fail: + SWIG_Python_RaiseOrModifyTypeError("Wrong number or type of arguments for overloaded function 'ibytes_erase'.\n" + " Possible C/C++ prototypes are:\n" + " std::vector< int8_t >::erase(std::vector< signed char >::iterator)\n" + " std::vector< int8_t >::erase(std::vector< signed char >::iterator,std::vector< signed char >::iterator)\n"); + return 0; +} + + +SWIGINTERN PyObject *_wrap_new_ibytes__SWIG_3(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + std::vector< signed char >::size_type arg1 ; + std::vector< signed char >::value_type *arg2 = 0 ; + size_t val1 ; + int ecode1 = 0 ; + std::vector< signed char >::value_type temp2 ; + signed char val2 ; + int ecode2 = 0 ; + std::vector< int8_t > *result = 0 ; + + (void)self; + if ((nobjs < 2) || (nobjs > 2)) SWIG_fail; + ecode1 = SWIG_AsVal_size_t(swig_obj[0], &val1); + if (!SWIG_IsOK(ecode1)) { + SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "new_ibytes" "', argument " "1"" of type '" "std::vector< signed char >::size_type""'"); + } + arg1 = static_cast< std::vector< signed char >::size_type >(val1); + ecode2 = SWIG_AsVal_signed_SS_char(swig_obj[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "new_ibytes" "', argument " "2"" of type '" "std::vector< signed char >::value_type""'"); + } + temp2 = static_cast< std::vector< signed char >::value_type >(val2); + arg2 = &temp2; + result = (std::vector< int8_t > *)new std::vector< int8_t >(arg1,(std::vector< signed char >::value_type const &)*arg2); + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorT_int8_t_t, SWIG_POINTER_NEW | 0 ); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_new_ibytes(PyObject *self, PyObject *args) { + Py_ssize_t argc; + PyObject *argv[3] = { + 0 + }; + + if (!(argc = SWIG_Python_UnpackTuple(args, "new_ibytes", 0, 2, argv))) SWIG_fail; + --argc; + if (argc == 0) { + return _wrap_new_ibytes__SWIG_0(self, argc, argv); + } + if (argc == 1) { + int _v = 0; + { + int res = SWIG_AsVal_size_t(argv[0], NULL); + _v = SWIG_CheckState(res); + } + if (_v) { + return _wrap_new_ibytes__SWIG_2(self, argc, argv); + } + } + if (argc == 1) { + int _v = 0; + int res = swig::asptr(argv[0], (std::vector< signed char,std::allocator< signed char > >**)(0)); + _v = SWIG_CheckState(res); + if (_v) { + return _wrap_new_ibytes__SWIG_1(self, argc, argv); + } + } + if (argc == 2) { + int _v = 0; + { + int res = SWIG_AsVal_size_t(argv[0], NULL); + _v = SWIG_CheckState(res); + } + if (_v) { + { + int res = SWIG_AsVal_signed_SS_char(argv[1], NULL); + _v = SWIG_CheckState(res); + } + if (_v) { + return _wrap_new_ibytes__SWIG_3(self, argc, argv); + } + } + } + +fail: + SWIG_Python_RaiseOrModifyTypeError("Wrong number or type of arguments for overloaded function 'new_ibytes'.\n" + " Possible C/C++ prototypes are:\n" + " std::vector< int8_t >::vector()\n" + " std::vector< int8_t >::vector(std::vector< int8_t > const &)\n" + " std::vector< int8_t >::vector(std::vector< signed char >::size_type)\n" + " std::vector< int8_t >::vector(std::vector< signed char >::size_type,std::vector< signed char >::value_type const &)\n"); + return 0; +} + + +SWIGINTERN PyObject *_wrap_ibytes_push_back(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< int8_t > *arg1 = (std::vector< int8_t > *) 0 ; + std::vector< signed char >::value_type *arg2 = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::vector< signed char >::value_type temp2 ; + signed char val2 ; + int ecode2 = 0 ; + PyObject *swig_obj[2] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "ibytes_push_back", 2, 2, swig_obj)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_int8_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ibytes_push_back" "', argument " "1"" of type '" "std::vector< int8_t > *""'"); + } + arg1 = reinterpret_cast< std::vector< int8_t > * >(argp1); + ecode2 = SWIG_AsVal_signed_SS_char(swig_obj[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ibytes_push_back" "', argument " "2"" of type '" "std::vector< signed char >::value_type""'"); + } + temp2 = static_cast< std::vector< signed char >::value_type >(val2); + arg2 = &temp2; + (arg1)->push_back((std::vector< signed char >::value_type const &)*arg2); + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ibytes_front(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< int8_t > *arg1 = (std::vector< int8_t > *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + std::vector< signed char >::value_type *result = 0 ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_int8_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ibytes_front" "', argument " "1"" of type '" "std::vector< int8_t > const *""'"); + } + arg1 = reinterpret_cast< std::vector< int8_t > * >(argp1); + result = (std::vector< signed char >::value_type *) &((std::vector< int8_t > const *)arg1)->front(); + resultobj = SWIG_From_signed_SS_char(static_cast< signed char >(*result)); + (void)swig::container_owner::value_type>::category>::back_reference(resultobj, swig_obj[0]); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ibytes_back(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< int8_t > *arg1 = (std::vector< int8_t > *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + std::vector< signed char >::value_type *result = 0 ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_int8_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ibytes_back" "', argument " "1"" of type '" "std::vector< int8_t > const *""'"); + } + arg1 = reinterpret_cast< std::vector< int8_t > * >(argp1); + result = (std::vector< signed char >::value_type *) &((std::vector< int8_t > const *)arg1)->back(); + resultobj = SWIG_From_signed_SS_char(static_cast< signed char >(*result)); + (void)swig::container_owner::value_type>::category>::back_reference(resultobj, swig_obj[0]); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ibytes_assign(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< int8_t > *arg1 = (std::vector< int8_t > *) 0 ; + std::vector< signed char >::size_type arg2 ; + std::vector< signed char >::value_type *arg3 = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + size_t val2 ; + int ecode2 = 0 ; + std::vector< signed char >::value_type temp3 ; + signed char val3 ; + int ecode3 = 0 ; + PyObject *swig_obj[3] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "ibytes_assign", 3, 3, swig_obj)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_int8_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ibytes_assign" "', argument " "1"" of type '" "std::vector< int8_t > *""'"); + } + arg1 = reinterpret_cast< std::vector< int8_t > * >(argp1); + ecode2 = SWIG_AsVal_size_t(swig_obj[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ibytes_assign" "', argument " "2"" of type '" "std::vector< signed char >::size_type""'"); + } + arg2 = static_cast< std::vector< signed char >::size_type >(val2); + ecode3 = SWIG_AsVal_signed_SS_char(swig_obj[2], &val3); + if (!SWIG_IsOK(ecode3)) { + SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "ibytes_assign" "', argument " "3"" of type '" "std::vector< signed char >::value_type""'"); + } + temp3 = static_cast< std::vector< signed char >::value_type >(val3); + arg3 = &temp3; + (arg1)->assign(arg2,(std::vector< signed char >::value_type const &)*arg3); + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ibytes_resize__SWIG_1(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + std::vector< int8_t > *arg1 = (std::vector< int8_t > *) 0 ; + std::vector< signed char >::size_type arg2 ; + std::vector< signed char >::value_type *arg3 = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + size_t val2 ; + int ecode2 = 0 ; + std::vector< signed char >::value_type temp3 ; + signed char val3 ; + int ecode3 = 0 ; + + (void)self; + if ((nobjs < 3) || (nobjs > 3)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_int8_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ibytes_resize" "', argument " "1"" of type '" "std::vector< int8_t > *""'"); + } + arg1 = reinterpret_cast< std::vector< int8_t > * >(argp1); + ecode2 = SWIG_AsVal_size_t(swig_obj[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ibytes_resize" "', argument " "2"" of type '" "std::vector< signed char >::size_type""'"); + } + arg2 = static_cast< std::vector< signed char >::size_type >(val2); + ecode3 = SWIG_AsVal_signed_SS_char(swig_obj[2], &val3); + if (!SWIG_IsOK(ecode3)) { + SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "ibytes_resize" "', argument " "3"" of type '" "std::vector< signed char >::value_type""'"); + } + temp3 = static_cast< std::vector< signed char >::value_type >(val3); + arg3 = &temp3; + (arg1)->resize(arg2,(std::vector< signed char >::value_type const &)*arg3); + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ibytes_resize(PyObject *self, PyObject *args) { + Py_ssize_t argc; + PyObject *argv[4] = { + 0 + }; + + if (!(argc = SWIG_Python_UnpackTuple(args, "ibytes_resize", 0, 3, argv))) SWIG_fail; + --argc; + if (argc == 2) { + int _v = 0; + int res = swig::asptr(argv[0], (std::vector< signed char,std::allocator< signed char > >**)(0)); + _v = SWIG_CheckState(res); + if (_v) { + { + int res = SWIG_AsVal_size_t(argv[1], NULL); + _v = SWIG_CheckState(res); + } + if (_v) { + return _wrap_ibytes_resize__SWIG_0(self, argc, argv); + } + } + } + if (argc == 3) { + int _v = 0; + int res = swig::asptr(argv[0], (std::vector< signed char,std::allocator< signed char > >**)(0)); + _v = SWIG_CheckState(res); + if (_v) { + { + int res = SWIG_AsVal_size_t(argv[1], NULL); + _v = SWIG_CheckState(res); + } + if (_v) { + { + int res = SWIG_AsVal_signed_SS_char(argv[2], NULL); + _v = SWIG_CheckState(res); + } + if (_v) { + return _wrap_ibytes_resize__SWIG_1(self, argc, argv); + } + } + } + } + +fail: + SWIG_Python_RaiseOrModifyTypeError("Wrong number or type of arguments for overloaded function 'ibytes_resize'.\n" + " Possible C/C++ prototypes are:\n" + " std::vector< int8_t >::resize(std::vector< signed char >::size_type)\n" + " std::vector< int8_t >::resize(std::vector< signed char >::size_type,std::vector< signed char >::value_type const &)\n"); + return 0; +} + + +SWIGINTERN PyObject *_wrap_ibytes_insert__SWIG_0(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + std::vector< int8_t > *arg1 = (std::vector< int8_t > *) 0 ; + SwigValueWrapper< std::vector< signed char >::iterator > arg2 ; + std::vector< signed char >::value_type *arg3 = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + swig::SwigPyIterator *iter2 = 0 ; + int res2 ; + std::vector< signed char >::value_type temp3 ; + signed char val3 ; + int ecode3 = 0 ; + SwigValueWrapper< std::vector< signed char >::iterator > result; + + (void)self; + if ((nobjs < 3) || (nobjs > 3)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_int8_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ibytes_insert" "', argument " "1"" of type '" "std::vector< int8_t > *""'"); + } + arg1 = reinterpret_cast< std::vector< int8_t > * >(argp1); + res2 = SWIG_ConvertPtr(swig_obj[1], SWIG_as_voidptrptr(&iter2), swig::SwigPyIterator::descriptor(), 0); + if (!SWIG_IsOK(res2) || !iter2) { + SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "ibytes_insert" "', argument " "2"" of type '" "std::vector< signed char >::iterator""'"); + } else { + swig::SwigPyIterator_T::iterator > *iter_t = dynamic_cast::iterator > *>(iter2); + if (iter_t) { + arg2 = iter_t->get_current(); + } else { + SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "ibytes_insert" "', argument " "2"" of type '" "std::vector< signed char >::iterator""'"); + } + } + ecode3 = SWIG_AsVal_signed_SS_char(swig_obj[2], &val3); + if (!SWIG_IsOK(ecode3)) { + SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "ibytes_insert" "', argument " "3"" of type '" "std::vector< signed char >::value_type""'"); + } + temp3 = static_cast< std::vector< signed char >::value_type >(val3); + arg3 = &temp3; + result = std_vector_Sl_int8_t_Sg__insert__SWIG_0(arg1,SWIG_STD_MOVE(arg2),(signed char const &)*arg3); + resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector< signed char >::iterator & >(result)), + swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ibytes_insert__SWIG_1(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + std::vector< int8_t > *arg1 = (std::vector< int8_t > *) 0 ; + SwigValueWrapper< std::vector< signed char >::iterator > arg2 ; + std::vector< signed char >::size_type arg3 ; + std::vector< signed char >::value_type *arg4 = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + swig::SwigPyIterator *iter2 = 0 ; + int res2 ; + size_t val3 ; + int ecode3 = 0 ; + std::vector< signed char >::value_type temp4 ; + signed char val4 ; + int ecode4 = 0 ; + + (void)self; + if ((nobjs < 4) || (nobjs > 4)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_int8_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ibytes_insert" "', argument " "1"" of type '" "std::vector< int8_t > *""'"); + } + arg1 = reinterpret_cast< std::vector< int8_t > * >(argp1); + res2 = SWIG_ConvertPtr(swig_obj[1], SWIG_as_voidptrptr(&iter2), swig::SwigPyIterator::descriptor(), 0); + if (!SWIG_IsOK(res2) || !iter2) { + SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "ibytes_insert" "', argument " "2"" of type '" "std::vector< signed char >::iterator""'"); + } else { + swig::SwigPyIterator_T::iterator > *iter_t = dynamic_cast::iterator > *>(iter2); + if (iter_t) { + arg2 = iter_t->get_current(); + } else { + SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "ibytes_insert" "', argument " "2"" of type '" "std::vector< signed char >::iterator""'"); + } + } + ecode3 = SWIG_AsVal_size_t(swig_obj[2], &val3); + if (!SWIG_IsOK(ecode3)) { + SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "ibytes_insert" "', argument " "3"" of type '" "std::vector< signed char >::size_type""'"); + } + arg3 = static_cast< std::vector< signed char >::size_type >(val3); + ecode4 = SWIG_AsVal_signed_SS_char(swig_obj[3], &val4); + if (!SWIG_IsOK(ecode4)) { + SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "ibytes_insert" "', argument " "4"" of type '" "std::vector< signed char >::value_type""'"); + } + temp4 = static_cast< std::vector< signed char >::value_type >(val4); + arg4 = &temp4; + std_vector_Sl_int8_t_Sg__insert__SWIG_1(arg1,SWIG_STD_MOVE(arg2),SWIG_STD_MOVE(arg3),(signed char const &)*arg4); + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ibytes_insert(PyObject *self, PyObject *args) { + Py_ssize_t argc; + PyObject *argv[5] = { + 0 + }; + + if (!(argc = SWIG_Python_UnpackTuple(args, "ibytes_insert", 0, 4, argv))) SWIG_fail; + --argc; + if (argc == 3) { + int _v = 0; + int res = swig::asptr(argv[0], (std::vector< signed char,std::allocator< signed char > >**)(0)); + _v = SWIG_CheckState(res); + if (_v) { + swig::SwigPyIterator *iter = 0; + int res = SWIG_ConvertPtr(argv[1], SWIG_as_voidptrptr(&iter), swig::SwigPyIterator::descriptor(), 0); + _v = (SWIG_IsOK(res) && iter && (dynamic_cast::iterator > *>(iter) != 0)); + if (_v) { + { + int res = SWIG_AsVal_signed_SS_char(argv[2], NULL); + _v = SWIG_CheckState(res); + } + if (_v) { + return _wrap_ibytes_insert__SWIG_0(self, argc, argv); + } + } + } + } + if (argc == 4) { + int _v = 0; + int res = swig::asptr(argv[0], (std::vector< signed char,std::allocator< signed char > >**)(0)); + _v = SWIG_CheckState(res); + if (_v) { + swig::SwigPyIterator *iter = 0; + int res = SWIG_ConvertPtr(argv[1], SWIG_as_voidptrptr(&iter), swig::SwigPyIterator::descriptor(), 0); + _v = (SWIG_IsOK(res) && iter && (dynamic_cast::iterator > *>(iter) != 0)); + if (_v) { + { + int res = SWIG_AsVal_size_t(argv[2], NULL); + _v = SWIG_CheckState(res); + } + if (_v) { + { + int res = SWIG_AsVal_signed_SS_char(argv[3], NULL); + _v = SWIG_CheckState(res); + } + if (_v) { + return _wrap_ibytes_insert__SWIG_1(self, argc, argv); + } + } + } + } + } + +fail: + SWIG_Python_RaiseOrModifyTypeError("Wrong number or type of arguments for overloaded function 'ibytes_insert'.\n" + " Possible C/C++ prototypes are:\n" + " std::vector< int8_t >::insert(std::vector< signed char >::iterator,std::vector< signed char >::value_type const &)\n" + " std::vector< int8_t >::insert(std::vector< signed char >::iterator,std::vector< signed char >::size_type,std::vector< signed char >::value_type const &)\n"); + return 0; +} + + +SWIGINTERN PyObject *_wrap_ibytes_reserve(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< int8_t > *arg1 = (std::vector< int8_t > *) 0 ; + std::vector< signed char >::size_type arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + size_t val2 ; + int ecode2 = 0 ; + PyObject *swig_obj[2] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "ibytes_reserve", 2, 2, swig_obj)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_int8_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ibytes_reserve" "', argument " "1"" of type '" "std::vector< int8_t > *""'"); + } + arg1 = reinterpret_cast< std::vector< int8_t > * >(argp1); + ecode2 = SWIG_AsVal_size_t(swig_obj[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ibytes_reserve" "', argument " "2"" of type '" "std::vector< signed char >::size_type""'"); + } + arg2 = static_cast< std::vector< signed char >::size_type >(val2); + (arg1)->reserve(arg2); + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ibytes_capacity(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< int8_t > *arg1 = (std::vector< int8_t > *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + std::vector< signed char >::size_type result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_int8_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ibytes_capacity" "', argument " "1"" of type '" "std::vector< int8_t > const *""'"); + } + arg1 = reinterpret_cast< std::vector< int8_t > * >(argp1); + result = ((std::vector< int8_t > const *)arg1)->capacity(); + resultobj = SWIG_From_size_t(static_cast< size_t >(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_delete_ibytes(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< int8_t > *arg1 = (std::vector< int8_t > *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_int8_t_t, SWIG_POINTER_DISOWN | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_ibytes" "', argument " "1"" of type '" "std::vector< int8_t > *""'"); + } + arg1 = reinterpret_cast< std::vector< int8_t > * >(argp1); + { + try { + delete arg1; + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *ibytes_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *obj; + if (!SWIG_Python_UnpackTuple(args, "swigregister", 1, 1, &obj)) return NULL; + SWIG_TypeNewClientData(SWIGTYPE_p_std__vectorT_int8_t_t, SWIG_NewClientData(obj)); + return SWIG_Py_Void(); +} + +SWIGINTERN PyObject *ibytes_swiginit(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + return SWIG_Python_InitShadowInstance(args); +} + +SWIGINTERN PyObject *_wrap_StringVec_iterator(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ; + PyObject **arg2 = (PyObject **) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + swig::SwigPyIterator *result = 0 ; + + arg2 = &swig_obj[0]; + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_std__string_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVec_iterator" "', argument " "1"" of type '" "std::vector< std::string > *""'"); + } + arg1 = reinterpret_cast< std::vector< std::string > * >(argp1); + result = (swig::SwigPyIterator *)std_vector_Sl_std_string_Sg__iterator(arg1,arg2); + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_swig__SwigPyIterator, SWIG_POINTER_OWN | 0 ); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_StringVec___nonzero__(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + bool result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_std__string_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVec___nonzero__" "', argument " "1"" of type '" "std::vector< std::string > const *""'"); + } + arg1 = reinterpret_cast< std::vector< std::string > * >(argp1); + result = (bool)std_vector_Sl_std_string_Sg____nonzero__((std::vector< std::string > const *)arg1); + resultobj = SWIG_From_bool(static_cast< bool >(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_StringVec___bool__(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + bool result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_std__string_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVec___bool__" "', argument " "1"" of type '" "std::vector< std::string > const *""'"); + } + arg1 = reinterpret_cast< std::vector< std::string > * >(argp1); + result = (bool)std_vector_Sl_std_string_Sg____bool__((std::vector< std::string > const *)arg1); + resultobj = SWIG_From_bool(static_cast< bool >(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_StringVec___len__(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + std::vector< std::string >::size_type result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_std__string_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVec___len__" "', argument " "1"" of type '" "std::vector< std::string > const *""'"); + } + arg1 = reinterpret_cast< std::vector< std::string > * >(argp1); + result = std_vector_Sl_std_string_Sg____len__((std::vector< std::string > const *)arg1); + resultobj = SWIG_From_size_t(static_cast< size_t >(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_StringVec___getslice__(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ; + std::vector< std::string >::difference_type arg2 ; + std::vector< std::string >::difference_type arg3 ; + void *argp1 = 0 ; + int res1 = 0 ; + ptrdiff_t val2 ; + int ecode2 = 0 ; + ptrdiff_t val3 ; + int ecode3 = 0 ; + PyObject *swig_obj[3] ; + std::vector< std::string,std::allocator< std::string > > *result = 0 ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "StringVec___getslice__", 3, 3, swig_obj)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_std__string_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVec___getslice__" "', argument " "1"" of type '" "std::vector< std::string > *""'"); + } + arg1 = reinterpret_cast< std::vector< std::string > * >(argp1); + ecode2 = SWIG_AsVal_ptrdiff_t(swig_obj[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "StringVec___getslice__" "', argument " "2"" of type '" "std::vector< std::string >::difference_type""'"); + } + arg2 = static_cast< std::vector< std::string >::difference_type >(val2); + ecode3 = SWIG_AsVal_ptrdiff_t(swig_obj[2], &val3); + if (!SWIG_IsOK(ecode3)) { + SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "StringVec___getslice__" "', argument " "3"" of type '" "std::vector< std::string >::difference_type""'"); + } + arg3 = static_cast< std::vector< std::string >::difference_type >(val3); + try { + result = (std::vector< std::string,std::allocator< std::string > > *)std_vector_Sl_std_string_Sg____getslice__(arg1,SWIG_STD_MOVE(arg2),SWIG_STD_MOVE(arg3)); + } catch(std::out_of_range &_e) { + SWIG_exception_fail(SWIG_IndexError, (&_e)->what()); + } catch(std::invalid_argument &_e) { + SWIG_exception_fail(SWIG_ValueError, (&_e)->what()); + } + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorT_std__string_t, SWIG_POINTER_OWN | 0 ); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_StringVec___setslice____SWIG_0(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ; + std::vector< std::string >::difference_type arg2 ; + std::vector< std::string >::difference_type arg3 ; + void *argp1 = 0 ; + int res1 = 0 ; + ptrdiff_t val2 ; + int ecode2 = 0 ; + ptrdiff_t val3 ; + int ecode3 = 0 ; + + (void)self; + if ((nobjs < 3) || (nobjs > 3)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_std__string_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVec___setslice__" "', argument " "1"" of type '" "std::vector< std::string > *""'"); + } + arg1 = reinterpret_cast< std::vector< std::string > * >(argp1); + ecode2 = SWIG_AsVal_ptrdiff_t(swig_obj[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "StringVec___setslice__" "', argument " "2"" of type '" "std::vector< std::string >::difference_type""'"); + } + arg2 = static_cast< std::vector< std::string >::difference_type >(val2); + ecode3 = SWIG_AsVal_ptrdiff_t(swig_obj[2], &val3); + if (!SWIG_IsOK(ecode3)) { + SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "StringVec___setslice__" "', argument " "3"" of type '" "std::vector< std::string >::difference_type""'"); + } + arg3 = static_cast< std::vector< std::string >::difference_type >(val3); + try { + std_vector_Sl_std_string_Sg____setslice____SWIG_0(arg1,SWIG_STD_MOVE(arg2),SWIG_STD_MOVE(arg3)); + } catch(std::out_of_range &_e) { + SWIG_exception_fail(SWIG_IndexError, (&_e)->what()); + } catch(std::invalid_argument &_e) { + SWIG_exception_fail(SWIG_ValueError, (&_e)->what()); + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_StringVec___setslice____SWIG_1(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ; + std::vector< std::string >::difference_type arg2 ; + std::vector< std::string >::difference_type arg3 ; + std::vector< std::string,std::allocator< std::string > > *arg4 = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + ptrdiff_t val2 ; + int ecode2 = 0 ; + ptrdiff_t val3 ; + int ecode3 = 0 ; + int res4 = SWIG_OLDOBJ ; + + (void)self; + if ((nobjs < 4) || (nobjs > 4)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_std__string_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVec___setslice__" "', argument " "1"" of type '" "std::vector< std::string > *""'"); + } + arg1 = reinterpret_cast< std::vector< std::string > * >(argp1); + ecode2 = SWIG_AsVal_ptrdiff_t(swig_obj[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "StringVec___setslice__" "', argument " "2"" of type '" "std::vector< std::string >::difference_type""'"); + } + arg2 = static_cast< std::vector< std::string >::difference_type >(val2); + ecode3 = SWIG_AsVal_ptrdiff_t(swig_obj[2], &val3); + if (!SWIG_IsOK(ecode3)) { + SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "StringVec___setslice__" "', argument " "3"" of type '" "std::vector< std::string >::difference_type""'"); + } + arg3 = static_cast< std::vector< std::string >::difference_type >(val3); + { + std::vector< std::string,std::allocator< std::string > > *ptr = (std::vector< std::string,std::allocator< std::string > > *)0; + res4 = swig::asptr(swig_obj[3], &ptr); + if (!SWIG_IsOK(res4)) { + SWIG_exception_fail(SWIG_ArgError(res4), "in method '" "StringVec___setslice__" "', argument " "4"" of type '" "std::vector< std::string,std::allocator< std::string > > const &""'"); + } + if (!ptr) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "StringVec___setslice__" "', argument " "4"" of type '" "std::vector< std::string,std::allocator< std::string > > const &""'"); + } + arg4 = ptr; + } + try { + std_vector_Sl_std_string_Sg____setslice____SWIG_1(arg1,SWIG_STD_MOVE(arg2),SWIG_STD_MOVE(arg3),(std::vector< std::string,std::allocator< std::string > > const &)*arg4); + } catch(std::out_of_range &_e) { + SWIG_exception_fail(SWIG_IndexError, (&_e)->what()); + } catch(std::invalid_argument &_e) { + SWIG_exception_fail(SWIG_ValueError, (&_e)->what()); + } + resultobj = SWIG_Py_Void(); + if (SWIG_IsNewObj(res4)) delete arg4; + return resultobj; +fail: + if (SWIG_IsNewObj(res4)) delete arg4; + return NULL; +} + + +SWIGINTERN PyObject *_wrap_StringVec___setslice__(PyObject *self, PyObject *args) { + Py_ssize_t argc; + PyObject *argv[5] = { + 0 + }; + + if (!(argc = SWIG_Python_UnpackTuple(args, "StringVec___setslice__", 0, 4, argv))) SWIG_fail; + --argc; + if (argc == 3) { + int _v = 0; + int res = swig::asptr(argv[0], (std::vector< std::string,std::allocator< std::string > >**)(0)); + _v = SWIG_CheckState(res); + if (_v) { + { + int res = SWIG_AsVal_ptrdiff_t(argv[1], NULL); + _v = SWIG_CheckState(res); + } + if (_v) { + { + int res = SWIG_AsVal_ptrdiff_t(argv[2], NULL); + _v = SWIG_CheckState(res); + } + if (_v) { + return _wrap_StringVec___setslice____SWIG_0(self, argc, argv); + } + } + } + } + if (argc == 4) { + int _v = 0; + int res = swig::asptr(argv[0], (std::vector< std::string,std::allocator< std::string > >**)(0)); + _v = SWIG_CheckState(res); + if (_v) { + { + int res = SWIG_AsVal_ptrdiff_t(argv[1], NULL); + _v = SWIG_CheckState(res); + } + if (_v) { + { + int res = SWIG_AsVal_ptrdiff_t(argv[2], NULL); + _v = SWIG_CheckState(res); + } + if (_v) { + int res = swig::asptr(argv[3], (std::vector< std::string,std::allocator< std::string > >**)(0)); + _v = SWIG_CheckState(res); + if (_v) { + return _wrap_StringVec___setslice____SWIG_1(self, argc, argv); + } + } + } + } + } + +fail: + SWIG_Python_RaiseOrModifyTypeError("Wrong number or type of arguments for overloaded function 'StringVec___setslice__'.\n" + " Possible C/C++ prototypes are:\n" + " std::vector< std::string >::__setslice__(std::vector< std::string >::difference_type,std::vector< std::string >::difference_type)\n" + " std::vector< std::string >::__setslice__(std::vector< std::string >::difference_type,std::vector< std::string >::difference_type,std::vector< std::string,std::allocator< std::string > > const &)\n"); + return 0; +} + + +SWIGINTERN PyObject *_wrap_StringVec___delslice__(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ; + std::vector< std::string >::difference_type arg2 ; + std::vector< std::string >::difference_type arg3 ; + void *argp1 = 0 ; + int res1 = 0 ; + ptrdiff_t val2 ; + int ecode2 = 0 ; + ptrdiff_t val3 ; + int ecode3 = 0 ; + PyObject *swig_obj[3] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "StringVec___delslice__", 3, 3, swig_obj)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_std__string_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVec___delslice__" "', argument " "1"" of type '" "std::vector< std::string > *""'"); + } + arg1 = reinterpret_cast< std::vector< std::string > * >(argp1); + ecode2 = SWIG_AsVal_ptrdiff_t(swig_obj[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "StringVec___delslice__" "', argument " "2"" of type '" "std::vector< std::string >::difference_type""'"); + } + arg2 = static_cast< std::vector< std::string >::difference_type >(val2); + ecode3 = SWIG_AsVal_ptrdiff_t(swig_obj[2], &val3); + if (!SWIG_IsOK(ecode3)) { + SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "StringVec___delslice__" "', argument " "3"" of type '" "std::vector< std::string >::difference_type""'"); + } + arg3 = static_cast< std::vector< std::string >::difference_type >(val3); + try { + std_vector_Sl_std_string_Sg____delslice__(arg1,SWIG_STD_MOVE(arg2),SWIG_STD_MOVE(arg3)); + } catch(std::out_of_range &_e) { + SWIG_exception_fail(SWIG_IndexError, (&_e)->what()); + } catch(std::invalid_argument &_e) { + SWIG_exception_fail(SWIG_ValueError, (&_e)->what()); + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_StringVec___delitem____SWIG_0(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ; + std::vector< std::string >::difference_type arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + ptrdiff_t val2 ; + int ecode2 = 0 ; + + (void)self; + if ((nobjs < 2) || (nobjs > 2)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_std__string_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVec___delitem__" "', argument " "1"" of type '" "std::vector< std::string > *""'"); + } + arg1 = reinterpret_cast< std::vector< std::string > * >(argp1); + ecode2 = SWIG_AsVal_ptrdiff_t(swig_obj[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "StringVec___delitem__" "', argument " "2"" of type '" "std::vector< std::string >::difference_type""'"); + } + arg2 = static_cast< std::vector< std::string >::difference_type >(val2); + try { + std_vector_Sl_std_string_Sg____delitem____SWIG_0(arg1,SWIG_STD_MOVE(arg2)); + } catch(std::out_of_range &_e) { + SWIG_exception_fail(SWIG_IndexError, (&_e)->what()); + } catch(std::invalid_argument &_e) { + SWIG_exception_fail(SWIG_ValueError, (&_e)->what()); + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_StringVec___getitem____SWIG_0(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ; + SWIGPY_SLICEOBJECT *arg2 = (SWIGPY_SLICEOBJECT *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::vector< std::string,std::allocator< std::string > > *result = 0 ; + + (void)self; + if ((nobjs < 2) || (nobjs > 2)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_std__string_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVec___getitem__" "', argument " "1"" of type '" "std::vector< std::string > *""'"); + } + arg1 = reinterpret_cast< std::vector< std::string > * >(argp1); + { + if (!PySlice_Check(swig_obj[1])) { + SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "StringVec___getitem__" "', argument " "2"" of type '" "SWIGPY_SLICEOBJECT *""'"); + } + arg2 = (SWIGPY_SLICEOBJECT *) swig_obj[1]; + } + try { + result = (std::vector< std::string,std::allocator< std::string > > *)std_vector_Sl_std_string_Sg____getitem____SWIG_0(arg1,arg2); + } catch(std::out_of_range &_e) { + SWIG_exception_fail(SWIG_IndexError, (&_e)->what()); + } catch(std::invalid_argument &_e) { + SWIG_exception_fail(SWIG_ValueError, (&_e)->what()); + } + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorT_std__string_t, SWIG_POINTER_OWN | 0 ); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_StringVec___setitem____SWIG_0(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ; + SWIGPY_SLICEOBJECT *arg2 = (SWIGPY_SLICEOBJECT *) 0 ; + std::vector< std::string,std::allocator< std::string > > *arg3 = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + int res3 = SWIG_OLDOBJ ; + + (void)self; + if ((nobjs < 3) || (nobjs > 3)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_std__string_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVec___setitem__" "', argument " "1"" of type '" "std::vector< std::string > *""'"); + } + arg1 = reinterpret_cast< std::vector< std::string > * >(argp1); + { + if (!PySlice_Check(swig_obj[1])) { + SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "StringVec___setitem__" "', argument " "2"" of type '" "SWIGPY_SLICEOBJECT *""'"); + } + arg2 = (SWIGPY_SLICEOBJECT *) swig_obj[1]; + } + { + std::vector< std::string,std::allocator< std::string > > *ptr = (std::vector< std::string,std::allocator< std::string > > *)0; + res3 = swig::asptr(swig_obj[2], &ptr); + if (!SWIG_IsOK(res3)) { + SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "StringVec___setitem__" "', argument " "3"" of type '" "std::vector< std::string,std::allocator< std::string > > const &""'"); + } + if (!ptr) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "StringVec___setitem__" "', argument " "3"" of type '" "std::vector< std::string,std::allocator< std::string > > const &""'"); + } + arg3 = ptr; + } + try { + std_vector_Sl_std_string_Sg____setitem____SWIG_0(arg1,arg2,(std::vector< std::string,std::allocator< std::string > > const &)*arg3); + } catch(std::out_of_range &_e) { + SWIG_exception_fail(SWIG_IndexError, (&_e)->what()); + } catch(std::invalid_argument &_e) { + SWIG_exception_fail(SWIG_ValueError, (&_e)->what()); + } + resultobj = SWIG_Py_Void(); + if (SWIG_IsNewObj(res3)) delete arg3; + return resultobj; +fail: + if (SWIG_IsNewObj(res3)) delete arg3; + return NULL; +} + + +SWIGINTERN PyObject *_wrap_StringVec___setitem____SWIG_1(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ; + SWIGPY_SLICEOBJECT *arg2 = (SWIGPY_SLICEOBJECT *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + + (void)self; + if ((nobjs < 2) || (nobjs > 2)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_std__string_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVec___setitem__" "', argument " "1"" of type '" "std::vector< std::string > *""'"); + } + arg1 = reinterpret_cast< std::vector< std::string > * >(argp1); + { + if (!PySlice_Check(swig_obj[1])) { + SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "StringVec___setitem__" "', argument " "2"" of type '" "SWIGPY_SLICEOBJECT *""'"); + } + arg2 = (SWIGPY_SLICEOBJECT *) swig_obj[1]; + } + try { + std_vector_Sl_std_string_Sg____setitem____SWIG_1(arg1,arg2); + } catch(std::out_of_range &_e) { + SWIG_exception_fail(SWIG_IndexError, (&_e)->what()); + } catch(std::invalid_argument &_e) { + SWIG_exception_fail(SWIG_ValueError, (&_e)->what()); + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_StringVec___delitem____SWIG_1(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ; + SWIGPY_SLICEOBJECT *arg2 = (SWIGPY_SLICEOBJECT *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + + (void)self; + if ((nobjs < 2) || (nobjs > 2)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_std__string_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVec___delitem__" "', argument " "1"" of type '" "std::vector< std::string > *""'"); + } + arg1 = reinterpret_cast< std::vector< std::string > * >(argp1); + { + if (!PySlice_Check(swig_obj[1])) { + SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "StringVec___delitem__" "', argument " "2"" of type '" "SWIGPY_SLICEOBJECT *""'"); + } + arg2 = (SWIGPY_SLICEOBJECT *) swig_obj[1]; + } + try { + std_vector_Sl_std_string_Sg____delitem____SWIG_1(arg1,arg2); + } catch(std::out_of_range &_e) { + SWIG_exception_fail(SWIG_IndexError, (&_e)->what()); + } catch(std::invalid_argument &_e) { + SWIG_exception_fail(SWIG_ValueError, (&_e)->what()); + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_StringVec___delitem__(PyObject *self, PyObject *args) { + Py_ssize_t argc; + PyObject *argv[3] = { + 0 + }; + + if (!(argc = SWIG_Python_UnpackTuple(args, "StringVec___delitem__", 0, 2, argv))) SWIG_fail; + --argc; + if (argc == 2) { + int _v = 0; + int res = swig::asptr(argv[0], (std::vector< std::string,std::allocator< std::string > >**)(0)); + _v = SWIG_CheckState(res); + if (_v) { + { + _v = PySlice_Check(argv[1]); + } + if (_v) { + return _wrap_StringVec___delitem____SWIG_1(self, argc, argv); + } + } + } + if (argc == 2) { + int _v = 0; + int res = swig::asptr(argv[0], (std::vector< std::string,std::allocator< std::string > >**)(0)); + _v = SWIG_CheckState(res); + if (_v) { + { + int res = SWIG_AsVal_ptrdiff_t(argv[1], NULL); + _v = SWIG_CheckState(res); + } + if (_v) { + return _wrap_StringVec___delitem____SWIG_0(self, argc, argv); + } + } + } + +fail: + SWIG_Python_RaiseOrModifyTypeError("Wrong number or type of arguments for overloaded function 'StringVec___delitem__'.\n" + " Possible C/C++ prototypes are:\n" + " std::vector< std::string >::__delitem__(std::vector< std::string >::difference_type)\n" + " std::vector< std::string >::__delitem__(SWIGPY_SLICEOBJECT *)\n"); + return 0; +} + + +SWIGINTERN PyObject *_wrap_StringVec___getitem____SWIG_1(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ; + std::vector< std::string >::difference_type arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + ptrdiff_t val2 ; + int ecode2 = 0 ; + std::vector< std::string >::value_type *result = 0 ; + + (void)self; + if ((nobjs < 2) || (nobjs > 2)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_std__string_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVec___getitem__" "', argument " "1"" of type '" "std::vector< std::string > const *""'"); + } + arg1 = reinterpret_cast< std::vector< std::string > * >(argp1); + ecode2 = SWIG_AsVal_ptrdiff_t(swig_obj[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "StringVec___getitem__" "', argument " "2"" of type '" "std::vector< std::string >::difference_type""'"); + } + arg2 = static_cast< std::vector< std::string >::difference_type >(val2); + try { + result = (std::vector< std::string >::value_type *) &std_vector_Sl_std_string_Sg____getitem____SWIG_1((std::vector< std::string > const *)arg1,SWIG_STD_MOVE(arg2)); + } catch(std::out_of_range &_e) { + SWIG_exception_fail(SWIG_IndexError, (&_e)->what()); + } + resultobj = SWIG_From_std_string(static_cast< std::string >(*result)); + (void)swig::container_owner::value_type>::category>::back_reference(resultobj, swig_obj[0]); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_StringVec___getitem__(PyObject *self, PyObject *args) { + Py_ssize_t argc; + PyObject *argv[3] = { + 0 + }; + + if (!(argc = SWIG_Python_UnpackTuple(args, "StringVec___getitem__", 0, 2, argv))) SWIG_fail; + --argc; + if (argc == 2) { + int _v = 0; + int res = swig::asptr(argv[0], (std::vector< std::string,std::allocator< std::string > >**)(0)); + _v = SWIG_CheckState(res); + if (_v) { + { + _v = PySlice_Check(argv[1]); + } + if (_v) { + return _wrap_StringVec___getitem____SWIG_0(self, argc, argv); + } + } + } + if (argc == 2) { + int _v = 0; + int res = swig::asptr(argv[0], (std::vector< std::string,std::allocator< std::string > >**)(0)); + _v = SWIG_CheckState(res); + if (_v) { + { + int res = SWIG_AsVal_ptrdiff_t(argv[1], NULL); + _v = SWIG_CheckState(res); + } + if (_v) { + return _wrap_StringVec___getitem____SWIG_1(self, argc, argv); + } + } + } + +fail: + SWIG_Python_RaiseOrModifyTypeError("Wrong number or type of arguments for overloaded function 'StringVec___getitem__'.\n" + " Possible C/C++ prototypes are:\n" + " std::vector< std::string >::__getitem__(SWIGPY_SLICEOBJECT *)\n" + " std::vector< std::string >::__getitem__(std::vector< std::string >::difference_type) const\n"); + return 0; +} + + +SWIGINTERN PyObject *_wrap_StringVec___setitem____SWIG_2(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ; + std::vector< std::string >::difference_type arg2 ; + std::vector< std::string >::value_type *arg3 = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + ptrdiff_t val2 ; + int ecode2 = 0 ; + int res3 = SWIG_OLDOBJ ; + + (void)self; + if ((nobjs < 3) || (nobjs > 3)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_std__string_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVec___setitem__" "', argument " "1"" of type '" "std::vector< std::string > *""'"); + } + arg1 = reinterpret_cast< std::vector< std::string > * >(argp1); + ecode2 = SWIG_AsVal_ptrdiff_t(swig_obj[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "StringVec___setitem__" "', argument " "2"" of type '" "std::vector< std::string >::difference_type""'"); + } + arg2 = static_cast< std::vector< std::string >::difference_type >(val2); + { + std::string *ptr = (std::string *)0; + res3 = SWIG_AsPtr_std_string(swig_obj[2], &ptr); + if (!SWIG_IsOK(res3)) { + SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "StringVec___setitem__" "', argument " "3"" of type '" "std::vector< std::string >::value_type const &""'"); + } + if (!ptr) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "StringVec___setitem__" "', argument " "3"" of type '" "std::vector< std::string >::value_type const &""'"); + } + arg3 = ptr; + } + try { + std_vector_Sl_std_string_Sg____setitem____SWIG_2(arg1,SWIG_STD_MOVE(arg2),(std::string const &)*arg3); + } catch(std::out_of_range &_e) { + SWIG_exception_fail(SWIG_IndexError, (&_e)->what()); + } + resultobj = SWIG_Py_Void(); + if (SWIG_IsNewObj(res3)) delete arg3; + return resultobj; +fail: + if (SWIG_IsNewObj(res3)) delete arg3; + return NULL; +} + + +SWIGINTERN PyObject *_wrap_StringVec___setitem__(PyObject *self, PyObject *args) { + Py_ssize_t argc; + PyObject *argv[4] = { + 0 + }; + + if (!(argc = SWIG_Python_UnpackTuple(args, "StringVec___setitem__", 0, 3, argv))) SWIG_fail; + --argc; + if (argc == 2) { + int _v = 0; + int res = swig::asptr(argv[0], (std::vector< std::string,std::allocator< std::string > >**)(0)); + _v = SWIG_CheckState(res); + if (_v) { + { + _v = PySlice_Check(argv[1]); + } + if (_v) { + return _wrap_StringVec___setitem____SWIG_1(self, argc, argv); + } + } + } + if (argc == 3) { + int _v = 0; + int res = swig::asptr(argv[0], (std::vector< std::string,std::allocator< std::string > >**)(0)); + _v = SWIG_CheckState(res); + if (_v) { + { + _v = PySlice_Check(argv[1]); + } + if (_v) { + int res = swig::asptr(argv[2], (std::vector< std::string,std::allocator< std::string > >**)(0)); + _v = SWIG_CheckState(res); + if (_v) { + return _wrap_StringVec___setitem____SWIG_0(self, argc, argv); + } + } + } + } + if (argc == 3) { + int _v = 0; + int res = swig::asptr(argv[0], (std::vector< std::string,std::allocator< std::string > >**)(0)); + _v = SWIG_CheckState(res); + if (_v) { + { + int res = SWIG_AsVal_ptrdiff_t(argv[1], NULL); + _v = SWIG_CheckState(res); + } + if (_v) { + int res = SWIG_AsPtr_std_string(argv[2], (std::string**)(0)); + _v = SWIG_CheckState(res); + if (_v) { + return _wrap_StringVec___setitem____SWIG_2(self, argc, argv); + } + } + } + } + +fail: + SWIG_Python_RaiseOrModifyTypeError("Wrong number or type of arguments for overloaded function 'StringVec___setitem__'.\n" + " Possible C/C++ prototypes are:\n" + " std::vector< std::string >::__setitem__(SWIGPY_SLICEOBJECT *,std::vector< std::string,std::allocator< std::string > > const &)\n" + " std::vector< std::string >::__setitem__(SWIGPY_SLICEOBJECT *)\n" + " std::vector< std::string >::__setitem__(std::vector< std::string >::difference_type,std::vector< std::string >::value_type const &)\n"); + return 0; +} + + +SWIGINTERN PyObject *_wrap_StringVec_pop(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + std::vector< std::string >::value_type result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_std__string_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVec_pop" "', argument " "1"" of type '" "std::vector< std::string > *""'"); + } + arg1 = reinterpret_cast< std::vector< std::string > * >(argp1); + try { + result = std_vector_Sl_std_string_Sg__pop(arg1); + } catch(std::out_of_range &_e) { + SWIG_exception_fail(SWIG_IndexError, (&_e)->what()); + } + resultobj = SWIG_From_std_string(static_cast< std::string >(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_StringVec_append(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ; + std::vector< std::string >::value_type *arg2 = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + int res2 = SWIG_OLDOBJ ; + PyObject *swig_obj[2] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "StringVec_append", 2, 2, swig_obj)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_std__string_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVec_append" "', argument " "1"" of type '" "std::vector< std::string > *""'"); + } + arg1 = reinterpret_cast< std::vector< std::string > * >(argp1); + { + std::string *ptr = (std::string *)0; + res2 = SWIG_AsPtr_std_string(swig_obj[1], &ptr); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "StringVec_append" "', argument " "2"" of type '" "std::vector< std::string >::value_type const &""'"); + } + if (!ptr) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "StringVec_append" "', argument " "2"" of type '" "std::vector< std::string >::value_type const &""'"); + } + arg2 = ptr; + } + std_vector_Sl_std_string_Sg__append(arg1,(std::string const &)*arg2); + resultobj = SWIG_Py_Void(); + if (SWIG_IsNewObj(res2)) delete arg2; + return resultobj; +fail: + if (SWIG_IsNewObj(res2)) delete arg2; + return NULL; +} + + +SWIGINTERN PyObject *_wrap_new_StringVec__SWIG_0(PyObject *self, Py_ssize_t nobjs, PyObject **SWIGUNUSEDPARM(swig_obj)) { + PyObject *resultobj = 0; + std::vector< std::string > *result = 0 ; + + (void)self; + if ((nobjs < 0) || (nobjs > 0)) SWIG_fail; + result = (std::vector< std::string > *)new std::vector< std::string >(); + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorT_std__string_t, SWIG_POINTER_NEW | 0 ); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_new_StringVec__SWIG_1(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + std::vector< std::string > *arg1 = 0 ; + int res1 = SWIG_OLDOBJ ; + std::vector< std::string > *result = 0 ; + + (void)self; + if ((nobjs < 1) || (nobjs > 1)) SWIG_fail; + { + std::vector< std::string,std::allocator< std::string > > *ptr = (std::vector< std::string,std::allocator< std::string > > *)0; + res1 = swig::asptr(swig_obj[0], &ptr); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "new_StringVec" "', argument " "1"" of type '" "std::vector< std::string > const &""'"); + } + if (!ptr) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_StringVec" "', argument " "1"" of type '" "std::vector< std::string > const &""'"); + } + arg1 = ptr; + } + result = (std::vector< std::string > *)new std::vector< std::string >((std::vector< std::string > const &)*arg1); + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorT_std__string_t, SWIG_POINTER_NEW | 0 ); + if (SWIG_IsNewObj(res1)) delete arg1; + return resultobj; +fail: + if (SWIG_IsNewObj(res1)) delete arg1; + return NULL; +} + + +SWIGINTERN PyObject *_wrap_StringVec_empty(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + bool result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_std__string_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVec_empty" "', argument " "1"" of type '" "std::vector< std::string > const *""'"); + } + arg1 = reinterpret_cast< std::vector< std::string > * >(argp1); + result = (bool)((std::vector< std::string > const *)arg1)->empty(); + resultobj = SWIG_From_bool(static_cast< bool >(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_StringVec_size(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + std::vector< std::string >::size_type result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_std__string_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVec_size" "', argument " "1"" of type '" "std::vector< std::string > const *""'"); + } + arg1 = reinterpret_cast< std::vector< std::string > * >(argp1); + result = ((std::vector< std::string > const *)arg1)->size(); + resultobj = SWIG_From_size_t(static_cast< size_t >(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_StringVec_swap(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ; + std::vector< std::string > *arg2 = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + void *argp2 = 0 ; + int res2 = 0 ; + PyObject *swig_obj[2] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "StringVec_swap", 2, 2, swig_obj)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_std__string_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVec_swap" "', argument " "1"" of type '" "std::vector< std::string > *""'"); + } + arg1 = reinterpret_cast< std::vector< std::string > * >(argp1); + res2 = SWIG_ConvertPtr(swig_obj[1], &argp2, SWIGTYPE_p_std__vectorT_std__string_t, 0 ); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "StringVec_swap" "', argument " "2"" of type '" "std::vector< std::string > &""'"); + } + if (!argp2) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "StringVec_swap" "', argument " "2"" of type '" "std::vector< std::string > &""'"); + } + arg2 = reinterpret_cast< std::vector< std::string > * >(argp2); + (arg1)->swap(*arg2); + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_StringVec_begin(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + std::vector< std::string >::iterator result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_std__string_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVec_begin" "', argument " "1"" of type '" "std::vector< std::string > *""'"); + } + arg1 = reinterpret_cast< std::vector< std::string > * >(argp1); + result = (arg1)->begin(); + resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector< std::string >::iterator & >(result)), + swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_StringVec_end(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + std::vector< std::string >::iterator result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_std__string_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVec_end" "', argument " "1"" of type '" "std::vector< std::string > *""'"); + } + arg1 = reinterpret_cast< std::vector< std::string > * >(argp1); + result = (arg1)->end(); + resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector< std::string >::iterator & >(result)), + swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_StringVec_rbegin(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + std::vector< std::string >::reverse_iterator result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_std__string_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVec_rbegin" "', argument " "1"" of type '" "std::vector< std::string > *""'"); + } + arg1 = reinterpret_cast< std::vector< std::string > * >(argp1); + result = (arg1)->rbegin(); + resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector< std::string >::reverse_iterator & >(result)), + swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_StringVec_rend(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + std::vector< std::string >::reverse_iterator result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_std__string_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVec_rend" "', argument " "1"" of type '" "std::vector< std::string > *""'"); + } + arg1 = reinterpret_cast< std::vector< std::string > * >(argp1); + result = (arg1)->rend(); + resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector< std::string >::reverse_iterator & >(result)), + swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_StringVec_clear(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_std__string_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVec_clear" "', argument " "1"" of type '" "std::vector< std::string > *""'"); + } + arg1 = reinterpret_cast< std::vector< std::string > * >(argp1); + (arg1)->clear(); + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_StringVec_get_allocator(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + SwigValueWrapper< std::allocator< std::string > > result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_std__string_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVec_get_allocator" "', argument " "1"" of type '" "std::vector< std::string > const *""'"); + } + arg1 = reinterpret_cast< std::vector< std::string > * >(argp1); + result = ((std::vector< std::string > const *)arg1)->get_allocator(); + resultobj = SWIG_NewPointerObj((new std::vector< std::string >::allocator_type(result)), SWIGTYPE_p_std__allocatorT_std__string_t, SWIG_POINTER_OWN | 0 ); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_new_StringVec__SWIG_2(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + std::vector< std::string >::size_type arg1 ; + size_t val1 ; + int ecode1 = 0 ; + std::vector< std::string > *result = 0 ; + + (void)self; + if ((nobjs < 1) || (nobjs > 1)) SWIG_fail; + ecode1 = SWIG_AsVal_size_t(swig_obj[0], &val1); + if (!SWIG_IsOK(ecode1)) { + SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "new_StringVec" "', argument " "1"" of type '" "std::vector< std::string >::size_type""'"); + } + arg1 = static_cast< std::vector< std::string >::size_type >(val1); + result = (std::vector< std::string > *)new std::vector< std::string >(arg1); + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorT_std__string_t, SWIG_POINTER_NEW | 0 ); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_StringVec_pop_back(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_std__string_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVec_pop_back" "', argument " "1"" of type '" "std::vector< std::string > *""'"); + } + arg1 = reinterpret_cast< std::vector< std::string > * >(argp1); + (arg1)->pop_back(); + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_StringVec_resize__SWIG_0(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ; + std::vector< std::string >::size_type arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + size_t val2 ; + int ecode2 = 0 ; + + (void)self; + if ((nobjs < 2) || (nobjs > 2)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_std__string_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVec_resize" "', argument " "1"" of type '" "std::vector< std::string > *""'"); + } + arg1 = reinterpret_cast< std::vector< std::string > * >(argp1); + ecode2 = SWIG_AsVal_size_t(swig_obj[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "StringVec_resize" "', argument " "2"" of type '" "std::vector< std::string >::size_type""'"); + } + arg2 = static_cast< std::vector< std::string >::size_type >(val2); + (arg1)->resize(arg2); + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_StringVec_erase__SWIG_0(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ; + std::vector< std::string >::iterator arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + swig::SwigPyIterator *iter2 = 0 ; + int res2 ; + std::vector< std::string >::iterator result; + + (void)self; + if ((nobjs < 2) || (nobjs > 2)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_std__string_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVec_erase" "', argument " "1"" of type '" "std::vector< std::string > *""'"); + } + arg1 = reinterpret_cast< std::vector< std::string > * >(argp1); + res2 = SWIG_ConvertPtr(swig_obj[1], SWIG_as_voidptrptr(&iter2), swig::SwigPyIterator::descriptor(), 0); + if (!SWIG_IsOK(res2) || !iter2) { + SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "StringVec_erase" "', argument " "2"" of type '" "std::vector< std::string >::iterator""'"); + } else { + swig::SwigPyIterator_T::iterator > *iter_t = dynamic_cast::iterator > *>(iter2); + if (iter_t) { + arg2 = iter_t->get_current(); + } else { + SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "StringVec_erase" "', argument " "2"" of type '" "std::vector< std::string >::iterator""'"); + } + } + result = std_vector_Sl_std_string_Sg__erase__SWIG_0(arg1,SWIG_STD_MOVE(arg2)); + resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector< std::string >::iterator & >(result)), + swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_StringVec_erase__SWIG_1(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ; + std::vector< std::string >::iterator arg2 ; + std::vector< std::string >::iterator arg3 ; + void *argp1 = 0 ; + int res1 = 0 ; + swig::SwigPyIterator *iter2 = 0 ; + int res2 ; + swig::SwigPyIterator *iter3 = 0 ; + int res3 ; + std::vector< std::string >::iterator result; + + (void)self; + if ((nobjs < 3) || (nobjs > 3)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_std__string_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVec_erase" "', argument " "1"" of type '" "std::vector< std::string > *""'"); + } + arg1 = reinterpret_cast< std::vector< std::string > * >(argp1); + res2 = SWIG_ConvertPtr(swig_obj[1], SWIG_as_voidptrptr(&iter2), swig::SwigPyIterator::descriptor(), 0); + if (!SWIG_IsOK(res2) || !iter2) { + SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "StringVec_erase" "', argument " "2"" of type '" "std::vector< std::string >::iterator""'"); + } else { + swig::SwigPyIterator_T::iterator > *iter_t = dynamic_cast::iterator > *>(iter2); + if (iter_t) { + arg2 = iter_t->get_current(); + } else { + SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "StringVec_erase" "', argument " "2"" of type '" "std::vector< std::string >::iterator""'"); + } + } + res3 = SWIG_ConvertPtr(swig_obj[2], SWIG_as_voidptrptr(&iter3), swig::SwigPyIterator::descriptor(), 0); + if (!SWIG_IsOK(res3) || !iter3) { + SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "StringVec_erase" "', argument " "3"" of type '" "std::vector< std::string >::iterator""'"); + } else { + swig::SwigPyIterator_T::iterator > *iter_t = dynamic_cast::iterator > *>(iter3); + if (iter_t) { + arg3 = iter_t->get_current(); + } else { + SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "StringVec_erase" "', argument " "3"" of type '" "std::vector< std::string >::iterator""'"); + } + } + result = std_vector_Sl_std_string_Sg__erase__SWIG_1(arg1,SWIG_STD_MOVE(arg2),SWIG_STD_MOVE(arg3)); + resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector< std::string >::iterator & >(result)), + swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_StringVec_erase(PyObject *self, PyObject *args) { + Py_ssize_t argc; + PyObject *argv[4] = { + 0 + }; + + if (!(argc = SWIG_Python_UnpackTuple(args, "StringVec_erase", 0, 3, argv))) SWIG_fail; + --argc; + if (argc == 2) { + int _v = 0; + int res = swig::asptr(argv[0], (std::vector< std::string,std::allocator< std::string > >**)(0)); + _v = SWIG_CheckState(res); + if (_v) { + swig::SwigPyIterator *iter = 0; + int res = SWIG_ConvertPtr(argv[1], SWIG_as_voidptrptr(&iter), swig::SwigPyIterator::descriptor(), 0); + _v = (SWIG_IsOK(res) && iter && (dynamic_cast::iterator > *>(iter) != 0)); + if (_v) { + return _wrap_StringVec_erase__SWIG_0(self, argc, argv); + } + } + } + if (argc == 3) { + int _v = 0; + int res = swig::asptr(argv[0], (std::vector< std::string,std::allocator< std::string > >**)(0)); + _v = SWIG_CheckState(res); + if (_v) { + swig::SwigPyIterator *iter = 0; + int res = SWIG_ConvertPtr(argv[1], SWIG_as_voidptrptr(&iter), swig::SwigPyIterator::descriptor(), 0); + _v = (SWIG_IsOK(res) && iter && (dynamic_cast::iterator > *>(iter) != 0)); + if (_v) { + swig::SwigPyIterator *iter = 0; + int res = SWIG_ConvertPtr(argv[2], SWIG_as_voidptrptr(&iter), swig::SwigPyIterator::descriptor(), 0); + _v = (SWIG_IsOK(res) && iter && (dynamic_cast::iterator > *>(iter) != 0)); + if (_v) { + return _wrap_StringVec_erase__SWIG_1(self, argc, argv); + } + } + } + } + +fail: + SWIG_Python_RaiseOrModifyTypeError("Wrong number or type of arguments for overloaded function 'StringVec_erase'.\n" + " Possible C/C++ prototypes are:\n" + " std::vector< std::string >::erase(std::vector< std::string >::iterator)\n" + " std::vector< std::string >::erase(std::vector< std::string >::iterator,std::vector< std::string >::iterator)\n"); + return 0; +} + + +SWIGINTERN PyObject *_wrap_new_StringVec__SWIG_3(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + std::vector< std::string >::size_type arg1 ; + std::vector< std::string >::value_type *arg2 = 0 ; + size_t val1 ; + int ecode1 = 0 ; + int res2 = SWIG_OLDOBJ ; + std::vector< std::string > *result = 0 ; + + (void)self; + if ((nobjs < 2) || (nobjs > 2)) SWIG_fail; + ecode1 = SWIG_AsVal_size_t(swig_obj[0], &val1); + if (!SWIG_IsOK(ecode1)) { + SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "new_StringVec" "', argument " "1"" of type '" "std::vector< std::string >::size_type""'"); + } + arg1 = static_cast< std::vector< std::string >::size_type >(val1); + { + std::string *ptr = (std::string *)0; + res2 = SWIG_AsPtr_std_string(swig_obj[1], &ptr); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "new_StringVec" "', argument " "2"" of type '" "std::vector< std::string >::value_type const &""'"); + } + if (!ptr) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_StringVec" "', argument " "2"" of type '" "std::vector< std::string >::value_type const &""'"); + } + arg2 = ptr; + } + result = (std::vector< std::string > *)new std::vector< std::string >(arg1,(std::vector< std::string >::value_type const &)*arg2); + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorT_std__string_t, SWIG_POINTER_NEW | 0 ); + if (SWIG_IsNewObj(res2)) delete arg2; + return resultobj; +fail: + if (SWIG_IsNewObj(res2)) delete arg2; + return NULL; +} + + +SWIGINTERN PyObject *_wrap_new_StringVec(PyObject *self, PyObject *args) { + Py_ssize_t argc; + PyObject *argv[3] = { + 0 + }; + + if (!(argc = SWIG_Python_UnpackTuple(args, "new_StringVec", 0, 2, argv))) SWIG_fail; + --argc; + if (argc == 0) { + return _wrap_new_StringVec__SWIG_0(self, argc, argv); + } + if (argc == 1) { + int _v = 0; + { + int res = SWIG_AsVal_size_t(argv[0], NULL); + _v = SWIG_CheckState(res); + } + if (_v) { + return _wrap_new_StringVec__SWIG_2(self, argc, argv); + } + } + if (argc == 1) { + int _v = 0; + int res = swig::asptr(argv[0], (std::vector< std::string,std::allocator< std::string > >**)(0)); + _v = SWIG_CheckState(res); + if (_v) { + return _wrap_new_StringVec__SWIG_1(self, argc, argv); + } + } + if (argc == 2) { + int _v = 0; + { + int res = SWIG_AsVal_size_t(argv[0], NULL); + _v = SWIG_CheckState(res); + } + if (_v) { + int res = SWIG_AsPtr_std_string(argv[1], (std::string**)(0)); + _v = SWIG_CheckState(res); + if (_v) { + return _wrap_new_StringVec__SWIG_3(self, argc, argv); + } + } + } + +fail: + SWIG_Python_RaiseOrModifyTypeError("Wrong number or type of arguments for overloaded function 'new_StringVec'.\n" + " Possible C/C++ prototypes are:\n" + " std::vector< std::string >::vector()\n" + " std::vector< std::string >::vector(std::vector< std::string > const &)\n" + " std::vector< std::string >::vector(std::vector< std::string >::size_type)\n" + " std::vector< std::string >::vector(std::vector< std::string >::size_type,std::vector< std::string >::value_type const &)\n"); + return 0; +} + + +SWIGINTERN PyObject *_wrap_StringVec_push_back(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ; + std::vector< std::string >::value_type *arg2 = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + int res2 = SWIG_OLDOBJ ; + PyObject *swig_obj[2] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "StringVec_push_back", 2, 2, swig_obj)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_std__string_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVec_push_back" "', argument " "1"" of type '" "std::vector< std::string > *""'"); + } + arg1 = reinterpret_cast< std::vector< std::string > * >(argp1); + { + std::string *ptr = (std::string *)0; + res2 = SWIG_AsPtr_std_string(swig_obj[1], &ptr); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "StringVec_push_back" "', argument " "2"" of type '" "std::vector< std::string >::value_type const &""'"); + } + if (!ptr) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "StringVec_push_back" "', argument " "2"" of type '" "std::vector< std::string >::value_type const &""'"); + } + arg2 = ptr; + } + (arg1)->push_back((std::vector< std::string >::value_type const &)*arg2); + resultobj = SWIG_Py_Void(); + if (SWIG_IsNewObj(res2)) delete arg2; + return resultobj; +fail: + if (SWIG_IsNewObj(res2)) delete arg2; + return NULL; +} + + +SWIGINTERN PyObject *_wrap_StringVec_front(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + std::vector< std::string >::value_type *result = 0 ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_std__string_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVec_front" "', argument " "1"" of type '" "std::vector< std::string > const *""'"); + } + arg1 = reinterpret_cast< std::vector< std::string > * >(argp1); + result = (std::vector< std::string >::value_type *) &((std::vector< std::string > const *)arg1)->front(); + resultobj = SWIG_From_std_string(static_cast< std::string >(*result)); + (void)swig::container_owner::value_type>::category>::back_reference(resultobj, swig_obj[0]); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_StringVec_back(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + std::vector< std::string >::value_type *result = 0 ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_std__string_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVec_back" "', argument " "1"" of type '" "std::vector< std::string > const *""'"); + } + arg1 = reinterpret_cast< std::vector< std::string > * >(argp1); + result = (std::vector< std::string >::value_type *) &((std::vector< std::string > const *)arg1)->back(); + resultobj = SWIG_From_std_string(static_cast< std::string >(*result)); + (void)swig::container_owner::value_type>::category>::back_reference(resultobj, swig_obj[0]); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_StringVec_assign(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ; + std::vector< std::string >::size_type arg2 ; + std::vector< std::string >::value_type *arg3 = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + size_t val2 ; + int ecode2 = 0 ; + int res3 = SWIG_OLDOBJ ; + PyObject *swig_obj[3] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "StringVec_assign", 3, 3, swig_obj)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_std__string_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVec_assign" "', argument " "1"" of type '" "std::vector< std::string > *""'"); + } + arg1 = reinterpret_cast< std::vector< std::string > * >(argp1); + ecode2 = SWIG_AsVal_size_t(swig_obj[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "StringVec_assign" "', argument " "2"" of type '" "std::vector< std::string >::size_type""'"); + } + arg2 = static_cast< std::vector< std::string >::size_type >(val2); + { + std::string *ptr = (std::string *)0; + res3 = SWIG_AsPtr_std_string(swig_obj[2], &ptr); + if (!SWIG_IsOK(res3)) { + SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "StringVec_assign" "', argument " "3"" of type '" "std::vector< std::string >::value_type const &""'"); + } + if (!ptr) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "StringVec_assign" "', argument " "3"" of type '" "std::vector< std::string >::value_type const &""'"); + } + arg3 = ptr; + } + (arg1)->assign(arg2,(std::vector< std::string >::value_type const &)*arg3); + resultobj = SWIG_Py_Void(); + if (SWIG_IsNewObj(res3)) delete arg3; + return resultobj; +fail: + if (SWIG_IsNewObj(res3)) delete arg3; + return NULL; +} + + +SWIGINTERN PyObject *_wrap_StringVec_resize__SWIG_1(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ; + std::vector< std::string >::size_type arg2 ; + std::vector< std::string >::value_type *arg3 = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + size_t val2 ; + int ecode2 = 0 ; + int res3 = SWIG_OLDOBJ ; + + (void)self; + if ((nobjs < 3) || (nobjs > 3)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_std__string_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVec_resize" "', argument " "1"" of type '" "std::vector< std::string > *""'"); + } + arg1 = reinterpret_cast< std::vector< std::string > * >(argp1); + ecode2 = SWIG_AsVal_size_t(swig_obj[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "StringVec_resize" "', argument " "2"" of type '" "std::vector< std::string >::size_type""'"); + } + arg2 = static_cast< std::vector< std::string >::size_type >(val2); + { + std::string *ptr = (std::string *)0; + res3 = SWIG_AsPtr_std_string(swig_obj[2], &ptr); + if (!SWIG_IsOK(res3)) { + SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "StringVec_resize" "', argument " "3"" of type '" "std::vector< std::string >::value_type const &""'"); + } + if (!ptr) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "StringVec_resize" "', argument " "3"" of type '" "std::vector< std::string >::value_type const &""'"); + } + arg3 = ptr; + } + (arg1)->resize(arg2,(std::vector< std::string >::value_type const &)*arg3); + resultobj = SWIG_Py_Void(); + if (SWIG_IsNewObj(res3)) delete arg3; + return resultobj; +fail: + if (SWIG_IsNewObj(res3)) delete arg3; + return NULL; +} + + +SWIGINTERN PyObject *_wrap_StringVec_resize(PyObject *self, PyObject *args) { + Py_ssize_t argc; + PyObject *argv[4] = { + 0 + }; + + if (!(argc = SWIG_Python_UnpackTuple(args, "StringVec_resize", 0, 3, argv))) SWIG_fail; + --argc; + if (argc == 2) { + int _v = 0; + int res = swig::asptr(argv[0], (std::vector< std::string,std::allocator< std::string > >**)(0)); + _v = SWIG_CheckState(res); + if (_v) { + { + int res = SWIG_AsVal_size_t(argv[1], NULL); + _v = SWIG_CheckState(res); + } + if (_v) { + return _wrap_StringVec_resize__SWIG_0(self, argc, argv); + } + } + } + if (argc == 3) { + int _v = 0; + int res = swig::asptr(argv[0], (std::vector< std::string,std::allocator< std::string > >**)(0)); + _v = SWIG_CheckState(res); + if (_v) { + { + int res = SWIG_AsVal_size_t(argv[1], NULL); + _v = SWIG_CheckState(res); + } + if (_v) { + int res = SWIG_AsPtr_std_string(argv[2], (std::string**)(0)); + _v = SWIG_CheckState(res); + if (_v) { + return _wrap_StringVec_resize__SWIG_1(self, argc, argv); + } + } + } + } + +fail: + SWIG_Python_RaiseOrModifyTypeError("Wrong number or type of arguments for overloaded function 'StringVec_resize'.\n" + " Possible C/C++ prototypes are:\n" + " std::vector< std::string >::resize(std::vector< std::string >::size_type)\n" + " std::vector< std::string >::resize(std::vector< std::string >::size_type,std::vector< std::string >::value_type const &)\n"); + return 0; +} + + +SWIGINTERN PyObject *_wrap_StringVec_insert__SWIG_0(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ; + std::vector< std::string >::iterator arg2 ; + std::vector< std::string >::value_type *arg3 = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + swig::SwigPyIterator *iter2 = 0 ; + int res2 ; + int res3 = SWIG_OLDOBJ ; + std::vector< std::string >::iterator result; + + (void)self; + if ((nobjs < 3) || (nobjs > 3)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_std__string_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVec_insert" "', argument " "1"" of type '" "std::vector< std::string > *""'"); + } + arg1 = reinterpret_cast< std::vector< std::string > * >(argp1); + res2 = SWIG_ConvertPtr(swig_obj[1], SWIG_as_voidptrptr(&iter2), swig::SwigPyIterator::descriptor(), 0); + if (!SWIG_IsOK(res2) || !iter2) { + SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "StringVec_insert" "', argument " "2"" of type '" "std::vector< std::string >::iterator""'"); + } else { + swig::SwigPyIterator_T::iterator > *iter_t = dynamic_cast::iterator > *>(iter2); + if (iter_t) { + arg2 = iter_t->get_current(); + } else { + SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "StringVec_insert" "', argument " "2"" of type '" "std::vector< std::string >::iterator""'"); + } + } + { + std::string *ptr = (std::string *)0; + res3 = SWIG_AsPtr_std_string(swig_obj[2], &ptr); + if (!SWIG_IsOK(res3)) { + SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "StringVec_insert" "', argument " "3"" of type '" "std::vector< std::string >::value_type const &""'"); + } + if (!ptr) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "StringVec_insert" "', argument " "3"" of type '" "std::vector< std::string >::value_type const &""'"); + } + arg3 = ptr; + } + result = std_vector_Sl_std_string_Sg__insert__SWIG_0(arg1,SWIG_STD_MOVE(arg2),(std::string const &)*arg3); + resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector< std::string >::iterator & >(result)), + swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN); + if (SWIG_IsNewObj(res3)) delete arg3; + return resultobj; +fail: + if (SWIG_IsNewObj(res3)) delete arg3; + return NULL; +} + + +SWIGINTERN PyObject *_wrap_StringVec_insert__SWIG_1(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ; + std::vector< std::string >::iterator arg2 ; + std::vector< std::string >::size_type arg3 ; + std::vector< std::string >::value_type *arg4 = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + swig::SwigPyIterator *iter2 = 0 ; + int res2 ; + size_t val3 ; + int ecode3 = 0 ; + int res4 = SWIG_OLDOBJ ; + + (void)self; + if ((nobjs < 4) || (nobjs > 4)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_std__string_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVec_insert" "', argument " "1"" of type '" "std::vector< std::string > *""'"); + } + arg1 = reinterpret_cast< std::vector< std::string > * >(argp1); + res2 = SWIG_ConvertPtr(swig_obj[1], SWIG_as_voidptrptr(&iter2), swig::SwigPyIterator::descriptor(), 0); + if (!SWIG_IsOK(res2) || !iter2) { + SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "StringVec_insert" "', argument " "2"" of type '" "std::vector< std::string >::iterator""'"); + } else { + swig::SwigPyIterator_T::iterator > *iter_t = dynamic_cast::iterator > *>(iter2); + if (iter_t) { + arg2 = iter_t->get_current(); + } else { + SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "StringVec_insert" "', argument " "2"" of type '" "std::vector< std::string >::iterator""'"); + } + } + ecode3 = SWIG_AsVal_size_t(swig_obj[2], &val3); + if (!SWIG_IsOK(ecode3)) { + SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "StringVec_insert" "', argument " "3"" of type '" "std::vector< std::string >::size_type""'"); + } + arg3 = static_cast< std::vector< std::string >::size_type >(val3); + { + std::string *ptr = (std::string *)0; + res4 = SWIG_AsPtr_std_string(swig_obj[3], &ptr); + if (!SWIG_IsOK(res4)) { + SWIG_exception_fail(SWIG_ArgError(res4), "in method '" "StringVec_insert" "', argument " "4"" of type '" "std::vector< std::string >::value_type const &""'"); + } + if (!ptr) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "StringVec_insert" "', argument " "4"" of type '" "std::vector< std::string >::value_type const &""'"); + } + arg4 = ptr; + } + std_vector_Sl_std_string_Sg__insert__SWIG_1(arg1,SWIG_STD_MOVE(arg2),SWIG_STD_MOVE(arg3),(std::string const &)*arg4); + resultobj = SWIG_Py_Void(); + if (SWIG_IsNewObj(res4)) delete arg4; + return resultobj; +fail: + if (SWIG_IsNewObj(res4)) delete arg4; + return NULL; +} + + +SWIGINTERN PyObject *_wrap_StringVec_insert(PyObject *self, PyObject *args) { + Py_ssize_t argc; + PyObject *argv[5] = { + 0 + }; + + if (!(argc = SWIG_Python_UnpackTuple(args, "StringVec_insert", 0, 4, argv))) SWIG_fail; + --argc; + if (argc == 3) { + int _v = 0; + int res = swig::asptr(argv[0], (std::vector< std::string,std::allocator< std::string > >**)(0)); + _v = SWIG_CheckState(res); + if (_v) { + swig::SwigPyIterator *iter = 0; + int res = SWIG_ConvertPtr(argv[1], SWIG_as_voidptrptr(&iter), swig::SwigPyIterator::descriptor(), 0); + _v = (SWIG_IsOK(res) && iter && (dynamic_cast::iterator > *>(iter) != 0)); + if (_v) { + int res = SWIG_AsPtr_std_string(argv[2], (std::string**)(0)); + _v = SWIG_CheckState(res); + if (_v) { + return _wrap_StringVec_insert__SWIG_0(self, argc, argv); + } + } + } + } + if (argc == 4) { + int _v = 0; + int res = swig::asptr(argv[0], (std::vector< std::string,std::allocator< std::string > >**)(0)); + _v = SWIG_CheckState(res); + if (_v) { + swig::SwigPyIterator *iter = 0; + int res = SWIG_ConvertPtr(argv[1], SWIG_as_voidptrptr(&iter), swig::SwigPyIterator::descriptor(), 0); + _v = (SWIG_IsOK(res) && iter && (dynamic_cast::iterator > *>(iter) != 0)); + if (_v) { + { + int res = SWIG_AsVal_size_t(argv[2], NULL); + _v = SWIG_CheckState(res); + } + if (_v) { + int res = SWIG_AsPtr_std_string(argv[3], (std::string**)(0)); + _v = SWIG_CheckState(res); + if (_v) { + return _wrap_StringVec_insert__SWIG_1(self, argc, argv); + } + } + } + } + } + +fail: + SWIG_Python_RaiseOrModifyTypeError("Wrong number or type of arguments for overloaded function 'StringVec_insert'.\n" + " Possible C/C++ prototypes are:\n" + " std::vector< std::string >::insert(std::vector< std::string >::iterator,std::vector< std::string >::value_type const &)\n" + " std::vector< std::string >::insert(std::vector< std::string >::iterator,std::vector< std::string >::size_type,std::vector< std::string >::value_type const &)\n"); + return 0; +} + + +SWIGINTERN PyObject *_wrap_StringVec_reserve(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ; + std::vector< std::string >::size_type arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + size_t val2 ; + int ecode2 = 0 ; + PyObject *swig_obj[2] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "StringVec_reserve", 2, 2, swig_obj)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_std__string_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVec_reserve" "', argument " "1"" of type '" "std::vector< std::string > *""'"); + } + arg1 = reinterpret_cast< std::vector< std::string > * >(argp1); + ecode2 = SWIG_AsVal_size_t(swig_obj[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "StringVec_reserve" "', argument " "2"" of type '" "std::vector< std::string >::size_type""'"); + } + arg2 = static_cast< std::vector< std::string >::size_type >(val2); + (arg1)->reserve(arg2); + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_StringVec_capacity(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + std::vector< std::string >::size_type result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_std__string_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVec_capacity" "', argument " "1"" of type '" "std::vector< std::string > const *""'"); + } + arg1 = reinterpret_cast< std::vector< std::string > * >(argp1); + result = ((std::vector< std::string > const *)arg1)->capacity(); + resultobj = SWIG_From_size_t(static_cast< size_t >(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_delete_StringVec(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_std__string_t, SWIG_POINTER_DISOWN | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_StringVec" "', argument " "1"" of type '" "std::vector< std::string > *""'"); + } + arg1 = reinterpret_cast< std::vector< std::string > * >(argp1); + { + try { + delete arg1; + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *StringVec_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *obj; + if (!SWIG_Python_UnpackTuple(args, "swigregister", 1, 1, &obj)) return NULL; + SWIG_TypeNewClientData(SWIGTYPE_p_std__vectorT_std__string_t, SWIG_NewClientData(obj)); + return SWIG_Py_Void(); +} + +SWIGINTERN PyObject *StringVec_swiginit(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + return SWIG_Python_InitShadowInstance(args); +} + +SWIGINTERN PyObject *_wrap_NodeInfoVec_iterator(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *arg1 = (std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *) 0 ; + PyObject **arg2 = (PyObject **) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + swig::SwigPyIterator *result = 0 ; + + arg2 = &swig_obj[0]; + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_std__shared_ptrT_ppc__protocol__INodeInfo_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "NodeInfoVec_iterator" "', argument " "1"" of type '" "std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *""'"); + } + arg1 = reinterpret_cast< std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > * >(argp1); + result = (swig::SwigPyIterator *)std_vector_Sl_std_shared_ptr_Sl_ppc_protocol_INodeInfo_Sg__Sg__iterator(arg1,arg2); + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_swig__SwigPyIterator, SWIG_POINTER_OWN | 0 ); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_NodeInfoVec___nonzero__(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *arg1 = (std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + bool result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_std__shared_ptrT_ppc__protocol__INodeInfo_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "NodeInfoVec___nonzero__" "', argument " "1"" of type '" "std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > const *""'"); + } + arg1 = reinterpret_cast< std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > * >(argp1); + result = (bool)std_vector_Sl_std_shared_ptr_Sl_ppc_protocol_INodeInfo_Sg__Sg____nonzero__((std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > const *)arg1); + resultobj = SWIG_From_bool(static_cast< bool >(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_NodeInfoVec___bool__(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *arg1 = (std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + bool result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_std__shared_ptrT_ppc__protocol__INodeInfo_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "NodeInfoVec___bool__" "', argument " "1"" of type '" "std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > const *""'"); + } + arg1 = reinterpret_cast< std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > * >(argp1); + result = (bool)std_vector_Sl_std_shared_ptr_Sl_ppc_protocol_INodeInfo_Sg__Sg____bool__((std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > const *)arg1); + resultobj = SWIG_From_bool(static_cast< bool >(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_NodeInfoVec___len__(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *arg1 = (std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::size_type result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_std__shared_ptrT_ppc__protocol__INodeInfo_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "NodeInfoVec___len__" "', argument " "1"" of type '" "std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > const *""'"); + } + arg1 = reinterpret_cast< std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > * >(argp1); + result = std_vector_Sl_std_shared_ptr_Sl_ppc_protocol_INodeInfo_Sg__Sg____len__((std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > const *)arg1); + resultobj = SWIG_From_size_t(static_cast< size_t >(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_NodeInfoVec___getslice__(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *arg1 = (std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *) 0 ; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::difference_type arg2 ; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::difference_type arg3 ; + void *argp1 = 0 ; + int res1 = 0 ; + ptrdiff_t val2 ; + int ecode2 = 0 ; + ptrdiff_t val3 ; + int ecode3 = 0 ; + PyObject *swig_obj[3] ; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo >,std::allocator< std::shared_ptr< ppc::protocol::INodeInfo > > > *result = 0 ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "NodeInfoVec___getslice__", 3, 3, swig_obj)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_std__shared_ptrT_ppc__protocol__INodeInfo_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "NodeInfoVec___getslice__" "', argument " "1"" of type '" "std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *""'"); + } + arg1 = reinterpret_cast< std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > * >(argp1); + ecode2 = SWIG_AsVal_ptrdiff_t(swig_obj[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "NodeInfoVec___getslice__" "', argument " "2"" of type '" "std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::difference_type""'"); + } + arg2 = static_cast< std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::difference_type >(val2); + ecode3 = SWIG_AsVal_ptrdiff_t(swig_obj[2], &val3); + if (!SWIG_IsOK(ecode3)) { + SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "NodeInfoVec___getslice__" "', argument " "3"" of type '" "std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::difference_type""'"); + } + arg3 = static_cast< std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::difference_type >(val3); + try { + result = (std::vector< std::shared_ptr< ppc::protocol::INodeInfo >,std::allocator< std::shared_ptr< ppc::protocol::INodeInfo > > > *)std_vector_Sl_std_shared_ptr_Sl_ppc_protocol_INodeInfo_Sg__Sg____getslice__(arg1,SWIG_STD_MOVE(arg2),SWIG_STD_MOVE(arg3)); + } catch(std::out_of_range &_e) { + SWIG_exception_fail(SWIG_IndexError, (&_e)->what()); + } catch(std::invalid_argument &_e) { + SWIG_exception_fail(SWIG_ValueError, (&_e)->what()); + } + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorT_std__shared_ptrT_ppc__protocol__INodeInfo_t_t, SWIG_POINTER_OWN | 0 ); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_NodeInfoVec___setslice____SWIG_0(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *arg1 = (std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *) 0 ; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::difference_type arg2 ; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::difference_type arg3 ; + void *argp1 = 0 ; + int res1 = 0 ; + ptrdiff_t val2 ; + int ecode2 = 0 ; + ptrdiff_t val3 ; + int ecode3 = 0 ; + + (void)self; + if ((nobjs < 3) || (nobjs > 3)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_std__shared_ptrT_ppc__protocol__INodeInfo_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "NodeInfoVec___setslice__" "', argument " "1"" of type '" "std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *""'"); + } + arg1 = reinterpret_cast< std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > * >(argp1); + ecode2 = SWIG_AsVal_ptrdiff_t(swig_obj[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "NodeInfoVec___setslice__" "', argument " "2"" of type '" "std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::difference_type""'"); + } + arg2 = static_cast< std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::difference_type >(val2); + ecode3 = SWIG_AsVal_ptrdiff_t(swig_obj[2], &val3); + if (!SWIG_IsOK(ecode3)) { + SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "NodeInfoVec___setslice__" "', argument " "3"" of type '" "std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::difference_type""'"); + } + arg3 = static_cast< std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::difference_type >(val3); + try { + std_vector_Sl_std_shared_ptr_Sl_ppc_protocol_INodeInfo_Sg__Sg____setslice____SWIG_0(arg1,SWIG_STD_MOVE(arg2),SWIG_STD_MOVE(arg3)); + } catch(std::out_of_range &_e) { + SWIG_exception_fail(SWIG_IndexError, (&_e)->what()); + } catch(std::invalid_argument &_e) { + SWIG_exception_fail(SWIG_ValueError, (&_e)->what()); + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_NodeInfoVec___setslice____SWIG_1(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *arg1 = (std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *) 0 ; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::difference_type arg2 ; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::difference_type arg3 ; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo >,std::allocator< std::shared_ptr< ppc::protocol::INodeInfo > > > *arg4 = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + ptrdiff_t val2 ; + int ecode2 = 0 ; + ptrdiff_t val3 ; + int ecode3 = 0 ; + int res4 = SWIG_OLDOBJ ; + + (void)self; + if ((nobjs < 4) || (nobjs > 4)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_std__shared_ptrT_ppc__protocol__INodeInfo_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "NodeInfoVec___setslice__" "', argument " "1"" of type '" "std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *""'"); + } + arg1 = reinterpret_cast< std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > * >(argp1); + ecode2 = SWIG_AsVal_ptrdiff_t(swig_obj[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "NodeInfoVec___setslice__" "', argument " "2"" of type '" "std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::difference_type""'"); + } + arg2 = static_cast< std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::difference_type >(val2); + ecode3 = SWIG_AsVal_ptrdiff_t(swig_obj[2], &val3); + if (!SWIG_IsOK(ecode3)) { + SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "NodeInfoVec___setslice__" "', argument " "3"" of type '" "std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::difference_type""'"); + } + arg3 = static_cast< std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::difference_type >(val3); + { + std::vector< std::shared_ptr< ppc::protocol::INodeInfo >,std::allocator< std::shared_ptr< ppc::protocol::INodeInfo > > > *ptr = (std::vector< std::shared_ptr< ppc::protocol::INodeInfo >,std::allocator< std::shared_ptr< ppc::protocol::INodeInfo > > > *)0; + res4 = swig::asptr(swig_obj[3], &ptr); + if (!SWIG_IsOK(res4)) { + SWIG_exception_fail(SWIG_ArgError(res4), "in method '" "NodeInfoVec___setslice__" "', argument " "4"" of type '" "std::vector< std::shared_ptr< ppc::protocol::INodeInfo >,std::allocator< std::shared_ptr< ppc::protocol::INodeInfo > > > const &""'"); + } + if (!ptr) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "NodeInfoVec___setslice__" "', argument " "4"" of type '" "std::vector< std::shared_ptr< ppc::protocol::INodeInfo >,std::allocator< std::shared_ptr< ppc::protocol::INodeInfo > > > const &""'"); + } + arg4 = ptr; + } + try { + std_vector_Sl_std_shared_ptr_Sl_ppc_protocol_INodeInfo_Sg__Sg____setslice____SWIG_1(arg1,SWIG_STD_MOVE(arg2),SWIG_STD_MOVE(arg3),(std::vector< std::shared_ptr< ppc::protocol::INodeInfo >,std::allocator< std::shared_ptr< ppc::protocol::INodeInfo > > > const &)*arg4); + } catch(std::out_of_range &_e) { + SWIG_exception_fail(SWIG_IndexError, (&_e)->what()); + } catch(std::invalid_argument &_e) { + SWIG_exception_fail(SWIG_ValueError, (&_e)->what()); + } + resultobj = SWIG_Py_Void(); + if (SWIG_IsNewObj(res4)) delete arg4; + return resultobj; +fail: + if (SWIG_IsNewObj(res4)) delete arg4; + return NULL; +} + + +SWIGINTERN PyObject *_wrap_NodeInfoVec___setslice__(PyObject *self, PyObject *args) { + Py_ssize_t argc; + PyObject *argv[5] = { + 0 + }; + + if (!(argc = SWIG_Python_UnpackTuple(args, "NodeInfoVec___setslice__", 0, 4, argv))) SWIG_fail; + --argc; + if (argc == 3) { + int _v = 0; + int res = swig::asptr(argv[0], (std::vector< std::shared_ptr< ppc::protocol::INodeInfo >,std::allocator< std::shared_ptr< ppc::protocol::INodeInfo > > >**)(0)); + _v = SWIG_CheckState(res); + if (_v) { + { + int res = SWIG_AsVal_ptrdiff_t(argv[1], NULL); + _v = SWIG_CheckState(res); + } + if (_v) { + { + int res = SWIG_AsVal_ptrdiff_t(argv[2], NULL); + _v = SWIG_CheckState(res); + } + if (_v) { + return _wrap_NodeInfoVec___setslice____SWIG_0(self, argc, argv); + } + } + } + } + if (argc == 4) { + int _v = 0; + int res = swig::asptr(argv[0], (std::vector< std::shared_ptr< ppc::protocol::INodeInfo >,std::allocator< std::shared_ptr< ppc::protocol::INodeInfo > > >**)(0)); + _v = SWIG_CheckState(res); + if (_v) { + { + int res = SWIG_AsVal_ptrdiff_t(argv[1], NULL); + _v = SWIG_CheckState(res); + } + if (_v) { + { + int res = SWIG_AsVal_ptrdiff_t(argv[2], NULL); + _v = SWIG_CheckState(res); + } + if (_v) { + int res = swig::asptr(argv[3], (std::vector< std::shared_ptr< ppc::protocol::INodeInfo >,std::allocator< std::shared_ptr< ppc::protocol::INodeInfo > > >**)(0)); + _v = SWIG_CheckState(res); + if (_v) { + return _wrap_NodeInfoVec___setslice____SWIG_1(self, argc, argv); + } + } + } + } + } + +fail: + SWIG_Python_RaiseOrModifyTypeError("Wrong number or type of arguments for overloaded function 'NodeInfoVec___setslice__'.\n" + " Possible C/C++ prototypes are:\n" + " std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::__setslice__(std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::difference_type,std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::difference_type)\n" + " std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::__setslice__(std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::difference_type,std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::difference_type,std::vector< std::shared_ptr< ppc::protocol::INodeInfo >,std::allocator< std::shared_ptr< ppc::protocol::INodeInfo > > > const &)\n"); + return 0; +} + + +SWIGINTERN PyObject *_wrap_NodeInfoVec___delslice__(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *arg1 = (std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *) 0 ; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::difference_type arg2 ; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::difference_type arg3 ; + void *argp1 = 0 ; + int res1 = 0 ; + ptrdiff_t val2 ; + int ecode2 = 0 ; + ptrdiff_t val3 ; + int ecode3 = 0 ; + PyObject *swig_obj[3] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "NodeInfoVec___delslice__", 3, 3, swig_obj)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_std__shared_ptrT_ppc__protocol__INodeInfo_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "NodeInfoVec___delslice__" "', argument " "1"" of type '" "std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *""'"); + } + arg1 = reinterpret_cast< std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > * >(argp1); + ecode2 = SWIG_AsVal_ptrdiff_t(swig_obj[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "NodeInfoVec___delslice__" "', argument " "2"" of type '" "std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::difference_type""'"); + } + arg2 = static_cast< std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::difference_type >(val2); + ecode3 = SWIG_AsVal_ptrdiff_t(swig_obj[2], &val3); + if (!SWIG_IsOK(ecode3)) { + SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "NodeInfoVec___delslice__" "', argument " "3"" of type '" "std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::difference_type""'"); + } + arg3 = static_cast< std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::difference_type >(val3); + try { + std_vector_Sl_std_shared_ptr_Sl_ppc_protocol_INodeInfo_Sg__Sg____delslice__(arg1,SWIG_STD_MOVE(arg2),SWIG_STD_MOVE(arg3)); + } catch(std::out_of_range &_e) { + SWIG_exception_fail(SWIG_IndexError, (&_e)->what()); + } catch(std::invalid_argument &_e) { + SWIG_exception_fail(SWIG_ValueError, (&_e)->what()); + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_NodeInfoVec___delitem____SWIG_0(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *arg1 = (std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *) 0 ; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::difference_type arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + ptrdiff_t val2 ; + int ecode2 = 0 ; + + (void)self; + if ((nobjs < 2) || (nobjs > 2)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_std__shared_ptrT_ppc__protocol__INodeInfo_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "NodeInfoVec___delitem__" "', argument " "1"" of type '" "std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *""'"); + } + arg1 = reinterpret_cast< std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > * >(argp1); + ecode2 = SWIG_AsVal_ptrdiff_t(swig_obj[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "NodeInfoVec___delitem__" "', argument " "2"" of type '" "std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::difference_type""'"); + } + arg2 = static_cast< std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::difference_type >(val2); + try { + std_vector_Sl_std_shared_ptr_Sl_ppc_protocol_INodeInfo_Sg__Sg____delitem____SWIG_0(arg1,SWIG_STD_MOVE(arg2)); + } catch(std::out_of_range &_e) { + SWIG_exception_fail(SWIG_IndexError, (&_e)->what()); + } catch(std::invalid_argument &_e) { + SWIG_exception_fail(SWIG_ValueError, (&_e)->what()); + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_NodeInfoVec___getitem____SWIG_0(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *arg1 = (std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *) 0 ; + SWIGPY_SLICEOBJECT *arg2 = (SWIGPY_SLICEOBJECT *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo >,std::allocator< std::shared_ptr< ppc::protocol::INodeInfo > > > *result = 0 ; + + (void)self; + if ((nobjs < 2) || (nobjs > 2)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_std__shared_ptrT_ppc__protocol__INodeInfo_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "NodeInfoVec___getitem__" "', argument " "1"" of type '" "std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *""'"); + } + arg1 = reinterpret_cast< std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > * >(argp1); + { + if (!PySlice_Check(swig_obj[1])) { + SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "NodeInfoVec___getitem__" "', argument " "2"" of type '" "SWIGPY_SLICEOBJECT *""'"); + } + arg2 = (SWIGPY_SLICEOBJECT *) swig_obj[1]; + } + try { + result = (std::vector< std::shared_ptr< ppc::protocol::INodeInfo >,std::allocator< std::shared_ptr< ppc::protocol::INodeInfo > > > *)std_vector_Sl_std_shared_ptr_Sl_ppc_protocol_INodeInfo_Sg__Sg____getitem____SWIG_0(arg1,arg2); + } catch(std::out_of_range &_e) { + SWIG_exception_fail(SWIG_IndexError, (&_e)->what()); + } catch(std::invalid_argument &_e) { + SWIG_exception_fail(SWIG_ValueError, (&_e)->what()); + } + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorT_std__shared_ptrT_ppc__protocol__INodeInfo_t_t, SWIG_POINTER_OWN | 0 ); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_NodeInfoVec___setitem____SWIG_0(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *arg1 = (std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *) 0 ; + SWIGPY_SLICEOBJECT *arg2 = (SWIGPY_SLICEOBJECT *) 0 ; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo >,std::allocator< std::shared_ptr< ppc::protocol::INodeInfo > > > *arg3 = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + int res3 = SWIG_OLDOBJ ; + + (void)self; + if ((nobjs < 3) || (nobjs > 3)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_std__shared_ptrT_ppc__protocol__INodeInfo_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "NodeInfoVec___setitem__" "', argument " "1"" of type '" "std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *""'"); + } + arg1 = reinterpret_cast< std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > * >(argp1); + { + if (!PySlice_Check(swig_obj[1])) { + SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "NodeInfoVec___setitem__" "', argument " "2"" of type '" "SWIGPY_SLICEOBJECT *""'"); + } + arg2 = (SWIGPY_SLICEOBJECT *) swig_obj[1]; + } + { + std::vector< std::shared_ptr< ppc::protocol::INodeInfo >,std::allocator< std::shared_ptr< ppc::protocol::INodeInfo > > > *ptr = (std::vector< std::shared_ptr< ppc::protocol::INodeInfo >,std::allocator< std::shared_ptr< ppc::protocol::INodeInfo > > > *)0; + res3 = swig::asptr(swig_obj[2], &ptr); + if (!SWIG_IsOK(res3)) { + SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "NodeInfoVec___setitem__" "', argument " "3"" of type '" "std::vector< std::shared_ptr< ppc::protocol::INodeInfo >,std::allocator< std::shared_ptr< ppc::protocol::INodeInfo > > > const &""'"); + } + if (!ptr) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "NodeInfoVec___setitem__" "', argument " "3"" of type '" "std::vector< std::shared_ptr< ppc::protocol::INodeInfo >,std::allocator< std::shared_ptr< ppc::protocol::INodeInfo > > > const &""'"); + } + arg3 = ptr; + } + try { + std_vector_Sl_std_shared_ptr_Sl_ppc_protocol_INodeInfo_Sg__Sg____setitem____SWIG_0(arg1,arg2,(std::vector< std::shared_ptr< ppc::protocol::INodeInfo >,std::allocator< std::shared_ptr< ppc::protocol::INodeInfo > > > const &)*arg3); + } catch(std::out_of_range &_e) { + SWIG_exception_fail(SWIG_IndexError, (&_e)->what()); + } catch(std::invalid_argument &_e) { + SWIG_exception_fail(SWIG_ValueError, (&_e)->what()); + } + resultobj = SWIG_Py_Void(); + if (SWIG_IsNewObj(res3)) delete arg3; + return resultobj; +fail: + if (SWIG_IsNewObj(res3)) delete arg3; + return NULL; +} + + +SWIGINTERN PyObject *_wrap_NodeInfoVec___setitem____SWIG_1(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *arg1 = (std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *) 0 ; + SWIGPY_SLICEOBJECT *arg2 = (SWIGPY_SLICEOBJECT *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + + (void)self; + if ((nobjs < 2) || (nobjs > 2)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_std__shared_ptrT_ppc__protocol__INodeInfo_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "NodeInfoVec___setitem__" "', argument " "1"" of type '" "std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *""'"); + } + arg1 = reinterpret_cast< std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > * >(argp1); + { + if (!PySlice_Check(swig_obj[1])) { + SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "NodeInfoVec___setitem__" "', argument " "2"" of type '" "SWIGPY_SLICEOBJECT *""'"); + } + arg2 = (SWIGPY_SLICEOBJECT *) swig_obj[1]; + } + try { + std_vector_Sl_std_shared_ptr_Sl_ppc_protocol_INodeInfo_Sg__Sg____setitem____SWIG_1(arg1,arg2); + } catch(std::out_of_range &_e) { + SWIG_exception_fail(SWIG_IndexError, (&_e)->what()); + } catch(std::invalid_argument &_e) { + SWIG_exception_fail(SWIG_ValueError, (&_e)->what()); + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_NodeInfoVec___delitem____SWIG_1(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *arg1 = (std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *) 0 ; + SWIGPY_SLICEOBJECT *arg2 = (SWIGPY_SLICEOBJECT *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + + (void)self; + if ((nobjs < 2) || (nobjs > 2)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_std__shared_ptrT_ppc__protocol__INodeInfo_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "NodeInfoVec___delitem__" "', argument " "1"" of type '" "std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *""'"); + } + arg1 = reinterpret_cast< std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > * >(argp1); + { + if (!PySlice_Check(swig_obj[1])) { + SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "NodeInfoVec___delitem__" "', argument " "2"" of type '" "SWIGPY_SLICEOBJECT *""'"); + } + arg2 = (SWIGPY_SLICEOBJECT *) swig_obj[1]; + } + try { + std_vector_Sl_std_shared_ptr_Sl_ppc_protocol_INodeInfo_Sg__Sg____delitem____SWIG_1(arg1,arg2); + } catch(std::out_of_range &_e) { + SWIG_exception_fail(SWIG_IndexError, (&_e)->what()); + } catch(std::invalid_argument &_e) { + SWIG_exception_fail(SWIG_ValueError, (&_e)->what()); + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_NodeInfoVec___delitem__(PyObject *self, PyObject *args) { + Py_ssize_t argc; + PyObject *argv[3] = { + 0 + }; + + if (!(argc = SWIG_Python_UnpackTuple(args, "NodeInfoVec___delitem__", 0, 2, argv))) SWIG_fail; + --argc; + if (argc == 2) { + int _v = 0; + int res = swig::asptr(argv[0], (std::vector< std::shared_ptr< ppc::protocol::INodeInfo >,std::allocator< std::shared_ptr< ppc::protocol::INodeInfo > > >**)(0)); + _v = SWIG_CheckState(res); + if (_v) { + { + _v = PySlice_Check(argv[1]); + } + if (_v) { + return _wrap_NodeInfoVec___delitem____SWIG_1(self, argc, argv); + } + } + } + if (argc == 2) { + int _v = 0; + int res = swig::asptr(argv[0], (std::vector< std::shared_ptr< ppc::protocol::INodeInfo >,std::allocator< std::shared_ptr< ppc::protocol::INodeInfo > > >**)(0)); + _v = SWIG_CheckState(res); + if (_v) { + { + int res = SWIG_AsVal_ptrdiff_t(argv[1], NULL); + _v = SWIG_CheckState(res); + } + if (_v) { + return _wrap_NodeInfoVec___delitem____SWIG_0(self, argc, argv); + } + } + } + +fail: + SWIG_Python_RaiseOrModifyTypeError("Wrong number or type of arguments for overloaded function 'NodeInfoVec___delitem__'.\n" + " Possible C/C++ prototypes are:\n" + " std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::__delitem__(std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::difference_type)\n" + " std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::__delitem__(SWIGPY_SLICEOBJECT *)\n"); + return 0; +} + + +SWIGINTERN PyObject *_wrap_NodeInfoVec___getitem____SWIG_1(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *arg1 = (std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *) 0 ; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::difference_type arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + ptrdiff_t val2 ; + int ecode2 = 0 ; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type *result = 0 ; + + (void)self; + if ((nobjs < 2) || (nobjs > 2)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_std__shared_ptrT_ppc__protocol__INodeInfo_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "NodeInfoVec___getitem__" "', argument " "1"" of type '" "std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > const *""'"); + } + arg1 = reinterpret_cast< std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > * >(argp1); + ecode2 = SWIG_AsVal_ptrdiff_t(swig_obj[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "NodeInfoVec___getitem__" "', argument " "2"" of type '" "std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::difference_type""'"); + } + arg2 = static_cast< std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::difference_type >(val2); + try { + result = (std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type *) &std_vector_Sl_std_shared_ptr_Sl_ppc_protocol_INodeInfo_Sg__Sg____getitem____SWIG_1((std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > const *)arg1,SWIG_STD_MOVE(arg2)); + } catch(std::out_of_range &_e) { + SWIG_exception_fail(SWIG_IndexError, (&_e)->what()); + } + { + std::shared_ptr< ppc::protocol::INodeInfo > *smartresult = *result ? new std::shared_ptr< ppc::protocol::INodeInfo >(*result) : 0; + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(smartresult), SWIGTYPE_p_std__shared_ptrT_ppc__protocol__INodeInfo_t, SWIG_POINTER_OWN); + } + (void)swig::container_owner >::value_type>::category>::back_reference(resultobj, swig_obj[0]); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_NodeInfoVec___getitem__(PyObject *self, PyObject *args) { + Py_ssize_t argc; + PyObject *argv[3] = { + 0 + }; + + if (!(argc = SWIG_Python_UnpackTuple(args, "NodeInfoVec___getitem__", 0, 2, argv))) SWIG_fail; + --argc; + if (argc == 2) { + int _v = 0; + int res = swig::asptr(argv[0], (std::vector< std::shared_ptr< ppc::protocol::INodeInfo >,std::allocator< std::shared_ptr< ppc::protocol::INodeInfo > > >**)(0)); + _v = SWIG_CheckState(res); + if (_v) { + { + _v = PySlice_Check(argv[1]); + } + if (_v) { + return _wrap_NodeInfoVec___getitem____SWIG_0(self, argc, argv); + } + } + } + if (argc == 2) { + int _v = 0; + int res = swig::asptr(argv[0], (std::vector< std::shared_ptr< ppc::protocol::INodeInfo >,std::allocator< std::shared_ptr< ppc::protocol::INodeInfo > > >**)(0)); + _v = SWIG_CheckState(res); + if (_v) { + { + int res = SWIG_AsVal_ptrdiff_t(argv[1], NULL); + _v = SWIG_CheckState(res); + } + if (_v) { + return _wrap_NodeInfoVec___getitem____SWIG_1(self, argc, argv); + } + } + } + +fail: + SWIG_Python_RaiseOrModifyTypeError("Wrong number or type of arguments for overloaded function 'NodeInfoVec___getitem__'.\n" + " Possible C/C++ prototypes are:\n" + " std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::__getitem__(SWIGPY_SLICEOBJECT *)\n" + " std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::__getitem__(std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::difference_type) const\n"); + return 0; +} + + +SWIGINTERN PyObject *_wrap_NodeInfoVec___setitem____SWIG_2(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *arg1 = (std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *) 0 ; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::difference_type arg2 ; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type *arg3 = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + ptrdiff_t val2 ; + int ecode2 = 0 ; + void *argp3 ; + int res3 = 0 ; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type tempshared3 ; + + (void)self; + if ((nobjs < 3) || (nobjs > 3)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_std__shared_ptrT_ppc__protocol__INodeInfo_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "NodeInfoVec___setitem__" "', argument " "1"" of type '" "std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *""'"); + } + arg1 = reinterpret_cast< std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > * >(argp1); + ecode2 = SWIG_AsVal_ptrdiff_t(swig_obj[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "NodeInfoVec___setitem__" "', argument " "2"" of type '" "std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::difference_type""'"); + } + arg2 = static_cast< std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::difference_type >(val2); + { + int newmem = 0; + res3 = SWIG_ConvertPtrAndOwn(swig_obj[2], &argp3, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__INodeInfo_t, 0 , &newmem); + if (!SWIG_IsOK(res3)) { + SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "NodeInfoVec___setitem__" "', argument " "3"" of type '" "std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type const &""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + if (argp3) tempshared3 = *reinterpret_cast< std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type * >(argp3); + delete reinterpret_cast< std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type * >(argp3); + arg3 = &tempshared3; + } else { + arg3 = (argp3) ? reinterpret_cast< std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type * >(argp3) : &tempshared3; + } + } + try { + std_vector_Sl_std_shared_ptr_Sl_ppc_protocol_INodeInfo_Sg__Sg____setitem____SWIG_2(arg1,SWIG_STD_MOVE(arg2),(std::shared_ptr< ppc::protocol::INodeInfo > const &)*arg3); + } catch(std::out_of_range &_e) { + SWIG_exception_fail(SWIG_IndexError, (&_e)->what()); + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_NodeInfoVec___setitem__(PyObject *self, PyObject *args) { + Py_ssize_t argc; + PyObject *argv[4] = { + 0 + }; + + if (!(argc = SWIG_Python_UnpackTuple(args, "NodeInfoVec___setitem__", 0, 3, argv))) SWIG_fail; + --argc; + if (argc == 2) { + int _v = 0; + int res = swig::asptr(argv[0], (std::vector< std::shared_ptr< ppc::protocol::INodeInfo >,std::allocator< std::shared_ptr< ppc::protocol::INodeInfo > > >**)(0)); + _v = SWIG_CheckState(res); + if (_v) { + { + _v = PySlice_Check(argv[1]); + } + if (_v) { + return _wrap_NodeInfoVec___setitem____SWIG_1(self, argc, argv); + } + } + } + if (argc == 3) { + int _v = 0; + int res = swig::asptr(argv[0], (std::vector< std::shared_ptr< ppc::protocol::INodeInfo >,std::allocator< std::shared_ptr< ppc::protocol::INodeInfo > > >**)(0)); + _v = SWIG_CheckState(res); + if (_v) { + { + _v = PySlice_Check(argv[1]); + } + if (_v) { + int res = swig::asptr(argv[2], (std::vector< std::shared_ptr< ppc::protocol::INodeInfo >,std::allocator< std::shared_ptr< ppc::protocol::INodeInfo > > >**)(0)); + _v = SWIG_CheckState(res); + if (_v) { + return _wrap_NodeInfoVec___setitem____SWIG_0(self, argc, argv); + } + } + } + } + if (argc == 3) { + int _v = 0; + int res = swig::asptr(argv[0], (std::vector< std::shared_ptr< ppc::protocol::INodeInfo >,std::allocator< std::shared_ptr< ppc::protocol::INodeInfo > > >**)(0)); + _v = SWIG_CheckState(res); + if (_v) { + { + int res = SWIG_AsVal_ptrdiff_t(argv[1], NULL); + _v = SWIG_CheckState(res); + } + if (_v) { + int res = SWIG_ConvertPtr(argv[2], 0, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__INodeInfo_t, 0); + _v = SWIG_CheckState(res); + if (_v) { + return _wrap_NodeInfoVec___setitem____SWIG_2(self, argc, argv); + } + } + } + } + +fail: + SWIG_Python_RaiseOrModifyTypeError("Wrong number or type of arguments for overloaded function 'NodeInfoVec___setitem__'.\n" + " Possible C/C++ prototypes are:\n" + " std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::__setitem__(SWIGPY_SLICEOBJECT *,std::vector< std::shared_ptr< ppc::protocol::INodeInfo >,std::allocator< std::shared_ptr< ppc::protocol::INodeInfo > > > const &)\n" + " std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::__setitem__(SWIGPY_SLICEOBJECT *)\n" + " std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::__setitem__(std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::difference_type,std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type const &)\n"); + return 0; +} + + +SWIGINTERN PyObject *_wrap_NodeInfoVec_pop(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *arg1 = (std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_std__shared_ptrT_ppc__protocol__INodeInfo_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "NodeInfoVec_pop" "', argument " "1"" of type '" "std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *""'"); + } + arg1 = reinterpret_cast< std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > * >(argp1); + try { + result = std_vector_Sl_std_shared_ptr_Sl_ppc_protocol_INodeInfo_Sg__Sg__pop(arg1); + } catch(std::out_of_range &_e) { + SWIG_exception_fail(SWIG_IndexError, (&_e)->what()); + } + { + std::shared_ptr< ppc::protocol::INodeInfo > *smartresult = result ? new std::shared_ptr< ppc::protocol::INodeInfo >(result) : 0; + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(smartresult), SWIGTYPE_p_std__shared_ptrT_ppc__protocol__INodeInfo_t, SWIG_POINTER_OWN); + } + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_NodeInfoVec_append(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *arg1 = (std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *) 0 ; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type *arg2 = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + void *argp2 ; + int res2 = 0 ; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type tempshared2 ; + PyObject *swig_obj[2] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "NodeInfoVec_append", 2, 2, swig_obj)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_std__shared_ptrT_ppc__protocol__INodeInfo_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "NodeInfoVec_append" "', argument " "1"" of type '" "std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *""'"); + } + arg1 = reinterpret_cast< std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > * >(argp1); + { + int newmem = 0; + res2 = SWIG_ConvertPtrAndOwn(swig_obj[1], &argp2, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__INodeInfo_t, 0 , &newmem); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "NodeInfoVec_append" "', argument " "2"" of type '" "std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type const &""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + if (argp2) tempshared2 = *reinterpret_cast< std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type * >(argp2); + delete reinterpret_cast< std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type * >(argp2); + arg2 = &tempshared2; + } else { + arg2 = (argp2) ? reinterpret_cast< std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type * >(argp2) : &tempshared2; + } + } + std_vector_Sl_std_shared_ptr_Sl_ppc_protocol_INodeInfo_Sg__Sg__append(arg1,(std::shared_ptr< ppc::protocol::INodeInfo > const &)*arg2); + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_new_NodeInfoVec__SWIG_0(PyObject *self, Py_ssize_t nobjs, PyObject **SWIGUNUSEDPARM(swig_obj)) { + PyObject *resultobj = 0; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *result = 0 ; + + (void)self; + if ((nobjs < 0) || (nobjs > 0)) SWIG_fail; + result = (std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *)new std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >(); + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorT_std__shared_ptrT_ppc__protocol__INodeInfo_t_t, SWIG_POINTER_NEW | 0 ); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_new_NodeInfoVec__SWIG_1(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *arg1 = 0 ; + int res1 = SWIG_OLDOBJ ; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *result = 0 ; + + (void)self; + if ((nobjs < 1) || (nobjs > 1)) SWIG_fail; + { + std::vector< std::shared_ptr< ppc::protocol::INodeInfo >,std::allocator< std::shared_ptr< ppc::protocol::INodeInfo > > > *ptr = (std::vector< std::shared_ptr< ppc::protocol::INodeInfo >,std::allocator< std::shared_ptr< ppc::protocol::INodeInfo > > > *)0; + res1 = swig::asptr(swig_obj[0], &ptr); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "new_NodeInfoVec" "', argument " "1"" of type '" "std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > const &""'"); + } + if (!ptr) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_NodeInfoVec" "', argument " "1"" of type '" "std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > const &""'"); + } + arg1 = ptr; + } + result = (std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *)new std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >((std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > const &)*arg1); + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorT_std__shared_ptrT_ppc__protocol__INodeInfo_t_t, SWIG_POINTER_NEW | 0 ); + if (SWIG_IsNewObj(res1)) delete arg1; + return resultobj; +fail: + if (SWIG_IsNewObj(res1)) delete arg1; + return NULL; +} + + +SWIGINTERN PyObject *_wrap_NodeInfoVec_empty(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *arg1 = (std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + bool result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_std__shared_ptrT_ppc__protocol__INodeInfo_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "NodeInfoVec_empty" "', argument " "1"" of type '" "std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > const *""'"); + } + arg1 = reinterpret_cast< std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > * >(argp1); + result = (bool)((std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > const *)arg1)->empty(); + resultobj = SWIG_From_bool(static_cast< bool >(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_NodeInfoVec_size(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *arg1 = (std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::size_type result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_std__shared_ptrT_ppc__protocol__INodeInfo_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "NodeInfoVec_size" "', argument " "1"" of type '" "std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > const *""'"); + } + arg1 = reinterpret_cast< std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > * >(argp1); + result = ((std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > const *)arg1)->size(); + resultobj = SWIG_From_size_t(static_cast< size_t >(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_NodeInfoVec_swap(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *arg1 = (std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *) 0 ; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *arg2 = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + void *argp2 = 0 ; + int res2 = 0 ; + PyObject *swig_obj[2] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "NodeInfoVec_swap", 2, 2, swig_obj)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_std__shared_ptrT_ppc__protocol__INodeInfo_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "NodeInfoVec_swap" "', argument " "1"" of type '" "std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *""'"); + } + arg1 = reinterpret_cast< std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > * >(argp1); + res2 = SWIG_ConvertPtr(swig_obj[1], &argp2, SWIGTYPE_p_std__vectorT_std__shared_ptrT_ppc__protocol__INodeInfo_t_t, 0 ); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "NodeInfoVec_swap" "', argument " "2"" of type '" "std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > &""'"); + } + if (!argp2) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "NodeInfoVec_swap" "', argument " "2"" of type '" "std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > &""'"); + } + arg2 = reinterpret_cast< std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > * >(argp2); + (arg1)->swap(*arg2); + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_NodeInfoVec_begin(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *arg1 = (std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::iterator result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_std__shared_ptrT_ppc__protocol__INodeInfo_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "NodeInfoVec_begin" "', argument " "1"" of type '" "std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *""'"); + } + arg1 = reinterpret_cast< std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > * >(argp1); + result = (arg1)->begin(); + resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::iterator & >(result)), + swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_NodeInfoVec_end(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *arg1 = (std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::iterator result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_std__shared_ptrT_ppc__protocol__INodeInfo_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "NodeInfoVec_end" "', argument " "1"" of type '" "std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *""'"); + } + arg1 = reinterpret_cast< std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > * >(argp1); + result = (arg1)->end(); + resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::iterator & >(result)), + swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_NodeInfoVec_rbegin(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *arg1 = (std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::reverse_iterator result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_std__shared_ptrT_ppc__protocol__INodeInfo_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "NodeInfoVec_rbegin" "', argument " "1"" of type '" "std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *""'"); + } + arg1 = reinterpret_cast< std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > * >(argp1); + result = (arg1)->rbegin(); + resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::reverse_iterator & >(result)), + swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_NodeInfoVec_rend(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *arg1 = (std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::reverse_iterator result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_std__shared_ptrT_ppc__protocol__INodeInfo_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "NodeInfoVec_rend" "', argument " "1"" of type '" "std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *""'"); + } + arg1 = reinterpret_cast< std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > * >(argp1); + result = (arg1)->rend(); + resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::reverse_iterator & >(result)), + swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_NodeInfoVec_clear(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *arg1 = (std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_std__shared_ptrT_ppc__protocol__INodeInfo_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "NodeInfoVec_clear" "', argument " "1"" of type '" "std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *""'"); + } + arg1 = reinterpret_cast< std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > * >(argp1); + (arg1)->clear(); + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_NodeInfoVec_get_allocator(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *arg1 = (std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + SwigValueWrapper< std::allocator< std::shared_ptr< ppc::protocol::INodeInfo > > > result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_std__shared_ptrT_ppc__protocol__INodeInfo_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "NodeInfoVec_get_allocator" "', argument " "1"" of type '" "std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > const *""'"); + } + arg1 = reinterpret_cast< std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > * >(argp1); + result = ((std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > const *)arg1)->get_allocator(); + resultobj = SWIG_NewPointerObj((new std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::allocator_type(result)), SWIGTYPE_p_std__allocatorT_std__shared_ptrT_ppc__protocol__INodeInfo_t_t, SWIG_POINTER_OWN | 0 ); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_new_NodeInfoVec__SWIG_2(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::size_type arg1 ; + size_t val1 ; + int ecode1 = 0 ; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *result = 0 ; + + (void)self; + if ((nobjs < 1) || (nobjs > 1)) SWIG_fail; + ecode1 = SWIG_AsVal_size_t(swig_obj[0], &val1); + if (!SWIG_IsOK(ecode1)) { + SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "new_NodeInfoVec" "', argument " "1"" of type '" "std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::size_type""'"); + } + arg1 = static_cast< std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::size_type >(val1); + result = (std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *)new std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >(arg1); + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorT_std__shared_ptrT_ppc__protocol__INodeInfo_t_t, SWIG_POINTER_NEW | 0 ); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_NodeInfoVec_pop_back(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *arg1 = (std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_std__shared_ptrT_ppc__protocol__INodeInfo_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "NodeInfoVec_pop_back" "', argument " "1"" of type '" "std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *""'"); + } + arg1 = reinterpret_cast< std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > * >(argp1); + (arg1)->pop_back(); + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_NodeInfoVec_resize__SWIG_0(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *arg1 = (std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *) 0 ; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::size_type arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + size_t val2 ; + int ecode2 = 0 ; + + (void)self; + if ((nobjs < 2) || (nobjs > 2)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_std__shared_ptrT_ppc__protocol__INodeInfo_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "NodeInfoVec_resize" "', argument " "1"" of type '" "std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *""'"); + } + arg1 = reinterpret_cast< std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > * >(argp1); + ecode2 = SWIG_AsVal_size_t(swig_obj[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "NodeInfoVec_resize" "', argument " "2"" of type '" "std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::size_type""'"); + } + arg2 = static_cast< std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::size_type >(val2); + (arg1)->resize(arg2); + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_NodeInfoVec_erase__SWIG_0(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *arg1 = (std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *) 0 ; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::iterator arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + swig::SwigPyIterator *iter2 = 0 ; + int res2 ; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::iterator result; + + (void)self; + if ((nobjs < 2) || (nobjs > 2)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_std__shared_ptrT_ppc__protocol__INodeInfo_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "NodeInfoVec_erase" "', argument " "1"" of type '" "std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *""'"); + } + arg1 = reinterpret_cast< std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > * >(argp1); + res2 = SWIG_ConvertPtr(swig_obj[1], SWIG_as_voidptrptr(&iter2), swig::SwigPyIterator::descriptor(), 0); + if (!SWIG_IsOK(res2) || !iter2) { + SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "NodeInfoVec_erase" "', argument " "2"" of type '" "std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::iterator""'"); + } else { + swig::SwigPyIterator_T >::iterator > *iter_t = dynamic_cast >::iterator > *>(iter2); + if (iter_t) { + arg2 = iter_t->get_current(); + } else { + SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "NodeInfoVec_erase" "', argument " "2"" of type '" "std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::iterator""'"); + } + } + result = std_vector_Sl_std_shared_ptr_Sl_ppc_protocol_INodeInfo_Sg__Sg__erase__SWIG_0(arg1,SWIG_STD_MOVE(arg2)); + resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::iterator & >(result)), + swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_NodeInfoVec_erase__SWIG_1(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *arg1 = (std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *) 0 ; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::iterator arg2 ; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::iterator arg3 ; + void *argp1 = 0 ; + int res1 = 0 ; + swig::SwigPyIterator *iter2 = 0 ; + int res2 ; + swig::SwigPyIterator *iter3 = 0 ; + int res3 ; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::iterator result; + + (void)self; + if ((nobjs < 3) || (nobjs > 3)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_std__shared_ptrT_ppc__protocol__INodeInfo_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "NodeInfoVec_erase" "', argument " "1"" of type '" "std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *""'"); + } + arg1 = reinterpret_cast< std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > * >(argp1); + res2 = SWIG_ConvertPtr(swig_obj[1], SWIG_as_voidptrptr(&iter2), swig::SwigPyIterator::descriptor(), 0); + if (!SWIG_IsOK(res2) || !iter2) { + SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "NodeInfoVec_erase" "', argument " "2"" of type '" "std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::iterator""'"); + } else { + swig::SwigPyIterator_T >::iterator > *iter_t = dynamic_cast >::iterator > *>(iter2); + if (iter_t) { + arg2 = iter_t->get_current(); + } else { + SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "NodeInfoVec_erase" "', argument " "2"" of type '" "std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::iterator""'"); + } + } + res3 = SWIG_ConvertPtr(swig_obj[2], SWIG_as_voidptrptr(&iter3), swig::SwigPyIterator::descriptor(), 0); + if (!SWIG_IsOK(res3) || !iter3) { + SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "NodeInfoVec_erase" "', argument " "3"" of type '" "std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::iterator""'"); + } else { + swig::SwigPyIterator_T >::iterator > *iter_t = dynamic_cast >::iterator > *>(iter3); + if (iter_t) { + arg3 = iter_t->get_current(); + } else { + SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "NodeInfoVec_erase" "', argument " "3"" of type '" "std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::iterator""'"); + } + } + result = std_vector_Sl_std_shared_ptr_Sl_ppc_protocol_INodeInfo_Sg__Sg__erase__SWIG_1(arg1,SWIG_STD_MOVE(arg2),SWIG_STD_MOVE(arg3)); + resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::iterator & >(result)), + swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_NodeInfoVec_erase(PyObject *self, PyObject *args) { + Py_ssize_t argc; + PyObject *argv[4] = { + 0 + }; + + if (!(argc = SWIG_Python_UnpackTuple(args, "NodeInfoVec_erase", 0, 3, argv))) SWIG_fail; + --argc; + if (argc == 2) { + int _v = 0; + int res = swig::asptr(argv[0], (std::vector< std::shared_ptr< ppc::protocol::INodeInfo >,std::allocator< std::shared_ptr< ppc::protocol::INodeInfo > > >**)(0)); + _v = SWIG_CheckState(res); + if (_v) { + swig::SwigPyIterator *iter = 0; + int res = SWIG_ConvertPtr(argv[1], SWIG_as_voidptrptr(&iter), swig::SwigPyIterator::descriptor(), 0); + _v = (SWIG_IsOK(res) && iter && (dynamic_cast >::iterator > *>(iter) != 0)); + if (_v) { + return _wrap_NodeInfoVec_erase__SWIG_0(self, argc, argv); + } + } + } + if (argc == 3) { + int _v = 0; + int res = swig::asptr(argv[0], (std::vector< std::shared_ptr< ppc::protocol::INodeInfo >,std::allocator< std::shared_ptr< ppc::protocol::INodeInfo > > >**)(0)); + _v = SWIG_CheckState(res); + if (_v) { + swig::SwigPyIterator *iter = 0; + int res = SWIG_ConvertPtr(argv[1], SWIG_as_voidptrptr(&iter), swig::SwigPyIterator::descriptor(), 0); + _v = (SWIG_IsOK(res) && iter && (dynamic_cast >::iterator > *>(iter) != 0)); + if (_v) { + swig::SwigPyIterator *iter = 0; + int res = SWIG_ConvertPtr(argv[2], SWIG_as_voidptrptr(&iter), swig::SwigPyIterator::descriptor(), 0); + _v = (SWIG_IsOK(res) && iter && (dynamic_cast >::iterator > *>(iter) != 0)); + if (_v) { + return _wrap_NodeInfoVec_erase__SWIG_1(self, argc, argv); + } + } + } + } + +fail: + SWIG_Python_RaiseOrModifyTypeError("Wrong number or type of arguments for overloaded function 'NodeInfoVec_erase'.\n" + " Possible C/C++ prototypes are:\n" + " std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::erase(std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::iterator)\n" + " std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::erase(std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::iterator,std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::iterator)\n"); + return 0; +} + + +SWIGINTERN PyObject *_wrap_new_NodeInfoVec__SWIG_3(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::size_type arg1 ; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type *arg2 = 0 ; + size_t val1 ; + int ecode1 = 0 ; + void *argp2 ; + int res2 = 0 ; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type tempshared2 ; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *result = 0 ; + + (void)self; + if ((nobjs < 2) || (nobjs > 2)) SWIG_fail; + ecode1 = SWIG_AsVal_size_t(swig_obj[0], &val1); + if (!SWIG_IsOK(ecode1)) { + SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "new_NodeInfoVec" "', argument " "1"" of type '" "std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::size_type""'"); + } + arg1 = static_cast< std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::size_type >(val1); + { + int newmem = 0; + res2 = SWIG_ConvertPtrAndOwn(swig_obj[1], &argp2, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__INodeInfo_t, 0 , &newmem); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "new_NodeInfoVec" "', argument " "2"" of type '" "std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type const &""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + if (argp2) tempshared2 = *reinterpret_cast< std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type * >(argp2); + delete reinterpret_cast< std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type * >(argp2); + arg2 = &tempshared2; + } else { + arg2 = (argp2) ? reinterpret_cast< std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type * >(argp2) : &tempshared2; + } + } + result = (std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *)new std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >(arg1,(std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type const &)*arg2); + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorT_std__shared_ptrT_ppc__protocol__INodeInfo_t_t, SWIG_POINTER_NEW | 0 ); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_new_NodeInfoVec(PyObject *self, PyObject *args) { + Py_ssize_t argc; + PyObject *argv[3] = { + 0 + }; + + if (!(argc = SWIG_Python_UnpackTuple(args, "new_NodeInfoVec", 0, 2, argv))) SWIG_fail; + --argc; + if (argc == 0) { + return _wrap_new_NodeInfoVec__SWIG_0(self, argc, argv); + } + if (argc == 1) { + int _v = 0; + { + int res = SWIG_AsVal_size_t(argv[0], NULL); + _v = SWIG_CheckState(res); + } + if (_v) { + return _wrap_new_NodeInfoVec__SWIG_2(self, argc, argv); + } + } + if (argc == 1) { + int _v = 0; + int res = swig::asptr(argv[0], (std::vector< std::shared_ptr< ppc::protocol::INodeInfo >,std::allocator< std::shared_ptr< ppc::protocol::INodeInfo > > >**)(0)); + _v = SWIG_CheckState(res); + if (_v) { + return _wrap_new_NodeInfoVec__SWIG_1(self, argc, argv); + } + } + if (argc == 2) { + int _v = 0; + { + int res = SWIG_AsVal_size_t(argv[0], NULL); + _v = SWIG_CheckState(res); + } + if (_v) { + int res = SWIG_ConvertPtr(argv[1], 0, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__INodeInfo_t, 0); + _v = SWIG_CheckState(res); + if (_v) { + return _wrap_new_NodeInfoVec__SWIG_3(self, argc, argv); + } + } + } + +fail: + SWIG_Python_RaiseOrModifyTypeError("Wrong number or type of arguments for overloaded function 'new_NodeInfoVec'.\n" + " Possible C/C++ prototypes are:\n" + " std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::vector()\n" + " std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::vector(std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > const &)\n" + " std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::vector(std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::size_type)\n" + " std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::vector(std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::size_type,std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type const &)\n"); + return 0; +} + + +SWIGINTERN PyObject *_wrap_NodeInfoVec_push_back(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *arg1 = (std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *) 0 ; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type *arg2 = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + void *argp2 ; + int res2 = 0 ; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type tempshared2 ; + PyObject *swig_obj[2] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "NodeInfoVec_push_back", 2, 2, swig_obj)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_std__shared_ptrT_ppc__protocol__INodeInfo_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "NodeInfoVec_push_back" "', argument " "1"" of type '" "std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *""'"); + } + arg1 = reinterpret_cast< std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > * >(argp1); + { + int newmem = 0; + res2 = SWIG_ConvertPtrAndOwn(swig_obj[1], &argp2, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__INodeInfo_t, 0 , &newmem); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "NodeInfoVec_push_back" "', argument " "2"" of type '" "std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type const &""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + if (argp2) tempshared2 = *reinterpret_cast< std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type * >(argp2); + delete reinterpret_cast< std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type * >(argp2); + arg2 = &tempshared2; + } else { + arg2 = (argp2) ? reinterpret_cast< std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type * >(argp2) : &tempshared2; + } + } + (arg1)->push_back((std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type const &)*arg2); + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_NodeInfoVec_front(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *arg1 = (std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type *result = 0 ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_std__shared_ptrT_ppc__protocol__INodeInfo_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "NodeInfoVec_front" "', argument " "1"" of type '" "std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > const *""'"); + } + arg1 = reinterpret_cast< std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > * >(argp1); + result = (std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type *) &((std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > const *)arg1)->front(); + { + std::shared_ptr< ppc::protocol::INodeInfo > *smartresult = *result ? new std::shared_ptr< ppc::protocol::INodeInfo >(*result) : 0; + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(smartresult), SWIGTYPE_p_std__shared_ptrT_ppc__protocol__INodeInfo_t, SWIG_POINTER_OWN); + } + (void)swig::container_owner >::value_type>::category>::back_reference(resultobj, swig_obj[0]); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_NodeInfoVec_back(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *arg1 = (std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type *result = 0 ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_std__shared_ptrT_ppc__protocol__INodeInfo_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "NodeInfoVec_back" "', argument " "1"" of type '" "std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > const *""'"); + } + arg1 = reinterpret_cast< std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > * >(argp1); + result = (std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type *) &((std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > const *)arg1)->back(); + { + std::shared_ptr< ppc::protocol::INodeInfo > *smartresult = *result ? new std::shared_ptr< ppc::protocol::INodeInfo >(*result) : 0; + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(smartresult), SWIGTYPE_p_std__shared_ptrT_ppc__protocol__INodeInfo_t, SWIG_POINTER_OWN); + } + (void)swig::container_owner >::value_type>::category>::back_reference(resultobj, swig_obj[0]); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_NodeInfoVec_assign(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *arg1 = (std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *) 0 ; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::size_type arg2 ; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type *arg3 = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + size_t val2 ; + int ecode2 = 0 ; + void *argp3 ; + int res3 = 0 ; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type tempshared3 ; + PyObject *swig_obj[3] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "NodeInfoVec_assign", 3, 3, swig_obj)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_std__shared_ptrT_ppc__protocol__INodeInfo_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "NodeInfoVec_assign" "', argument " "1"" of type '" "std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *""'"); + } + arg1 = reinterpret_cast< std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > * >(argp1); + ecode2 = SWIG_AsVal_size_t(swig_obj[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "NodeInfoVec_assign" "', argument " "2"" of type '" "std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::size_type""'"); + } + arg2 = static_cast< std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::size_type >(val2); + { + int newmem = 0; + res3 = SWIG_ConvertPtrAndOwn(swig_obj[2], &argp3, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__INodeInfo_t, 0 , &newmem); + if (!SWIG_IsOK(res3)) { + SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "NodeInfoVec_assign" "', argument " "3"" of type '" "std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type const &""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + if (argp3) tempshared3 = *reinterpret_cast< std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type * >(argp3); + delete reinterpret_cast< std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type * >(argp3); + arg3 = &tempshared3; + } else { + arg3 = (argp3) ? reinterpret_cast< std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type * >(argp3) : &tempshared3; + } + } + (arg1)->assign(arg2,(std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type const &)*arg3); + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_NodeInfoVec_resize__SWIG_1(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *arg1 = (std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *) 0 ; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::size_type arg2 ; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type *arg3 = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + size_t val2 ; + int ecode2 = 0 ; + void *argp3 ; + int res3 = 0 ; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type tempshared3 ; + + (void)self; + if ((nobjs < 3) || (nobjs > 3)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_std__shared_ptrT_ppc__protocol__INodeInfo_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "NodeInfoVec_resize" "', argument " "1"" of type '" "std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *""'"); + } + arg1 = reinterpret_cast< std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > * >(argp1); + ecode2 = SWIG_AsVal_size_t(swig_obj[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "NodeInfoVec_resize" "', argument " "2"" of type '" "std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::size_type""'"); + } + arg2 = static_cast< std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::size_type >(val2); + { + int newmem = 0; + res3 = SWIG_ConvertPtrAndOwn(swig_obj[2], &argp3, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__INodeInfo_t, 0 , &newmem); + if (!SWIG_IsOK(res3)) { + SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "NodeInfoVec_resize" "', argument " "3"" of type '" "std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type const &""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + if (argp3) tempshared3 = *reinterpret_cast< std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type * >(argp3); + delete reinterpret_cast< std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type * >(argp3); + arg3 = &tempshared3; + } else { + arg3 = (argp3) ? reinterpret_cast< std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type * >(argp3) : &tempshared3; + } + } + (arg1)->resize(arg2,(std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type const &)*arg3); + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_NodeInfoVec_resize(PyObject *self, PyObject *args) { + Py_ssize_t argc; + PyObject *argv[4] = { + 0 + }; + + if (!(argc = SWIG_Python_UnpackTuple(args, "NodeInfoVec_resize", 0, 3, argv))) SWIG_fail; + --argc; + if (argc == 2) { + int _v = 0; + int res = swig::asptr(argv[0], (std::vector< std::shared_ptr< ppc::protocol::INodeInfo >,std::allocator< std::shared_ptr< ppc::protocol::INodeInfo > > >**)(0)); + _v = SWIG_CheckState(res); + if (_v) { + { + int res = SWIG_AsVal_size_t(argv[1], NULL); + _v = SWIG_CheckState(res); + } + if (_v) { + return _wrap_NodeInfoVec_resize__SWIG_0(self, argc, argv); + } + } + } + if (argc == 3) { + int _v = 0; + int res = swig::asptr(argv[0], (std::vector< std::shared_ptr< ppc::protocol::INodeInfo >,std::allocator< std::shared_ptr< ppc::protocol::INodeInfo > > >**)(0)); + _v = SWIG_CheckState(res); + if (_v) { + { + int res = SWIG_AsVal_size_t(argv[1], NULL); + _v = SWIG_CheckState(res); + } + if (_v) { + int res = SWIG_ConvertPtr(argv[2], 0, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__INodeInfo_t, 0); + _v = SWIG_CheckState(res); + if (_v) { + return _wrap_NodeInfoVec_resize__SWIG_1(self, argc, argv); + } + } + } + } + +fail: + SWIG_Python_RaiseOrModifyTypeError("Wrong number or type of arguments for overloaded function 'NodeInfoVec_resize'.\n" + " Possible C/C++ prototypes are:\n" + " std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::resize(std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::size_type)\n" + " std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::resize(std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::size_type,std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type const &)\n"); + return 0; +} + + +SWIGINTERN PyObject *_wrap_NodeInfoVec_insert__SWIG_0(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *arg1 = (std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *) 0 ; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::iterator arg2 ; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type *arg3 = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + swig::SwigPyIterator *iter2 = 0 ; + int res2 ; + void *argp3 ; + int res3 = 0 ; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type tempshared3 ; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::iterator result; + + (void)self; + if ((nobjs < 3) || (nobjs > 3)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_std__shared_ptrT_ppc__protocol__INodeInfo_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "NodeInfoVec_insert" "', argument " "1"" of type '" "std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *""'"); + } + arg1 = reinterpret_cast< std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > * >(argp1); + res2 = SWIG_ConvertPtr(swig_obj[1], SWIG_as_voidptrptr(&iter2), swig::SwigPyIterator::descriptor(), 0); + if (!SWIG_IsOK(res2) || !iter2) { + SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "NodeInfoVec_insert" "', argument " "2"" of type '" "std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::iterator""'"); + } else { + swig::SwigPyIterator_T >::iterator > *iter_t = dynamic_cast >::iterator > *>(iter2); + if (iter_t) { + arg2 = iter_t->get_current(); + } else { + SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "NodeInfoVec_insert" "', argument " "2"" of type '" "std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::iterator""'"); + } + } + { + int newmem = 0; + res3 = SWIG_ConvertPtrAndOwn(swig_obj[2], &argp3, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__INodeInfo_t, 0 , &newmem); + if (!SWIG_IsOK(res3)) { + SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "NodeInfoVec_insert" "', argument " "3"" of type '" "std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type const &""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + if (argp3) tempshared3 = *reinterpret_cast< std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type * >(argp3); + delete reinterpret_cast< std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type * >(argp3); + arg3 = &tempshared3; + } else { + arg3 = (argp3) ? reinterpret_cast< std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type * >(argp3) : &tempshared3; + } + } + result = std_vector_Sl_std_shared_ptr_Sl_ppc_protocol_INodeInfo_Sg__Sg__insert__SWIG_0(arg1,SWIG_STD_MOVE(arg2),(std::shared_ptr< ppc::protocol::INodeInfo > const &)*arg3); + resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::iterator & >(result)), + swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_NodeInfoVec_insert__SWIG_1(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *arg1 = (std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *) 0 ; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::iterator arg2 ; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::size_type arg3 ; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type *arg4 = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + swig::SwigPyIterator *iter2 = 0 ; + int res2 ; + size_t val3 ; + int ecode3 = 0 ; + void *argp4 ; + int res4 = 0 ; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type tempshared4 ; + + (void)self; + if ((nobjs < 4) || (nobjs > 4)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_std__shared_ptrT_ppc__protocol__INodeInfo_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "NodeInfoVec_insert" "', argument " "1"" of type '" "std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *""'"); + } + arg1 = reinterpret_cast< std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > * >(argp1); + res2 = SWIG_ConvertPtr(swig_obj[1], SWIG_as_voidptrptr(&iter2), swig::SwigPyIterator::descriptor(), 0); + if (!SWIG_IsOK(res2) || !iter2) { + SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "NodeInfoVec_insert" "', argument " "2"" of type '" "std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::iterator""'"); + } else { + swig::SwigPyIterator_T >::iterator > *iter_t = dynamic_cast >::iterator > *>(iter2); + if (iter_t) { + arg2 = iter_t->get_current(); + } else { + SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "NodeInfoVec_insert" "', argument " "2"" of type '" "std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::iterator""'"); + } + } + ecode3 = SWIG_AsVal_size_t(swig_obj[2], &val3); + if (!SWIG_IsOK(ecode3)) { + SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "NodeInfoVec_insert" "', argument " "3"" of type '" "std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::size_type""'"); + } + arg3 = static_cast< std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::size_type >(val3); + { + int newmem = 0; + res4 = SWIG_ConvertPtrAndOwn(swig_obj[3], &argp4, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__INodeInfo_t, 0 , &newmem); + if (!SWIG_IsOK(res4)) { + SWIG_exception_fail(SWIG_ArgError(res4), "in method '" "NodeInfoVec_insert" "', argument " "4"" of type '" "std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type const &""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + if (argp4) tempshared4 = *reinterpret_cast< std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type * >(argp4); + delete reinterpret_cast< std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type * >(argp4); + arg4 = &tempshared4; + } else { + arg4 = (argp4) ? reinterpret_cast< std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type * >(argp4) : &tempshared4; + } + } + std_vector_Sl_std_shared_ptr_Sl_ppc_protocol_INodeInfo_Sg__Sg__insert__SWIG_1(arg1,SWIG_STD_MOVE(arg2),SWIG_STD_MOVE(arg3),(std::shared_ptr< ppc::protocol::INodeInfo > const &)*arg4); + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_NodeInfoVec_insert(PyObject *self, PyObject *args) { + Py_ssize_t argc; + PyObject *argv[5] = { + 0 + }; + + if (!(argc = SWIG_Python_UnpackTuple(args, "NodeInfoVec_insert", 0, 4, argv))) SWIG_fail; + --argc; + if (argc == 3) { + int _v = 0; + int res = swig::asptr(argv[0], (std::vector< std::shared_ptr< ppc::protocol::INodeInfo >,std::allocator< std::shared_ptr< ppc::protocol::INodeInfo > > >**)(0)); + _v = SWIG_CheckState(res); + if (_v) { + swig::SwigPyIterator *iter = 0; + int res = SWIG_ConvertPtr(argv[1], SWIG_as_voidptrptr(&iter), swig::SwigPyIterator::descriptor(), 0); + _v = (SWIG_IsOK(res) && iter && (dynamic_cast >::iterator > *>(iter) != 0)); + if (_v) { + int res = SWIG_ConvertPtr(argv[2], 0, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__INodeInfo_t, 0); + _v = SWIG_CheckState(res); + if (_v) { + return _wrap_NodeInfoVec_insert__SWIG_0(self, argc, argv); + } + } + } + } + if (argc == 4) { + int _v = 0; + int res = swig::asptr(argv[0], (std::vector< std::shared_ptr< ppc::protocol::INodeInfo >,std::allocator< std::shared_ptr< ppc::protocol::INodeInfo > > >**)(0)); + _v = SWIG_CheckState(res); + if (_v) { + swig::SwigPyIterator *iter = 0; + int res = SWIG_ConvertPtr(argv[1], SWIG_as_voidptrptr(&iter), swig::SwigPyIterator::descriptor(), 0); + _v = (SWIG_IsOK(res) && iter && (dynamic_cast >::iterator > *>(iter) != 0)); + if (_v) { + { + int res = SWIG_AsVal_size_t(argv[2], NULL); + _v = SWIG_CheckState(res); + } + if (_v) { + int res = SWIG_ConvertPtr(argv[3], 0, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__INodeInfo_t, 0); + _v = SWIG_CheckState(res); + if (_v) { + return _wrap_NodeInfoVec_insert__SWIG_1(self, argc, argv); + } + } + } + } + } + +fail: + SWIG_Python_RaiseOrModifyTypeError("Wrong number or type of arguments for overloaded function 'NodeInfoVec_insert'.\n" + " Possible C/C++ prototypes are:\n" + " std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::insert(std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::iterator,std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type const &)\n" + " std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::insert(std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::iterator,std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::size_type,std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::value_type const &)\n"); + return 0; +} + + +SWIGINTERN PyObject *_wrap_NodeInfoVec_reserve(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *arg1 = (std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *) 0 ; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::size_type arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + size_t val2 ; + int ecode2 = 0 ; + PyObject *swig_obj[2] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "NodeInfoVec_reserve", 2, 2, swig_obj)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_std__shared_ptrT_ppc__protocol__INodeInfo_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "NodeInfoVec_reserve" "', argument " "1"" of type '" "std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *""'"); + } + arg1 = reinterpret_cast< std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > * >(argp1); + ecode2 = SWIG_AsVal_size_t(swig_obj[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "NodeInfoVec_reserve" "', argument " "2"" of type '" "std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::size_type""'"); + } + arg2 = static_cast< std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::size_type >(val2); + (arg1)->reserve(arg2); + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_NodeInfoVec_capacity(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *arg1 = (std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::size_type result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_std__shared_ptrT_ppc__protocol__INodeInfo_t_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "NodeInfoVec_capacity" "', argument " "1"" of type '" "std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > const *""'"); + } + arg1 = reinterpret_cast< std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > * >(argp1); + result = ((std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > const *)arg1)->capacity(); + resultobj = SWIG_From_size_t(static_cast< size_t >(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_delete_NodeInfoVec(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *arg1 = (std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_std__shared_ptrT_ppc__protocol__INodeInfo_t_t, SWIG_POINTER_DISOWN | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_NodeInfoVec" "', argument " "1"" of type '" "std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *""'"); + } + arg1 = reinterpret_cast< std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > * >(argp1); + { + try { + delete arg1; + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *NodeInfoVec_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *obj; + if (!SWIG_Python_UnpackTuple(args, "swigregister", 1, 1, &obj)) return NULL; + SWIG_TypeNewClientData(SWIGTYPE_p_std__vectorT_std__shared_ptrT_ppc__protocol__INodeInfo_t_t, SWIG_NewClientData(obj)); + return SWIG_Py_Void(); +} + +SWIGINTERN PyObject *NodeInfoVec_swiginit(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + return SWIG_Python_InitShadowInstance(args); +} + +SWIGINTERN PyObject *_wrap_Error_buildError__SWIG_0(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + char *arg1 = (char *) 0 ; + char *arg2 = (char *) 0 ; + int arg3 ; + int32_t arg4 ; + std::string *arg5 = 0 ; + int res1 ; + char *buf1 = 0 ; + int alloc1 = 0 ; + int res2 ; + char *buf2 = 0 ; + int alloc2 = 0 ; + int val3 ; + int ecode3 = 0 ; + int val4 ; + int ecode4 = 0 ; + int res5 = SWIG_OLDOBJ ; + bcos::Error result; + + (void)self; + if ((nobjs < 5) || (nobjs > 5)) SWIG_fail; + res1 = SWIG_AsCharPtrAndSize(swig_obj[0], &buf1, NULL, &alloc1); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Error_buildError" "', argument " "1"" of type '" "char const *""'"); + } + arg1 = reinterpret_cast< char * >(buf1); + res2 = SWIG_AsCharPtrAndSize(swig_obj[1], &buf2, NULL, &alloc2); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Error_buildError" "', argument " "2"" of type '" "char const *""'"); + } + arg2 = reinterpret_cast< char * >(buf2); + ecode3 = SWIG_AsVal_int(swig_obj[2], &val3); + if (!SWIG_IsOK(ecode3)) { + SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "Error_buildError" "', argument " "3"" of type '" "int""'"); + } + arg3 = static_cast< int >(val3); + ecode4 = SWIG_AsVal_int(swig_obj[3], &val4); + if (!SWIG_IsOK(ecode4)) { + SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "Error_buildError" "', argument " "4"" of type '" "int32_t""'"); + } + arg4 = static_cast< int32_t >(val4); + { + std::string *ptr = (std::string *)0; + res5 = SWIG_AsPtr_std_string(swig_obj[4], &ptr); + if (!SWIG_IsOK(res5)) { + SWIG_exception_fail(SWIG_ArgError(res5), "in method '" "Error_buildError" "', argument " "5"" of type '" "std::string const &""'"); + } + if (!ptr) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "Error_buildError" "', argument " "5"" of type '" "std::string const &""'"); + } + arg5 = ptr; + } + { + try { + result = bcos::Error::buildError((char const *)arg1,(char const *)arg2,arg3,arg4,(std::string const &)*arg5); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + { + std::shared_ptr< bcos::Error > *smartresult = new std::shared_ptr< bcos::Error >(new bcos::Error(result)); + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(smartresult), SWIGTYPE_p_std__shared_ptrT_bcos__Error_t, SWIG_POINTER_OWN); + } + if (alloc1 == SWIG_NEWOBJ) delete[] buf1; + if (alloc2 == SWIG_NEWOBJ) delete[] buf2; + if (SWIG_IsNewObj(res5)) delete arg5; + return resultobj; +fail: + if (alloc1 == SWIG_NEWOBJ) delete[] buf1; + if (alloc2 == SWIG_NEWOBJ) delete[] buf2; + if (SWIG_IsNewObj(res5)) delete arg5; + return NULL; +} + + +SWIGINTERN PyObject *_wrap_Error_buildError__SWIG_1(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + char *arg1 = (char *) 0 ; + char *arg2 = (char *) 0 ; + int arg3 ; + int32_t arg4 ; + std::string *arg5 = 0 ; + bcos::Error *arg6 = 0 ; + int res1 ; + char *buf1 = 0 ; + int alloc1 = 0 ; + int res2 ; + char *buf2 = 0 ; + int alloc2 = 0 ; + int val3 ; + int ecode3 = 0 ; + int val4 ; + int ecode4 = 0 ; + int res5 = SWIG_OLDOBJ ; + void *argp6 = 0 ; + int res6 = 0 ; + std::shared_ptr< bcos::Error const > tempshared6 ; + bcos::Error result; + + (void)self; + if ((nobjs < 6) || (nobjs > 6)) SWIG_fail; + res1 = SWIG_AsCharPtrAndSize(swig_obj[0], &buf1, NULL, &alloc1); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Error_buildError" "', argument " "1"" of type '" "char const *""'"); + } + arg1 = reinterpret_cast< char * >(buf1); + res2 = SWIG_AsCharPtrAndSize(swig_obj[1], &buf2, NULL, &alloc2); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Error_buildError" "', argument " "2"" of type '" "char const *""'"); + } + arg2 = reinterpret_cast< char * >(buf2); + ecode3 = SWIG_AsVal_int(swig_obj[2], &val3); + if (!SWIG_IsOK(ecode3)) { + SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "Error_buildError" "', argument " "3"" of type '" "int""'"); + } + arg3 = static_cast< int >(val3); + ecode4 = SWIG_AsVal_int(swig_obj[3], &val4); + if (!SWIG_IsOK(ecode4)) { + SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "Error_buildError" "', argument " "4"" of type '" "int32_t""'"); + } + arg4 = static_cast< int32_t >(val4); + { + std::string *ptr = (std::string *)0; + res5 = SWIG_AsPtr_std_string(swig_obj[4], &ptr); + if (!SWIG_IsOK(res5)) { + SWIG_exception_fail(SWIG_ArgError(res5), "in method '" "Error_buildError" "', argument " "5"" of type '" "std::string const &""'"); + } + if (!ptr) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "Error_buildError" "', argument " "5"" of type '" "std::string const &""'"); + } + arg5 = ptr; + } + { + int newmem = 0; + res6 = SWIG_ConvertPtrAndOwn(swig_obj[5], &argp6, SWIGTYPE_p_std__shared_ptrT_bcos__Error_t, 0 , &newmem); + if (!SWIG_IsOK(res6)) { + SWIG_exception_fail(SWIG_ArgError(res6), "in method '" "Error_buildError" "', argument " "6"" of type '" "bcos::Error const &""'"); + } + if (!argp6) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "Error_buildError" "', argument " "6"" of type '" "bcos::Error const &""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared6 = *reinterpret_cast< std::shared_ptr< const bcos::Error > * >(argp6); + delete reinterpret_cast< std::shared_ptr< const bcos::Error > * >(argp6); + arg6 = const_cast< bcos::Error * >(tempshared6.get()); + } else { + arg6 = const_cast< bcos::Error * >(reinterpret_cast< std::shared_ptr< const bcos::Error > * >(argp6)->get()); + } + } + { + try { + result = bcos::Error::buildError((char const *)arg1,(char const *)arg2,arg3,arg4,(std::string const &)*arg5,(bcos::Error const &)*arg6); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + { + std::shared_ptr< bcos::Error > *smartresult = new std::shared_ptr< bcos::Error >(new bcos::Error(result)); + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(smartresult), SWIGTYPE_p_std__shared_ptrT_bcos__Error_t, SWIG_POINTER_OWN); + } + if (alloc1 == SWIG_NEWOBJ) delete[] buf1; + if (alloc2 == SWIG_NEWOBJ) delete[] buf2; + if (SWIG_IsNewObj(res5)) delete arg5; + return resultobj; +fail: + if (alloc1 == SWIG_NEWOBJ) delete[] buf1; + if (alloc2 == SWIG_NEWOBJ) delete[] buf2; + if (SWIG_IsNewObj(res5)) delete arg5; + return NULL; +} + + +SWIGINTERN PyObject *_wrap_Error_buildError__SWIG_2(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + char *arg1 = (char *) 0 ; + char *arg2 = (char *) 0 ; + int arg3 ; + int32_t arg4 ; + std::string *arg5 = 0 ; + std::exception *arg6 = 0 ; + int res1 ; + char *buf1 = 0 ; + int alloc1 = 0 ; + int res2 ; + char *buf2 = 0 ; + int alloc2 = 0 ; + int val3 ; + int ecode3 = 0 ; + int val4 ; + int ecode4 = 0 ; + int res5 = SWIG_OLDOBJ ; + void *argp6 = 0 ; + int res6 = 0 ; + bcos::Error result; + + (void)self; + if ((nobjs < 6) || (nobjs > 6)) SWIG_fail; + res1 = SWIG_AsCharPtrAndSize(swig_obj[0], &buf1, NULL, &alloc1); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Error_buildError" "', argument " "1"" of type '" "char const *""'"); + } + arg1 = reinterpret_cast< char * >(buf1); + res2 = SWIG_AsCharPtrAndSize(swig_obj[1], &buf2, NULL, &alloc2); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Error_buildError" "', argument " "2"" of type '" "char const *""'"); + } + arg2 = reinterpret_cast< char * >(buf2); + ecode3 = SWIG_AsVal_int(swig_obj[2], &val3); + if (!SWIG_IsOK(ecode3)) { + SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "Error_buildError" "', argument " "3"" of type '" "int""'"); + } + arg3 = static_cast< int >(val3); + ecode4 = SWIG_AsVal_int(swig_obj[3], &val4); + if (!SWIG_IsOK(ecode4)) { + SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "Error_buildError" "', argument " "4"" of type '" "int32_t""'"); + } + arg4 = static_cast< int32_t >(val4); + { + std::string *ptr = (std::string *)0; + res5 = SWIG_AsPtr_std_string(swig_obj[4], &ptr); + if (!SWIG_IsOK(res5)) { + SWIG_exception_fail(SWIG_ArgError(res5), "in method '" "Error_buildError" "', argument " "5"" of type '" "std::string const &""'"); + } + if (!ptr) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "Error_buildError" "', argument " "5"" of type '" "std::string const &""'"); + } + arg5 = ptr; + } + res6 = SWIG_ConvertPtr(swig_obj[5], &argp6, SWIGTYPE_p_std__exception, 0 | 0); + if (!SWIG_IsOK(res6)) { + SWIG_exception_fail(SWIG_ArgError(res6), "in method '" "Error_buildError" "', argument " "6"" of type '" "std::exception const &""'"); + } + if (!argp6) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "Error_buildError" "', argument " "6"" of type '" "std::exception const &""'"); + } + arg6 = reinterpret_cast< std::exception * >(argp6); + { + try { + result = bcos::Error::buildError((char const *)arg1,(char const *)arg2,arg3,arg4,(std::string const &)*arg5,(std::exception const &)*arg6); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + { + std::shared_ptr< bcos::Error > *smartresult = new std::shared_ptr< bcos::Error >(new bcos::Error(result)); + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(smartresult), SWIGTYPE_p_std__shared_ptrT_bcos__Error_t, SWIG_POINTER_OWN); + } + if (alloc1 == SWIG_NEWOBJ) delete[] buf1; + if (alloc2 == SWIG_NEWOBJ) delete[] buf2; + if (SWIG_IsNewObj(res5)) delete arg5; + return resultobj; +fail: + if (alloc1 == SWIG_NEWOBJ) delete[] buf1; + if (alloc2 == SWIG_NEWOBJ) delete[] buf2; + if (SWIG_IsNewObj(res5)) delete arg5; + return NULL; +} + + +SWIGINTERN PyObject *_wrap_Error_buildError(PyObject *self, PyObject *args) { + Py_ssize_t argc; + PyObject *argv[7] = { + 0 + }; + + if (!(argc = SWIG_Python_UnpackTuple(args, "Error_buildError", 0, 6, argv))) SWIG_fail; + --argc; + if (argc == 5) { + int _v = 0; + int res = SWIG_AsCharPtrAndSize(argv[0], 0, NULL, 0); + _v = SWIG_CheckState(res); + if (_v) { + int res = SWIG_AsCharPtrAndSize(argv[1], 0, NULL, 0); + _v = SWIG_CheckState(res); + if (_v) { + { + int res = SWIG_AsVal_int(argv[2], NULL); + _v = SWIG_CheckState(res); + } + if (_v) { + { + int res = SWIG_AsVal_int(argv[3], NULL); + _v = SWIG_CheckState(res); + } + if (_v) { + int res = SWIG_AsPtr_std_string(argv[4], (std::string**)(0)); + _v = SWIG_CheckState(res); + if (_v) { + return _wrap_Error_buildError__SWIG_0(self, argc, argv); + } + } + } + } + } + } + if (argc == 6) { + int _v = 0; + int res = SWIG_AsCharPtrAndSize(argv[0], 0, NULL, 0); + _v = SWIG_CheckState(res); + if (_v) { + int res = SWIG_AsCharPtrAndSize(argv[1], 0, NULL, 0); + _v = SWIG_CheckState(res); + if (_v) { + { + int res = SWIG_AsVal_int(argv[2], NULL); + _v = SWIG_CheckState(res); + } + if (_v) { + { + int res = SWIG_AsVal_int(argv[3], NULL); + _v = SWIG_CheckState(res); + } + if (_v) { + int res = SWIG_AsPtr_std_string(argv[4], (std::string**)(0)); + _v = SWIG_CheckState(res); + if (_v) { + int res = SWIG_ConvertPtr(argv[5], 0, SWIGTYPE_p_std__shared_ptrT_bcos__Error_t, 0); + _v = SWIG_CheckState(res); + if (_v) { + return _wrap_Error_buildError__SWIG_1(self, argc, argv); + } + } + } + } + } + } + } + if (argc == 6) { + int _v = 0; + int res = SWIG_AsCharPtrAndSize(argv[0], 0, NULL, 0); + _v = SWIG_CheckState(res); + if (_v) { + int res = SWIG_AsCharPtrAndSize(argv[1], 0, NULL, 0); + _v = SWIG_CheckState(res); + if (_v) { + { + int res = SWIG_AsVal_int(argv[2], NULL); + _v = SWIG_CheckState(res); + } + if (_v) { + { + int res = SWIG_AsVal_int(argv[3], NULL); + _v = SWIG_CheckState(res); + } + if (_v) { + int res = SWIG_AsPtr_std_string(argv[4], (std::string**)(0)); + _v = SWIG_CheckState(res); + if (_v) { + int res = SWIG_ConvertPtr(argv[5], 0, SWIGTYPE_p_std__exception, SWIG_POINTER_NO_NULL | 0); + _v = SWIG_CheckState(res); + if (_v) { + return _wrap_Error_buildError__SWIG_2(self, argc, argv); + } + } + } + } + } + } + } + +fail: + SWIG_Python_RaiseOrModifyTypeError("Wrong number or type of arguments for overloaded function 'Error_buildError'.\n" + " Possible C/C++ prototypes are:\n" + " bcos::Error::buildError(char const *,char const *,int,int32_t,std::string const &)\n" + " bcos::Error::buildError(char const *,char const *,int,int32_t,std::string const &,bcos::Error const &)\n" + " bcos::Error::buildError(char const *,char const *,int,int32_t,std::string const &,std::exception const &)\n"); + return 0; +} + + +SWIGINTERN PyObject *_wrap_new_Error__SWIG_0(PyObject *self, Py_ssize_t nobjs, PyObject **SWIGUNUSEDPARM(swig_obj)) { + PyObject *resultobj = 0; + bcos::Error *result = 0 ; + + (void)self; + if ((nobjs < 0) || (nobjs > 0)) SWIG_fail; + { + try { + result = (bcos::Error *)new bcos::Error(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + { + std::shared_ptr< bcos::Error > *smartresult = result ? new std::shared_ptr< bcos::Error >(result SWIG_NO_NULL_DELETER_SWIG_POINTER_NEW) : 0; + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(smartresult), SWIGTYPE_p_std__shared_ptrT_bcos__Error_t, SWIG_POINTER_NEW | SWIG_POINTER_OWN); + } + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_new_Error__SWIG_1(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + int64_t arg1 ; + std::string arg2 ; + long long val1 ; + int ecode1 = 0 ; + bcos::Error *result = 0 ; + + (void)self; + if ((nobjs < 2) || (nobjs > 2)) SWIG_fail; + ecode1 = SWIG_AsVal_long_SS_long(swig_obj[0], &val1); + if (!SWIG_IsOK(ecode1)) { + SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "new_Error" "', argument " "1"" of type '" "int64_t""'"); + } + arg1 = static_cast< int64_t >(val1); + { + std::string *ptr = (std::string *)0; + int res = SWIG_AsPtr_std_string(swig_obj[1], &ptr); + if (!SWIG_IsOK(res) || !ptr) { + SWIG_exception_fail(SWIG_ArgError((ptr ? res : SWIG_TypeError)), "in method '" "new_Error" "', argument " "2"" of type '" "std::string""'"); + } + arg2 = *ptr; + if (SWIG_IsNewObj(res)) delete ptr; + } + { + try { + result = (bcos::Error *)new bcos::Error(arg1,arg2); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + { + std::shared_ptr< bcos::Error > *smartresult = result ? new std::shared_ptr< bcos::Error >(result SWIG_NO_NULL_DELETER_SWIG_POINTER_NEW) : 0; + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(smartresult), SWIGTYPE_p_std__shared_ptrT_bcos__Error_t, SWIG_POINTER_NEW | SWIG_POINTER_OWN); + } + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_new_Error(PyObject *self, PyObject *args) { + Py_ssize_t argc; + PyObject *argv[3] = { + 0 + }; + + if (!(argc = SWIG_Python_UnpackTuple(args, "new_Error", 0, 2, argv))) SWIG_fail; + --argc; + if (argc == 0) { + return _wrap_new_Error__SWIG_0(self, argc, argv); + } + if (argc == 2) { + int _v = 0; + { + int res = SWIG_AsVal_long_SS_long(argv[0], NULL); + _v = SWIG_CheckState(res); + } + if (_v) { + int res = SWIG_AsPtr_std_string(argv[1], (std::string**)(0)); + _v = SWIG_CheckState(res); + if (_v) { + return _wrap_new_Error__SWIG_1(self, argc, argv); + } + } + } + +fail: + SWIG_Python_RaiseOrModifyTypeError("Wrong number or type of arguments for overloaded function 'new_Error'.\n" + " Possible C/C++ prototypes are:\n" + " bcos::Error::Error()\n" + " bcos::Error::Error(int64_t,std::string)\n"); + return 0; +} + + +SWIGINTERN PyObject *_wrap_delete_Error(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + bcos::Error *arg1 = (bcos::Error *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< bcos::Error > tempshared1 ; + std::shared_ptr< bcos::Error > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_bcos__Error_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_Error" "', argument " "1"" of type '" "bcos::Error *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< bcos::Error > * >(argp1); + delete reinterpret_cast< std::shared_ptr< bcos::Error > * >(argp1); + arg1 = const_cast< bcos::Error * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< bcos::Error > * >(argp1); + arg1 = const_cast< bcos::Error * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + (void)arg1; delete smartarg1; + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_Error_errorCode(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + bcos::Error *arg1 = (bcos::Error *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< bcos::Error const > tempshared1 ; + std::shared_ptr< bcos::Error const > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + int64_t result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_bcos__Error_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Error_errorCode" "', argument " "1"" of type '" "bcos::Error const *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< const bcos::Error > * >(argp1); + delete reinterpret_cast< std::shared_ptr< const bcos::Error > * >(argp1); + arg1 = const_cast< bcos::Error * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< const bcos::Error > * >(argp1); + arg1 = const_cast< bcos::Error * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + result = (int64_t)((bcos::Error const *)arg1)->errorCode(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_From_long_SS_long(static_cast< long long >(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_Error_errorMessage(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + bcos::Error *arg1 = (bcos::Error *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< bcos::Error const > tempshared1 ; + std::shared_ptr< bcos::Error const > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + std::string *result = 0 ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_bcos__Error_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Error_errorMessage" "', argument " "1"" of type '" "bcos::Error const *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< const bcos::Error > * >(argp1); + delete reinterpret_cast< std::shared_ptr< const bcos::Error > * >(argp1); + arg1 = const_cast< bcos::Error * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< const bcos::Error > * >(argp1); + arg1 = const_cast< bcos::Error * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + result = (std::string *) &((bcos::Error const *)arg1)->errorMessage(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_From_std_string(static_cast< std::string >(*result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_Error_setErrorCode(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + bcos::Error *arg1 = (bcos::Error *) 0 ; + int64_t arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< bcos::Error > tempshared1 ; + std::shared_ptr< bcos::Error > *smartarg1 = 0 ; + long long val2 ; + int ecode2 = 0 ; + PyObject *swig_obj[2] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "Error_setErrorCode", 2, 2, swig_obj)) SWIG_fail; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_bcos__Error_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Error_setErrorCode" "', argument " "1"" of type '" "bcos::Error *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< bcos::Error > * >(argp1); + delete reinterpret_cast< std::shared_ptr< bcos::Error > * >(argp1); + arg1 = const_cast< bcos::Error * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< bcos::Error > * >(argp1); + arg1 = const_cast< bcos::Error * >((smartarg1 ? smartarg1->get() : 0)); + } + } + ecode2 = SWIG_AsVal_long_SS_long(swig_obj[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "Error_setErrorCode" "', argument " "2"" of type '" "int64_t""'"); + } + arg2 = static_cast< int64_t >(val2); + { + try { + (arg1)->setErrorCode(arg2); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_Error_setErrorMessage(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + bcos::Error *arg1 = (bcos::Error *) 0 ; + std::string *arg2 = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< bcos::Error > tempshared1 ; + std::shared_ptr< bcos::Error > *smartarg1 = 0 ; + int res2 = SWIG_OLDOBJ ; + PyObject *swig_obj[2] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "Error_setErrorMessage", 2, 2, swig_obj)) SWIG_fail; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_bcos__Error_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Error_setErrorMessage" "', argument " "1"" of type '" "bcos::Error *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< bcos::Error > * >(argp1); + delete reinterpret_cast< std::shared_ptr< bcos::Error > * >(argp1); + arg1 = const_cast< bcos::Error * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< bcos::Error > * >(argp1); + arg1 = const_cast< bcos::Error * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + std::string *ptr = (std::string *)0; + res2 = SWIG_AsPtr_std_string(swig_obj[1], &ptr); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Error_setErrorMessage" "', argument " "2"" of type '" "std::string const &""'"); + } + if (!ptr) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "Error_setErrorMessage" "', argument " "2"" of type '" "std::string const &""'"); + } + arg2 = ptr; + } + { + try { + (arg1)->setErrorMessage((std::string const &)*arg2); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + if (SWIG_IsNewObj(res2)) delete arg2; + return resultobj; +fail: + if (SWIG_IsNewObj(res2)) delete arg2; + return NULL; +} + + +SWIGINTERN PyObject *Error_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *obj; + if (!SWIG_Python_UnpackTuple(args, "swigregister", 1, 1, &obj)) return NULL; + SWIG_TypeNewClientData(SWIGTYPE_p_std__shared_ptrT_bcos__Error_t, SWIG_NewClientData(obj)); + return SWIG_Py_Void(); +} + +SWIGINTERN PyObject *Error_swiginit(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + return SWIG_Python_InitShadowInstance(args); +} + +SWIGINTERN PyObject *_wrap_InputBuffer_data_set(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + InputBuffer *arg1 = (InputBuffer *) 0 ; + unsigned char *arg2 = (unsigned char *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + void *argp2 = 0 ; + int res2 = 0 ; + PyObject *swig_obj[2] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "InputBuffer_data_set", 2, 2, swig_obj)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_InputBuffer, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InputBuffer_data_set" "', argument " "1"" of type '" "InputBuffer *""'"); + } + arg1 = reinterpret_cast< InputBuffer * >(argp1); + res2 = SWIG_ConvertPtr(swig_obj[1], &argp2,SWIGTYPE_p_unsigned_char, SWIG_POINTER_DISOWN | 0 ); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "InputBuffer_data_set" "', argument " "2"" of type '" "unsigned char const *""'"); + } + arg2 = reinterpret_cast< unsigned char * >(argp2); + if (arg1) (arg1)->data = (unsigned char const *)arg2; + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_InputBuffer_data_get(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + InputBuffer *arg1 = (InputBuffer *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + unsigned char *result = 0 ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_InputBuffer, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InputBuffer_data_get" "', argument " "1"" of type '" "InputBuffer *""'"); + } + arg1 = reinterpret_cast< InputBuffer * >(argp1); + result = (unsigned char *) ((arg1)->data); + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_unsigned_char, 0 | 0 ); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_InputBuffer_len_set(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + InputBuffer *arg1 = (InputBuffer *) 0 ; + uint64_t arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + unsigned long long val2 ; + int ecode2 = 0 ; + PyObject *swig_obj[2] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "InputBuffer_len_set", 2, 2, swig_obj)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_InputBuffer, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InputBuffer_len_set" "', argument " "1"" of type '" "InputBuffer *""'"); + } + arg1 = reinterpret_cast< InputBuffer * >(argp1); + ecode2 = SWIG_AsVal_unsigned_SS_long_SS_long(swig_obj[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "InputBuffer_len_set" "', argument " "2"" of type '" "uint64_t""'"); + } + arg2 = static_cast< uint64_t >(val2); + if (arg1) (arg1)->len = arg2; + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_InputBuffer_len_get(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + InputBuffer *arg1 = (InputBuffer *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + uint64_t result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_InputBuffer, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InputBuffer_len_get" "', argument " "1"" of type '" "InputBuffer *""'"); + } + arg1 = reinterpret_cast< InputBuffer * >(argp1); + result = (uint64_t) ((arg1)->len); + resultobj = SWIG_From_unsigned_SS_long_SS_long(static_cast< unsigned long long >(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_new_InputBuffer(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + InputBuffer *result = 0 ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "new_InputBuffer", 0, 0, 0)) SWIG_fail; + { + try { + result = (InputBuffer *)new InputBuffer(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_InputBuffer, SWIG_POINTER_NEW | 0 ); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_delete_InputBuffer(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + InputBuffer *arg1 = (InputBuffer *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_InputBuffer, SWIG_POINTER_DISOWN | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_InputBuffer" "', argument " "1"" of type '" "InputBuffer *""'"); + } + arg1 = reinterpret_cast< InputBuffer * >(argp1); + { + try { + delete arg1; + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *InputBuffer_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *obj; + if (!SWIG_Python_UnpackTuple(args, "swigregister", 1, 1, &obj)) return NULL; + SWIG_TypeNewClientData(SWIGTYPE_p_InputBuffer, SWIG_NewClientData(obj)); + return SWIG_Py_Void(); +} + +SWIGINTERN PyObject *InputBuffer_swiginit(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + return SWIG_Python_InitShadowInstance(args); +} + +SWIGINTERN PyObject *_wrap_OutputBuffer_data_set(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + OutputBuffer *arg1 = (OutputBuffer *) 0 ; + unsigned char *arg2 = (unsigned char *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + void *argp2 = 0 ; + int res2 = 0 ; + PyObject *swig_obj[2] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "OutputBuffer_data_set", 2, 2, swig_obj)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_OutputBuffer, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "OutputBuffer_data_set" "', argument " "1"" of type '" "OutputBuffer *""'"); + } + arg1 = reinterpret_cast< OutputBuffer * >(argp1); + res2 = SWIG_ConvertPtr(swig_obj[1], &argp2,SWIGTYPE_p_unsigned_char, SWIG_POINTER_DISOWN | 0 ); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "OutputBuffer_data_set" "', argument " "2"" of type '" "unsigned char *""'"); + } + arg2 = reinterpret_cast< unsigned char * >(argp2); + if (arg1) (arg1)->data = arg2; + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_OutputBuffer_data_get(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + OutputBuffer *arg1 = (OutputBuffer *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + unsigned char *result = 0 ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_OutputBuffer, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "OutputBuffer_data_get" "', argument " "1"" of type '" "OutputBuffer *""'"); + } + arg1 = reinterpret_cast< OutputBuffer * >(argp1); + result = (unsigned char *) ((arg1)->data); + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_unsigned_char, 0 | 0 ); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_OutputBuffer_len_set(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + OutputBuffer *arg1 = (OutputBuffer *) 0 ; + uint64_t arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + unsigned long long val2 ; + int ecode2 = 0 ; + PyObject *swig_obj[2] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "OutputBuffer_len_set", 2, 2, swig_obj)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_OutputBuffer, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "OutputBuffer_len_set" "', argument " "1"" of type '" "OutputBuffer *""'"); + } + arg1 = reinterpret_cast< OutputBuffer * >(argp1); + ecode2 = SWIG_AsVal_unsigned_SS_long_SS_long(swig_obj[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "OutputBuffer_len_set" "', argument " "2"" of type '" "uint64_t""'"); + } + arg2 = static_cast< uint64_t >(val2); + if (arg1) (arg1)->len = arg2; + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_OutputBuffer_len_get(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + OutputBuffer *arg1 = (OutputBuffer *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + uint64_t result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_OutputBuffer, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "OutputBuffer_len_get" "', argument " "1"" of type '" "OutputBuffer *""'"); + } + arg1 = reinterpret_cast< OutputBuffer * >(argp1); + result = (uint64_t) ((arg1)->len); + resultobj = SWIG_From_unsigned_SS_long_SS_long(static_cast< unsigned long long >(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_new_OutputBuffer(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + OutputBuffer *result = 0 ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "new_OutputBuffer", 0, 0, 0)) SWIG_fail; + { + try { + result = (OutputBuffer *)new OutputBuffer(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_OutputBuffer, SWIG_POINTER_NEW | 0 ); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_delete_OutputBuffer(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + OutputBuffer *arg1 = (OutputBuffer *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_OutputBuffer, SWIG_POINTER_DISOWN | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_OutputBuffer" "', argument " "1"" of type '" "OutputBuffer *""'"); + } + arg1 = reinterpret_cast< OutputBuffer * >(argp1); + { + try { + delete arg1; + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *OutputBuffer_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *obj; + if (!SWIG_Python_UnpackTuple(args, "swigregister", 1, 1, &obj)) return NULL; + SWIG_TypeNewClientData(SWIGTYPE_p_OutputBuffer, SWIG_NewClientData(obj)); + return SWIG_Py_Void(); +} + +SWIGINTERN PyObject *OutputBuffer_swiginit(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + return SWIG_Python_InitShadowInstance(args); +} + +SWIGINTERN PyObject *_wrap_delete_FrontConfig(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::front::FrontConfig *arg1 = (ppc::front::FrontConfig *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::front::FrontConfig > tempshared1 ; + std::shared_ptr< ppc::front::FrontConfig > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__front__FrontConfig_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_FrontConfig" "', argument " "1"" of type '" "ppc::front::FrontConfig *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::front::FrontConfig > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::front::FrontConfig > * >(argp1); + arg1 = const_cast< ppc::front::FrontConfig * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::front::FrontConfig > * >(argp1); + arg1 = const_cast< ppc::front::FrontConfig * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + (void)arg1; delete smartarg1; + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_FrontConfig_threadPoolSize(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::front::FrontConfig *arg1 = (ppc::front::FrontConfig *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::front::FrontConfig const > tempshared1 ; + std::shared_ptr< ppc::front::FrontConfig const > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + int result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__front__FrontConfig_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FrontConfig_threadPoolSize" "', argument " "1"" of type '" "ppc::front::FrontConfig const *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< const ppc::front::FrontConfig > * >(argp1); + delete reinterpret_cast< std::shared_ptr< const ppc::front::FrontConfig > * >(argp1); + arg1 = const_cast< ppc::front::FrontConfig * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< const ppc::front::FrontConfig > * >(argp1); + arg1 = const_cast< ppc::front::FrontConfig * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + result = (int)((ppc::front::FrontConfig const *)arg1)->threadPoolSize(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_From_int(static_cast< int >(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_FrontConfig_setThreadPoolSize(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::front::FrontConfig *arg1 = (ppc::front::FrontConfig *) 0 ; + int arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::front::FrontConfig > tempshared1 ; + std::shared_ptr< ppc::front::FrontConfig > *smartarg1 = 0 ; + int val2 ; + int ecode2 = 0 ; + PyObject *swig_obj[2] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "FrontConfig_setThreadPoolSize", 2, 2, swig_obj)) SWIG_fail; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__front__FrontConfig_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FrontConfig_setThreadPoolSize" "', argument " "1"" of type '" "ppc::front::FrontConfig *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::front::FrontConfig > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::front::FrontConfig > * >(argp1); + arg1 = const_cast< ppc::front::FrontConfig * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::front::FrontConfig > * >(argp1); + arg1 = const_cast< ppc::front::FrontConfig * >((smartarg1 ? smartarg1->get() : 0)); + } + } + ecode2 = SWIG_AsVal_int(swig_obj[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "FrontConfig_setThreadPoolSize" "', argument " "2"" of type '" "int""'"); + } + arg2 = static_cast< int >(val2); + { + try { + (arg1)->setThreadPoolSize(arg2); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_FrontConfig_nodeID(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::front::FrontConfig *arg1 = (ppc::front::FrontConfig *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::front::FrontConfig const > tempshared1 ; + std::shared_ptr< ppc::front::FrontConfig const > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + std::string *result = 0 ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__front__FrontConfig_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FrontConfig_nodeID" "', argument " "1"" of type '" "ppc::front::FrontConfig const *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< const ppc::front::FrontConfig > * >(argp1); + delete reinterpret_cast< std::shared_ptr< const ppc::front::FrontConfig > * >(argp1); + arg1 = const_cast< ppc::front::FrontConfig * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< const ppc::front::FrontConfig > * >(argp1); + arg1 = const_cast< ppc::front::FrontConfig * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + result = (std::string *) &((ppc::front::FrontConfig const *)arg1)->nodeID(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_From_std_string(static_cast< std::string >(*result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_FrontConfig_setNodeID(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::front::FrontConfig *arg1 = (ppc::front::FrontConfig *) 0 ; + std::string *arg2 = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::front::FrontConfig > tempshared1 ; + std::shared_ptr< ppc::front::FrontConfig > *smartarg1 = 0 ; + int res2 = SWIG_OLDOBJ ; + PyObject *swig_obj[2] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "FrontConfig_setNodeID", 2, 2, swig_obj)) SWIG_fail; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__front__FrontConfig_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FrontConfig_setNodeID" "', argument " "1"" of type '" "ppc::front::FrontConfig *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::front::FrontConfig > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::front::FrontConfig > * >(argp1); + arg1 = const_cast< ppc::front::FrontConfig * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::front::FrontConfig > * >(argp1); + arg1 = const_cast< ppc::front::FrontConfig * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + std::string *ptr = (std::string *)0; + res2 = SWIG_AsPtr_std_string(swig_obj[1], &ptr); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "FrontConfig_setNodeID" "', argument " "2"" of type '" "std::string const &""'"); + } + if (!ptr) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "FrontConfig_setNodeID" "', argument " "2"" of type '" "std::string const &""'"); + } + arg2 = ptr; + } + { + try { + (arg1)->setNodeID((std::string const &)*arg2); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + if (SWIG_IsNewObj(res2)) delete arg2; + return resultobj; +fail: + if (SWIG_IsNewObj(res2)) delete arg2; + return NULL; +} + + +SWIGINTERN PyObject *_wrap_FrontConfig_selfEndPoint(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::front::FrontConfig *arg1 = (ppc::front::FrontConfig *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::front::FrontConfig const > tempshared1 ; + std::shared_ptr< ppc::front::FrontConfig const > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + ppc::protocol::EndPoint *result = 0 ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__front__FrontConfig_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FrontConfig_selfEndPoint" "', argument " "1"" of type '" "ppc::front::FrontConfig const *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< const ppc::front::FrontConfig > * >(argp1); + delete reinterpret_cast< std::shared_ptr< const ppc::front::FrontConfig > * >(argp1); + arg1 = const_cast< ppc::front::FrontConfig * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< const ppc::front::FrontConfig > * >(argp1); + arg1 = const_cast< ppc::front::FrontConfig * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + result = (ppc::protocol::EndPoint *) &((ppc::front::FrontConfig const *)arg1)->selfEndPoint(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_ppc__protocol__EndPoint, 0 | 0 ); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_FrontConfig_mutableSelfEndPoint(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::front::FrontConfig *arg1 = (ppc::front::FrontConfig *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::front::FrontConfig > tempshared1 ; + std::shared_ptr< ppc::front::FrontConfig > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + ppc::protocol::EndPoint *result = 0 ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__front__FrontConfig_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FrontConfig_mutableSelfEndPoint" "', argument " "1"" of type '" "ppc::front::FrontConfig *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::front::FrontConfig > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::front::FrontConfig > * >(argp1); + arg1 = const_cast< ppc::front::FrontConfig * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::front::FrontConfig > * >(argp1); + arg1 = const_cast< ppc::front::FrontConfig * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + result = (ppc::protocol::EndPoint *) &(arg1)->mutableSelfEndPoint(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_ppc__protocol__EndPoint, 0 | 0 ); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_FrontConfig_setSelfEndPoint(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::front::FrontConfig *arg1 = (ppc::front::FrontConfig *) 0 ; + ppc::protocol::EndPoint *arg2 = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::front::FrontConfig > tempshared1 ; + std::shared_ptr< ppc::front::FrontConfig > *smartarg1 = 0 ; + void *argp2 = 0 ; + int res2 = 0 ; + PyObject *swig_obj[2] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "FrontConfig_setSelfEndPoint", 2, 2, swig_obj)) SWIG_fail; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__front__FrontConfig_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FrontConfig_setSelfEndPoint" "', argument " "1"" of type '" "ppc::front::FrontConfig *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::front::FrontConfig > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::front::FrontConfig > * >(argp1); + arg1 = const_cast< ppc::front::FrontConfig * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::front::FrontConfig > * >(argp1); + arg1 = const_cast< ppc::front::FrontConfig * >((smartarg1 ? smartarg1->get() : 0)); + } + } + res2 = SWIG_ConvertPtr(swig_obj[1], &argp2, SWIGTYPE_p_ppc__protocol__EndPoint, 0 | 0); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "FrontConfig_setSelfEndPoint" "', argument " "2"" of type '" "ppc::protocol::EndPoint const &""'"); + } + if (!argp2) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "FrontConfig_setSelfEndPoint" "', argument " "2"" of type '" "ppc::protocol::EndPoint const &""'"); + } + arg2 = reinterpret_cast< ppc::protocol::EndPoint * >(argp2); + { + try { + (arg1)->setSelfEndPoint((ppc::protocol::EndPoint const &)*arg2); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_FrontConfig_setGatewayGrpcTarget(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::front::FrontConfig *arg1 = (ppc::front::FrontConfig *) 0 ; + std::string *arg2 = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::front::FrontConfig > tempshared1 ; + std::shared_ptr< ppc::front::FrontConfig > *smartarg1 = 0 ; + int res2 = SWIG_OLDOBJ ; + PyObject *swig_obj[2] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "FrontConfig_setGatewayGrpcTarget", 2, 2, swig_obj)) SWIG_fail; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__front__FrontConfig_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FrontConfig_setGatewayGrpcTarget" "', argument " "1"" of type '" "ppc::front::FrontConfig *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::front::FrontConfig > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::front::FrontConfig > * >(argp1); + arg1 = const_cast< ppc::front::FrontConfig * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::front::FrontConfig > * >(argp1); + arg1 = const_cast< ppc::front::FrontConfig * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + std::string *ptr = (std::string *)0; + res2 = SWIG_AsPtr_std_string(swig_obj[1], &ptr); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "FrontConfig_setGatewayGrpcTarget" "', argument " "2"" of type '" "std::string const &""'"); + } + if (!ptr) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "FrontConfig_setGatewayGrpcTarget" "', argument " "2"" of type '" "std::string const &""'"); + } + arg2 = ptr; + } + { + try { + (arg1)->setGatewayGrpcTarget((std::string const &)*arg2); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + if (SWIG_IsNewObj(res2)) delete arg2; + return resultobj; +fail: + if (SWIG_IsNewObj(res2)) delete arg2; + return NULL; +} + + +SWIGINTERN PyObject *_wrap_FrontConfig_gatewayGrpcTarget(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::front::FrontConfig *arg1 = (ppc::front::FrontConfig *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::front::FrontConfig const > tempshared1 ; + std::shared_ptr< ppc::front::FrontConfig const > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + std::string *result = 0 ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__front__FrontConfig_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FrontConfig_gatewayGrpcTarget" "', argument " "1"" of type '" "ppc::front::FrontConfig const *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< const ppc::front::FrontConfig > * >(argp1); + delete reinterpret_cast< std::shared_ptr< const ppc::front::FrontConfig > * >(argp1); + arg1 = const_cast< ppc::front::FrontConfig * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< const ppc::front::FrontConfig > * >(argp1); + arg1 = const_cast< ppc::front::FrontConfig * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + result = (std::string *) &((ppc::front::FrontConfig const *)arg1)->gatewayGrpcTarget(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_From_std_string(static_cast< std::string >(*result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_FrontConfig_setGrpcConfig(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::front::FrontConfig *arg1 = (ppc::front::FrontConfig *) 0 ; + ppc::protocol::GrpcConfig::Ptr arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::front::FrontConfig > tempshared1 ; + std::shared_ptr< ppc::front::FrontConfig > *smartarg1 = 0 ; + void *argp2 ; + int res2 = 0 ; + PyObject *swig_obj[2] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "FrontConfig_setGrpcConfig", 2, 2, swig_obj)) SWIG_fail; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__front__FrontConfig_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FrontConfig_setGrpcConfig" "', argument " "1"" of type '" "ppc::front::FrontConfig *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::front::FrontConfig > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::front::FrontConfig > * >(argp1); + arg1 = const_cast< ppc::front::FrontConfig * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::front::FrontConfig > * >(argp1); + arg1 = const_cast< ppc::front::FrontConfig * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + int newmem = 0; + res2 = SWIG_ConvertPtrAndOwn(swig_obj[1], &argp2, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__GrpcConfig_t, 0 , &newmem); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "FrontConfig_setGrpcConfig" "', argument " "2"" of type '" "ppc::protocol::GrpcConfig::Ptr""'"); + } + if (argp2) arg2 = *(reinterpret_cast< ppc::protocol::GrpcConfig::Ptr * >(argp2)); + if (newmem & SWIG_CAST_NEW_MEMORY) delete reinterpret_cast< ppc::protocol::GrpcConfig::Ptr * >(argp2); + } + { + try { + (arg1)->setGrpcConfig(arg2); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_FrontConfig_grpcConfig(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::front::FrontConfig *arg1 = (ppc::front::FrontConfig *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::front::FrontConfig const > tempshared1 ; + std::shared_ptr< ppc::front::FrontConfig const > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + ppc::protocol::GrpcConfig::Ptr *result = 0 ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__front__FrontConfig_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FrontConfig_grpcConfig" "', argument " "1"" of type '" "ppc::front::FrontConfig const *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< const ppc::front::FrontConfig > * >(argp1); + delete reinterpret_cast< std::shared_ptr< const ppc::front::FrontConfig > * >(argp1); + arg1 = const_cast< ppc::front::FrontConfig * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< const ppc::front::FrontConfig > * >(argp1); + arg1 = const_cast< ppc::front::FrontConfig * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + result = (ppc::protocol::GrpcConfig::Ptr *) &((ppc::front::FrontConfig const *)arg1)->grpcConfig(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + { + std::shared_ptr< ppc::protocol::GrpcConfig > *smartresult = *result ? new std::shared_ptr< ppc::protocol::GrpcConfig >(*result) : 0; + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(smartresult), SWIGTYPE_p_std__shared_ptrT_ppc__protocol__GrpcConfig_t, SWIG_POINTER_OWN); + } + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_FrontConfig_generateNodeInfo(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::front::FrontConfig *arg1 = (ppc::front::FrontConfig *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::front::FrontConfig const > tempshared1 ; + std::shared_ptr< ppc::front::FrontConfig const > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + ppc::protocol::INodeInfo::Ptr result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__front__FrontConfig_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FrontConfig_generateNodeInfo" "', argument " "1"" of type '" "ppc::front::FrontConfig const *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< const ppc::front::FrontConfig > * >(argp1); + delete reinterpret_cast< std::shared_ptr< const ppc::front::FrontConfig > * >(argp1); + arg1 = const_cast< ppc::front::FrontConfig * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< const ppc::front::FrontConfig > * >(argp1); + arg1 = const_cast< ppc::front::FrontConfig * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + result = ((ppc::front::FrontConfig const *)arg1)->generateNodeInfo(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + { + std::shared_ptr< ppc::protocol::INodeInfo > *smartresult = result ? new std::shared_ptr< ppc::protocol::INodeInfo >(result) : 0; + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(smartresult), SWIGTYPE_p_std__shared_ptrT_ppc__protocol__INodeInfo_t, SWIG_POINTER_OWN); + } + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_FrontConfig_getComponents(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::front::FrontConfig *arg1 = (ppc::front::FrontConfig *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::front::FrontConfig const > tempshared1 ; + std::shared_ptr< ppc::front::FrontConfig const > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + std::vector< std::string,std::allocator< std::string > > *result = 0 ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__front__FrontConfig_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FrontConfig_getComponents" "', argument " "1"" of type '" "ppc::front::FrontConfig const *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< const ppc::front::FrontConfig > * >(argp1); + delete reinterpret_cast< std::shared_ptr< const ppc::front::FrontConfig > * >(argp1); + arg1 = const_cast< ppc::front::FrontConfig * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< const ppc::front::FrontConfig > * >(argp1); + arg1 = const_cast< ppc::front::FrontConfig * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + result = (std::vector< std::string,std::allocator< std::string > > *) &((ppc::front::FrontConfig const *)arg1)->getComponents(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = swig::from(static_cast< std::vector< std::string,std::allocator< std::string > > >(*result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_FrontConfig_setComponents(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::front::FrontConfig *arg1 = (ppc::front::FrontConfig *) 0 ; + std::vector< std::string,std::allocator< std::string > > *arg2 = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::front::FrontConfig > tempshared1 ; + std::shared_ptr< ppc::front::FrontConfig > *smartarg1 = 0 ; + int res2 = SWIG_OLDOBJ ; + PyObject *swig_obj[2] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "FrontConfig_setComponents", 2, 2, swig_obj)) SWIG_fail; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__front__FrontConfig_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FrontConfig_setComponents" "', argument " "1"" of type '" "ppc::front::FrontConfig *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::front::FrontConfig > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::front::FrontConfig > * >(argp1); + arg1 = const_cast< ppc::front::FrontConfig * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::front::FrontConfig > * >(argp1); + arg1 = const_cast< ppc::front::FrontConfig * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + std::vector< std::string,std::allocator< std::string > > *ptr = (std::vector< std::string,std::allocator< std::string > > *)0; + res2 = swig::asptr(swig_obj[1], &ptr); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "FrontConfig_setComponents" "', argument " "2"" of type '" "std::vector< std::string,std::allocator< std::string > > const &""'"); + } + if (!ptr) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "FrontConfig_setComponents" "', argument " "2"" of type '" "std::vector< std::string,std::allocator< std::string > > const &""'"); + } + arg2 = ptr; + } + { + try { + (arg1)->setComponents((std::vector< std::string,std::allocator< std::string > > const &)*arg2); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + if (SWIG_IsNewObj(res2)) delete arg2; + return resultobj; +fail: + if (SWIG_IsNewObj(res2)) delete arg2; + return NULL; +} + + +SWIGINTERN PyObject *_wrap_FrontConfig_addComponent(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::front::FrontConfig *arg1 = (ppc::front::FrontConfig *) 0 ; + std::string *arg2 = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::front::FrontConfig > tempshared1 ; + std::shared_ptr< ppc::front::FrontConfig > *smartarg1 = 0 ; + int res2 = SWIG_OLDOBJ ; + PyObject *swig_obj[2] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "FrontConfig_addComponent", 2, 2, swig_obj)) SWIG_fail; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__front__FrontConfig_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FrontConfig_addComponent" "', argument " "1"" of type '" "ppc::front::FrontConfig *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::front::FrontConfig > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::front::FrontConfig > * >(argp1); + arg1 = const_cast< ppc::front::FrontConfig * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::front::FrontConfig > * >(argp1); + arg1 = const_cast< ppc::front::FrontConfig * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + std::string *ptr = (std::string *)0; + res2 = SWIG_AsPtr_std_string(swig_obj[1], &ptr); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "FrontConfig_addComponent" "', argument " "2"" of type '" "std::string const &""'"); + } + if (!ptr) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "FrontConfig_addComponent" "', argument " "2"" of type '" "std::string const &""'"); + } + arg2 = ptr; + } + { + try { + (arg1)->addComponent((std::string const &)*arg2); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + if (SWIG_IsNewObj(res2)) delete arg2; + return resultobj; +fail: + if (SWIG_IsNewObj(res2)) delete arg2; + return NULL; +} + + +SWIGINTERN PyObject *_wrap_FrontConfig_mutableComponents(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::front::FrontConfig *arg1 = (ppc::front::FrontConfig *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::front::FrontConfig > tempshared1 ; + std::shared_ptr< ppc::front::FrontConfig > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + std::vector< std::string,std::allocator< std::string > > *result = 0 ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__front__FrontConfig_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FrontConfig_mutableComponents" "', argument " "1"" of type '" "ppc::front::FrontConfig *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::front::FrontConfig > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::front::FrontConfig > * >(argp1); + arg1 = const_cast< ppc::front::FrontConfig * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::front::FrontConfig > * >(argp1); + arg1 = const_cast< ppc::front::FrontConfig * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + result = (std::vector< std::string,std::allocator< std::string > > *) &(arg1)->mutableComponents(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorT_std__string_t, 0 | 0 ); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_FrontConfig_meta(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::front::FrontConfig *arg1 = (ppc::front::FrontConfig *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::front::FrontConfig const > tempshared1 ; + std::shared_ptr< ppc::front::FrontConfig const > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + std::string result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__front__FrontConfig_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FrontConfig_meta" "', argument " "1"" of type '" "ppc::front::FrontConfig const *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< const ppc::front::FrontConfig > * >(argp1); + delete reinterpret_cast< std::shared_ptr< const ppc::front::FrontConfig > * >(argp1); + arg1 = const_cast< ppc::front::FrontConfig * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< const ppc::front::FrontConfig > * >(argp1); + arg1 = const_cast< ppc::front::FrontConfig * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + result = ((ppc::front::FrontConfig const *)arg1)->meta(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_From_std_string(static_cast< std::string >(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_FrontConfig_setMeta(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::front::FrontConfig *arg1 = (ppc::front::FrontConfig *) 0 ; + std::string arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::front::FrontConfig > tempshared1 ; + std::shared_ptr< ppc::front::FrontConfig > *smartarg1 = 0 ; + PyObject *swig_obj[2] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "FrontConfig_setMeta", 2, 2, swig_obj)) SWIG_fail; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__front__FrontConfig_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FrontConfig_setMeta" "', argument " "1"" of type '" "ppc::front::FrontConfig *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::front::FrontConfig > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::front::FrontConfig > * >(argp1); + arg1 = const_cast< ppc::front::FrontConfig * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::front::FrontConfig > * >(argp1); + arg1 = const_cast< ppc::front::FrontConfig * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + std::string *ptr = (std::string *)0; + int res = SWIG_AsPtr_std_string(swig_obj[1], &ptr); + if (!SWIG_IsOK(res) || !ptr) { + SWIG_exception_fail(SWIG_ArgError((ptr ? res : SWIG_TypeError)), "in method '" "FrontConfig_setMeta" "', argument " "2"" of type '" "std::string""'"); + } + arg2 = *ptr; + if (SWIG_IsNewObj(res)) delete ptr; + } + { + try { + (arg1)->setMeta(arg2); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *FrontConfig_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *obj; + if (!SWIG_Python_UnpackTuple(args, "swigregister", 1, 1, &obj)) return NULL; + SWIG_TypeNewClientData(SWIGTYPE_p_std__shared_ptrT_ppc__front__FrontConfig_t, SWIG_NewClientData(obj)); + return SWIG_Py_Void(); +} + +SWIGINTERN PyObject *_wrap_delete_FrontConfigBuilder(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::front::FrontConfigBuilder *arg1 = (ppc::front::FrontConfigBuilder *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_ppc__front__FrontConfigBuilder, SWIG_POINTER_DISOWN | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_FrontConfigBuilder" "', argument " "1"" of type '" "ppc::front::FrontConfigBuilder *""'"); + } + arg1 = reinterpret_cast< ppc::front::FrontConfigBuilder * >(argp1); + { + try { + delete arg1; + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_FrontConfigBuilder_build__SWIG_0(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + ppc::front::FrontConfigBuilder *arg1 = (ppc::front::FrontConfigBuilder *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + ppc::front::FrontConfig::Ptr result; + + (void)self; + if ((nobjs < 1) || (nobjs > 1)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_ppc__front__FrontConfigBuilder, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FrontConfigBuilder_build" "', argument " "1"" of type '" "ppc::front::FrontConfigBuilder const *""'"); + } + arg1 = reinterpret_cast< ppc::front::FrontConfigBuilder * >(argp1); + { + try { + result = ((ppc::front::FrontConfigBuilder const *)arg1)->build(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + { + std::shared_ptr< ppc::front::FrontConfig > *smartresult = result ? new std::shared_ptr< ppc::front::FrontConfig >(result) : 0; + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(smartresult), SWIGTYPE_p_std__shared_ptrT_ppc__front__FrontConfig_t, SWIG_POINTER_OWN); + } + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_FrontConfigBuilder_build__SWIG_1(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + ppc::front::FrontConfigBuilder *arg1 = (ppc::front::FrontConfigBuilder *) 0 ; + int arg2 ; + std::string arg3 ; + void *argp1 = 0 ; + int res1 = 0 ; + int val2 ; + int ecode2 = 0 ; + ppc::front::FrontConfig::Ptr result; + + (void)self; + if ((nobjs < 3) || (nobjs > 3)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_ppc__front__FrontConfigBuilder, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FrontConfigBuilder_build" "', argument " "1"" of type '" "ppc::front::FrontConfigBuilder const *""'"); + } + arg1 = reinterpret_cast< ppc::front::FrontConfigBuilder * >(argp1); + ecode2 = SWIG_AsVal_int(swig_obj[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "FrontConfigBuilder_build" "', argument " "2"" of type '" "int""'"); + } + arg2 = static_cast< int >(val2); + { + std::string *ptr = (std::string *)0; + int res = SWIG_AsPtr_std_string(swig_obj[2], &ptr); + if (!SWIG_IsOK(res) || !ptr) { + SWIG_exception_fail(SWIG_ArgError((ptr ? res : SWIG_TypeError)), "in method '" "FrontConfigBuilder_build" "', argument " "3"" of type '" "std::string""'"); + } + arg3 = *ptr; + if (SWIG_IsNewObj(res)) delete ptr; + } + { + try { + result = ((ppc::front::FrontConfigBuilder const *)arg1)->build(arg2,arg3); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + { + std::shared_ptr< ppc::front::FrontConfig > *smartresult = result ? new std::shared_ptr< ppc::front::FrontConfig >(result) : 0; + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(smartresult), SWIGTYPE_p_std__shared_ptrT_ppc__front__FrontConfig_t, SWIG_POINTER_OWN); + } + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_FrontConfigBuilder_build(PyObject *self, PyObject *args) { + Py_ssize_t argc; + PyObject *argv[4] = { + 0 + }; + + if (!(argc = SWIG_Python_UnpackTuple(args, "FrontConfigBuilder_build", 0, 3, argv))) SWIG_fail; + --argc; + if (argc == 1) { + int _v = 0; + void *vptr = 0; + int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_ppc__front__FrontConfigBuilder, 0); + _v = SWIG_CheckState(res); + if (_v) { + return _wrap_FrontConfigBuilder_build__SWIG_0(self, argc, argv); + } + } + if (argc == 3) { + int _v = 0; + void *vptr = 0; + int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_ppc__front__FrontConfigBuilder, 0); + _v = SWIG_CheckState(res); + if (_v) { + { + int res = SWIG_AsVal_int(argv[1], NULL); + _v = SWIG_CheckState(res); + } + if (_v) { + int res = SWIG_AsPtr_std_string(argv[2], (std::string**)(0)); + _v = SWIG_CheckState(res); + if (_v) { + return _wrap_FrontConfigBuilder_build__SWIG_1(self, argc, argv); + } + } + } + } + +fail: + SWIG_Python_RaiseOrModifyTypeError("Wrong number or type of arguments for overloaded function 'FrontConfigBuilder_build'.\n" + " Possible C/C++ prototypes are:\n" + " ppc::front::FrontConfigBuilder::build() const\n" + " ppc::front::FrontConfigBuilder::build(int,std::string) const\n"); + return 0; +} + + +SWIGINTERN PyObject *FrontConfigBuilder_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *obj; + if (!SWIG_Python_UnpackTuple(args, "swigregister", 1, 1, &obj)) return NULL; + SWIG_TypeNewClientData(SWIGTYPE_p_ppc__front__FrontConfigBuilder, SWIG_NewClientData(obj)); + return SWIG_Py_Void(); +} + +SWIGINTERN PyObject *_wrap_printFrontDesc(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::front::FrontConfig::Ptr *arg1 = 0 ; + void *argp1 ; + int res1 = 0 ; + ppc::front::FrontConfig::Ptr tempshared1 ; + PyObject *swig_obj[1] ; + std::string result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__front__FrontConfig_t, 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "printFrontDesc" "', argument " "1"" of type '" "ppc::front::FrontConfig::Ptr const &""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + if (argp1) tempshared1 = *reinterpret_cast< ppc::front::FrontConfig::Ptr * >(argp1); + delete reinterpret_cast< ppc::front::FrontConfig::Ptr * >(argp1); + arg1 = &tempshared1; + } else { + arg1 = (argp1) ? reinterpret_cast< ppc::front::FrontConfig::Ptr * >(argp1) : &tempshared1; + } + } + { + try { + result = ppc::front::printFrontDesc((std::shared_ptr< ppc::front::FrontConfig > const &)*arg1); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_From_std_string(static_cast< std::string >(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_new_EndPoint__SWIG_0(PyObject *self, Py_ssize_t nobjs, PyObject **SWIGUNUSEDPARM(swig_obj)) { + PyObject *resultobj = 0; + ppc::protocol::EndPoint *result = 0 ; + + (void)self; + if ((nobjs < 0) || (nobjs > 0)) SWIG_fail; + { + try { + result = (ppc::protocol::EndPoint *)new ppc::protocol::EndPoint(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_ppc__protocol__EndPoint, SWIG_POINTER_NEW | 0 ); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_new_EndPoint__SWIG_1(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + std::string *arg1 = 0 ; + uint16_t arg2 ; + int res1 = SWIG_OLDOBJ ; + unsigned short val2 ; + int ecode2 = 0 ; + ppc::protocol::EndPoint *result = 0 ; + + (void)self; + if ((nobjs < 2) || (nobjs > 2)) SWIG_fail; + { + std::string *ptr = (std::string *)0; + res1 = SWIG_AsPtr_std_string(swig_obj[0], &ptr); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "new_EndPoint" "', argument " "1"" of type '" "std::string const &""'"); + } + if (!ptr) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_EndPoint" "', argument " "1"" of type '" "std::string const &""'"); + } + arg1 = ptr; + } + ecode2 = SWIG_AsVal_unsigned_SS_short(swig_obj[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "new_EndPoint" "', argument " "2"" of type '" "uint16_t""'"); + } + arg2 = static_cast< uint16_t >(val2); + { + try { + result = (ppc::protocol::EndPoint *)new ppc::protocol::EndPoint((std::string const &)*arg1,arg2); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_ppc__protocol__EndPoint, SWIG_POINTER_NEW | 0 ); + if (SWIG_IsNewObj(res1)) delete arg1; + return resultobj; +fail: + if (SWIG_IsNewObj(res1)) delete arg1; + return NULL; +} + + +SWIGINTERN PyObject *_wrap_new_EndPoint(PyObject *self, PyObject *args) { + Py_ssize_t argc; + PyObject *argv[3] = { + 0 + }; + + if (!(argc = SWIG_Python_UnpackTuple(args, "new_EndPoint", 0, 2, argv))) SWIG_fail; + --argc; + if (argc == 0) { + return _wrap_new_EndPoint__SWIG_0(self, argc, argv); + } + if (argc == 2) { + int _v = 0; + int res = SWIG_AsPtr_std_string(argv[0], (std::string**)(0)); + _v = SWIG_CheckState(res); + if (_v) { + { + int res = SWIG_AsVal_unsigned_SS_short(argv[1], NULL); + _v = SWIG_CheckState(res); + } + if (_v) { + return _wrap_new_EndPoint__SWIG_1(self, argc, argv); + } + } + } + +fail: + SWIG_Python_RaiseOrModifyTypeError("Wrong number or type of arguments for overloaded function 'new_EndPoint'.\n" + " Possible C/C++ prototypes are:\n" + " ppc::protocol::EndPoint::EndPoint()\n" + " ppc::protocol::EndPoint::EndPoint(std::string const &,uint16_t)\n"); + return 0; +} + + +SWIGINTERN PyObject *_wrap_delete_EndPoint(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::EndPoint *arg1 = (ppc::protocol::EndPoint *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_ppc__protocol__EndPoint, SWIG_POINTER_DISOWN | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_EndPoint" "', argument " "1"" of type '" "ppc::protocol::EndPoint *""'"); + } + arg1 = reinterpret_cast< ppc::protocol::EndPoint * >(argp1); + { + try { + delete arg1; + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_EndPoint_host(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::EndPoint *arg1 = (ppc::protocol::EndPoint *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + std::string *result = 0 ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_ppc__protocol__EndPoint, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "EndPoint_host" "', argument " "1"" of type '" "ppc::protocol::EndPoint const *""'"); + } + arg1 = reinterpret_cast< ppc::protocol::EndPoint * >(argp1); + { + try { + result = (std::string *) &((ppc::protocol::EndPoint const *)arg1)->host(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_From_std_string(static_cast< std::string >(*result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_EndPoint_port(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::EndPoint *arg1 = (ppc::protocol::EndPoint *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + uint16_t result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_ppc__protocol__EndPoint, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "EndPoint_port" "', argument " "1"" of type '" "ppc::protocol::EndPoint const *""'"); + } + arg1 = reinterpret_cast< ppc::protocol::EndPoint * >(argp1); + { + try { + result = (uint16_t)((ppc::protocol::EndPoint const *)arg1)->port(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_From_unsigned_SS_short(static_cast< unsigned short >(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_EndPoint_setHost(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::EndPoint *arg1 = (ppc::protocol::EndPoint *) 0 ; + std::string arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[2] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "EndPoint_setHost", 2, 2, swig_obj)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_ppc__protocol__EndPoint, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "EndPoint_setHost" "', argument " "1"" of type '" "ppc::protocol::EndPoint *""'"); + } + arg1 = reinterpret_cast< ppc::protocol::EndPoint * >(argp1); + { + std::string *ptr = (std::string *)0; + int res = SWIG_AsPtr_std_string(swig_obj[1], &ptr); + if (!SWIG_IsOK(res) || !ptr) { + SWIG_exception_fail(SWIG_ArgError((ptr ? res : SWIG_TypeError)), "in method '" "EndPoint_setHost" "', argument " "2"" of type '" "std::string""'"); + } + arg2 = *ptr; + if (SWIG_IsNewObj(res)) delete ptr; + } + { + try { + (arg1)->setHost(arg2); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_EndPoint_setPort(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::EndPoint *arg1 = (ppc::protocol::EndPoint *) 0 ; + uint16_t arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + unsigned short val2 ; + int ecode2 = 0 ; + PyObject *swig_obj[2] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "EndPoint_setPort", 2, 2, swig_obj)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_ppc__protocol__EndPoint, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "EndPoint_setPort" "', argument " "1"" of type '" "ppc::protocol::EndPoint *""'"); + } + arg1 = reinterpret_cast< ppc::protocol::EndPoint * >(argp1); + ecode2 = SWIG_AsVal_unsigned_SS_short(swig_obj[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "EndPoint_setPort" "', argument " "2"" of type '" "uint16_t""'"); + } + arg2 = static_cast< uint16_t >(val2); + { + try { + (arg1)->setPort(arg2); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_EndPoint_setListenIp(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::EndPoint *arg1 = (ppc::protocol::EndPoint *) 0 ; + std::string *arg2 = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + int res2 = SWIG_OLDOBJ ; + PyObject *swig_obj[2] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "EndPoint_setListenIp", 2, 2, swig_obj)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_ppc__protocol__EndPoint, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "EndPoint_setListenIp" "', argument " "1"" of type '" "ppc::protocol::EndPoint *""'"); + } + arg1 = reinterpret_cast< ppc::protocol::EndPoint * >(argp1); + { + std::string *ptr = (std::string *)0; + res2 = SWIG_AsPtr_std_string(swig_obj[1], &ptr); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "EndPoint_setListenIp" "', argument " "2"" of type '" "std::string const &""'"); + } + if (!ptr) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "EndPoint_setListenIp" "', argument " "2"" of type '" "std::string const &""'"); + } + arg2 = ptr; + } + { + try { + (arg1)->setListenIp((std::string const &)*arg2); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + if (SWIG_IsNewObj(res2)) delete arg2; + return resultobj; +fail: + if (SWIG_IsNewObj(res2)) delete arg2; + return NULL; +} + + +SWIGINTERN PyObject *_wrap_EndPoint_entryPoint(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::EndPoint *arg1 = (ppc::protocol::EndPoint *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + std::string result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_ppc__protocol__EndPoint, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "EndPoint_entryPoint" "', argument " "1"" of type '" "ppc::protocol::EndPoint const *""'"); + } + arg1 = reinterpret_cast< ppc::protocol::EndPoint * >(argp1); + { + try { + result = ((ppc::protocol::EndPoint const *)arg1)->entryPoint(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_From_std_string(static_cast< std::string >(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_EndPoint_listenEndPoint(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::EndPoint *arg1 = (ppc::protocol::EndPoint *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + std::string result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_ppc__protocol__EndPoint, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "EndPoint_listenEndPoint" "', argument " "1"" of type '" "ppc::protocol::EndPoint const *""'"); + } + arg1 = reinterpret_cast< ppc::protocol::EndPoint * >(argp1); + { + try { + result = ((ppc::protocol::EndPoint const *)arg1)->listenEndPoint(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_From_std_string(static_cast< std::string >(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_EndPoint_listenIp(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::EndPoint *arg1 = (ppc::protocol::EndPoint *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + std::string *result = 0 ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_ppc__protocol__EndPoint, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "EndPoint_listenIp" "', argument " "1"" of type '" "ppc::protocol::EndPoint const *""'"); + } + arg1 = reinterpret_cast< ppc::protocol::EndPoint * >(argp1); + { + try { + result = (std::string *) &((ppc::protocol::EndPoint const *)arg1)->listenIp(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_From_std_string(static_cast< std::string >(*result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *EndPoint_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *obj; + if (!SWIG_Python_UnpackTuple(args, "swigregister", 1, 1, &obj)) return NULL; + SWIG_TypeNewClientData(SWIGTYPE_p_ppc__protocol__EndPoint, SWIG_NewClientData(obj)); + return SWIG_Py_Void(); +} + +SWIGINTERN PyObject *EndPoint_swiginit(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + return SWIG_Python_InitShadowInstance(args); +} + +SWIGINTERN PyObject *_wrap_new_GrpcConfig(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::GrpcConfig *result = 0 ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "new_GrpcConfig", 0, 0, 0)) SWIG_fail; + { + try { + result = (ppc::protocol::GrpcConfig *)new ppc::protocol::GrpcConfig(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + { + std::shared_ptr< ppc::protocol::GrpcConfig > *smartresult = result ? new std::shared_ptr< ppc::protocol::GrpcConfig >(result SWIG_NO_NULL_DELETER_SWIG_POINTER_NEW) : 0; + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(smartresult), SWIGTYPE_p_std__shared_ptrT_ppc__protocol__GrpcConfig_t, SWIG_POINTER_NEW | SWIG_POINTER_OWN); + } + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_GrpcConfig_loadBalancePolicy(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::GrpcConfig *arg1 = (ppc::protocol::GrpcConfig *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::GrpcConfig const > tempshared1 ; + std::shared_ptr< ppc::protocol::GrpcConfig const > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + std::string *result = 0 ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__GrpcConfig_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GrpcConfig_loadBalancePolicy" "', argument " "1"" of type '" "ppc::protocol::GrpcConfig const *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< const ppc::protocol::GrpcConfig > * >(argp1); + delete reinterpret_cast< std::shared_ptr< const ppc::protocol::GrpcConfig > * >(argp1); + arg1 = const_cast< ppc::protocol::GrpcConfig * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< const ppc::protocol::GrpcConfig > * >(argp1); + arg1 = const_cast< ppc::protocol::GrpcConfig * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + result = (std::string *) &((ppc::protocol::GrpcConfig const *)arg1)->loadBalancePolicy(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_From_std_string(static_cast< std::string >(*result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_GrpcConfig_setLoadBalancePolicy(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::GrpcConfig *arg1 = (ppc::protocol::GrpcConfig *) 0 ; + std::string *arg2 = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::GrpcConfig > tempshared1 ; + std::shared_ptr< ppc::protocol::GrpcConfig > *smartarg1 = 0 ; + int res2 = SWIG_OLDOBJ ; + PyObject *swig_obj[2] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "GrpcConfig_setLoadBalancePolicy", 2, 2, swig_obj)) SWIG_fail; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__GrpcConfig_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GrpcConfig_setLoadBalancePolicy" "', argument " "1"" of type '" "ppc::protocol::GrpcConfig *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::protocol::GrpcConfig > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::protocol::GrpcConfig > * >(argp1); + arg1 = const_cast< ppc::protocol::GrpcConfig * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::protocol::GrpcConfig > * >(argp1); + arg1 = const_cast< ppc::protocol::GrpcConfig * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + std::string *ptr = (std::string *)0; + res2 = SWIG_AsPtr_std_string(swig_obj[1], &ptr); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "GrpcConfig_setLoadBalancePolicy" "', argument " "2"" of type '" "std::string const &""'"); + } + if (!ptr) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "GrpcConfig_setLoadBalancePolicy" "', argument " "2"" of type '" "std::string const &""'"); + } + arg2 = ptr; + } + { + try { + (arg1)->setLoadBalancePolicy((std::string const &)*arg2); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + if (SWIG_IsNewObj(res2)) delete arg2; + return resultobj; +fail: + if (SWIG_IsNewObj(res2)) delete arg2; + return NULL; +} + + +SWIGINTERN PyObject *_wrap_GrpcConfig_enableHealthCheck(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::GrpcConfig *arg1 = (ppc::protocol::GrpcConfig *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::GrpcConfig const > tempshared1 ; + std::shared_ptr< ppc::protocol::GrpcConfig const > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + bool result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__GrpcConfig_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GrpcConfig_enableHealthCheck" "', argument " "1"" of type '" "ppc::protocol::GrpcConfig const *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< const ppc::protocol::GrpcConfig > * >(argp1); + delete reinterpret_cast< std::shared_ptr< const ppc::protocol::GrpcConfig > * >(argp1); + arg1 = const_cast< ppc::protocol::GrpcConfig * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< const ppc::protocol::GrpcConfig > * >(argp1); + arg1 = const_cast< ppc::protocol::GrpcConfig * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + result = (bool)((ppc::protocol::GrpcConfig const *)arg1)->enableHealthCheck(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_From_bool(static_cast< bool >(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_GrpcConfig_setEnableHealthCheck(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::GrpcConfig *arg1 = (ppc::protocol::GrpcConfig *) 0 ; + bool arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::GrpcConfig > tempshared1 ; + std::shared_ptr< ppc::protocol::GrpcConfig > *smartarg1 = 0 ; + bool val2 ; + int ecode2 = 0 ; + PyObject *swig_obj[2] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "GrpcConfig_setEnableHealthCheck", 2, 2, swig_obj)) SWIG_fail; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__GrpcConfig_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GrpcConfig_setEnableHealthCheck" "', argument " "1"" of type '" "ppc::protocol::GrpcConfig *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::protocol::GrpcConfig > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::protocol::GrpcConfig > * >(argp1); + arg1 = const_cast< ppc::protocol::GrpcConfig * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::protocol::GrpcConfig > * >(argp1); + arg1 = const_cast< ppc::protocol::GrpcConfig * >((smartarg1 ? smartarg1->get() : 0)); + } + } + ecode2 = SWIG_AsVal_bool(swig_obj[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "GrpcConfig_setEnableHealthCheck" "', argument " "2"" of type '" "bool""'"); + } + arg2 = static_cast< bool >(val2); + { + try { + (arg1)->setEnableHealthCheck(arg2); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_GrpcConfig_setEnableDnslookup(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::GrpcConfig *arg1 = (ppc::protocol::GrpcConfig *) 0 ; + bool arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::GrpcConfig > tempshared1 ; + std::shared_ptr< ppc::protocol::GrpcConfig > *smartarg1 = 0 ; + bool val2 ; + int ecode2 = 0 ; + PyObject *swig_obj[2] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "GrpcConfig_setEnableDnslookup", 2, 2, swig_obj)) SWIG_fail; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__GrpcConfig_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GrpcConfig_setEnableDnslookup" "', argument " "1"" of type '" "ppc::protocol::GrpcConfig *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::protocol::GrpcConfig > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::protocol::GrpcConfig > * >(argp1); + arg1 = const_cast< ppc::protocol::GrpcConfig * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::protocol::GrpcConfig > * >(argp1); + arg1 = const_cast< ppc::protocol::GrpcConfig * >((smartarg1 ? smartarg1->get() : 0)); + } + } + ecode2 = SWIG_AsVal_bool(swig_obj[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "GrpcConfig_setEnableDnslookup" "', argument " "2"" of type '" "bool""'"); + } + arg2 = static_cast< bool >(val2); + { + try { + (arg1)->setEnableDnslookup(arg2); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_GrpcConfig_enableDnslookup(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::GrpcConfig *arg1 = (ppc::protocol::GrpcConfig *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::GrpcConfig const > tempshared1 ; + std::shared_ptr< ppc::protocol::GrpcConfig const > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + bool result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__GrpcConfig_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GrpcConfig_enableDnslookup" "', argument " "1"" of type '" "ppc::protocol::GrpcConfig const *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< const ppc::protocol::GrpcConfig > * >(argp1); + delete reinterpret_cast< std::shared_ptr< const ppc::protocol::GrpcConfig > * >(argp1); + arg1 = const_cast< ppc::protocol::GrpcConfig * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< const ppc::protocol::GrpcConfig > * >(argp1); + arg1 = const_cast< ppc::protocol::GrpcConfig * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + result = (bool)((ppc::protocol::GrpcConfig const *)arg1)->enableDnslookup(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_From_bool(static_cast< bool >(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_GrpcConfig_maxSendMessageSize(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::GrpcConfig *arg1 = (ppc::protocol::GrpcConfig *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::GrpcConfig const > tempshared1 ; + std::shared_ptr< ppc::protocol::GrpcConfig const > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + uint64_t result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__GrpcConfig_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GrpcConfig_maxSendMessageSize" "', argument " "1"" of type '" "ppc::protocol::GrpcConfig const *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< const ppc::protocol::GrpcConfig > * >(argp1); + delete reinterpret_cast< std::shared_ptr< const ppc::protocol::GrpcConfig > * >(argp1); + arg1 = const_cast< ppc::protocol::GrpcConfig * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< const ppc::protocol::GrpcConfig > * >(argp1); + arg1 = const_cast< ppc::protocol::GrpcConfig * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + result = (uint64_t)((ppc::protocol::GrpcConfig const *)arg1)->maxSendMessageSize(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_From_unsigned_SS_long_SS_long(static_cast< unsigned long long >(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_GrpcConfig_maxReceivedMessageSize(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::GrpcConfig *arg1 = (ppc::protocol::GrpcConfig *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::GrpcConfig const > tempshared1 ; + std::shared_ptr< ppc::protocol::GrpcConfig const > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + uint64_t result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__GrpcConfig_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GrpcConfig_maxReceivedMessageSize" "', argument " "1"" of type '" "ppc::protocol::GrpcConfig const *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< const ppc::protocol::GrpcConfig > * >(argp1); + delete reinterpret_cast< std::shared_ptr< const ppc::protocol::GrpcConfig > * >(argp1); + arg1 = const_cast< ppc::protocol::GrpcConfig * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< const ppc::protocol::GrpcConfig > * >(argp1); + arg1 = const_cast< ppc::protocol::GrpcConfig * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + result = (uint64_t)((ppc::protocol::GrpcConfig const *)arg1)->maxReceivedMessageSize(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_From_unsigned_SS_long_SS_long(static_cast< unsigned long long >(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_GrpcConfig_setMaxSendMessageSize(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::GrpcConfig *arg1 = (ppc::protocol::GrpcConfig *) 0 ; + uint64_t arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::GrpcConfig > tempshared1 ; + std::shared_ptr< ppc::protocol::GrpcConfig > *smartarg1 = 0 ; + unsigned long long val2 ; + int ecode2 = 0 ; + PyObject *swig_obj[2] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "GrpcConfig_setMaxSendMessageSize", 2, 2, swig_obj)) SWIG_fail; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__GrpcConfig_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GrpcConfig_setMaxSendMessageSize" "', argument " "1"" of type '" "ppc::protocol::GrpcConfig *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::protocol::GrpcConfig > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::protocol::GrpcConfig > * >(argp1); + arg1 = const_cast< ppc::protocol::GrpcConfig * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::protocol::GrpcConfig > * >(argp1); + arg1 = const_cast< ppc::protocol::GrpcConfig * >((smartarg1 ? smartarg1->get() : 0)); + } + } + ecode2 = SWIG_AsVal_unsigned_SS_long_SS_long(swig_obj[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "GrpcConfig_setMaxSendMessageSize" "', argument " "2"" of type '" "uint64_t""'"); + } + arg2 = static_cast< uint64_t >(val2); + { + try { + (arg1)->setMaxSendMessageSize(arg2); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_GrpcConfig_setMaxReceivedMessageSize(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::GrpcConfig *arg1 = (ppc::protocol::GrpcConfig *) 0 ; + uint64_t arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::GrpcConfig > tempshared1 ; + std::shared_ptr< ppc::protocol::GrpcConfig > *smartarg1 = 0 ; + unsigned long long val2 ; + int ecode2 = 0 ; + PyObject *swig_obj[2] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "GrpcConfig_setMaxReceivedMessageSize", 2, 2, swig_obj)) SWIG_fail; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__GrpcConfig_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GrpcConfig_setMaxReceivedMessageSize" "', argument " "1"" of type '" "ppc::protocol::GrpcConfig *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::protocol::GrpcConfig > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::protocol::GrpcConfig > * >(argp1); + arg1 = const_cast< ppc::protocol::GrpcConfig * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::protocol::GrpcConfig > * >(argp1); + arg1 = const_cast< ppc::protocol::GrpcConfig * >((smartarg1 ? smartarg1->get() : 0)); + } + } + ecode2 = SWIG_AsVal_unsigned_SS_long_SS_long(swig_obj[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "GrpcConfig_setMaxReceivedMessageSize" "', argument " "2"" of type '" "uint64_t""'"); + } + arg2 = static_cast< uint64_t >(val2); + { + try { + (arg1)->setMaxReceivedMessageSize(arg2); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_GrpcConfig_compressAlgorithm(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::GrpcConfig *arg1 = (ppc::protocol::GrpcConfig *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::GrpcConfig const > tempshared1 ; + std::shared_ptr< ppc::protocol::GrpcConfig const > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + int result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__GrpcConfig_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GrpcConfig_compressAlgorithm" "', argument " "1"" of type '" "ppc::protocol::GrpcConfig const *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< const ppc::protocol::GrpcConfig > * >(argp1); + delete reinterpret_cast< std::shared_ptr< const ppc::protocol::GrpcConfig > * >(argp1); + arg1 = const_cast< ppc::protocol::GrpcConfig * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< const ppc::protocol::GrpcConfig > * >(argp1); + arg1 = const_cast< ppc::protocol::GrpcConfig * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + result = (int)((ppc::protocol::GrpcConfig const *)arg1)->compressAlgorithm(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_From_int(static_cast< int >(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_GrpcConfig_setCompressAlgorithm(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::GrpcConfig *arg1 = (ppc::protocol::GrpcConfig *) 0 ; + int arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::GrpcConfig > tempshared1 ; + std::shared_ptr< ppc::protocol::GrpcConfig > *smartarg1 = 0 ; + int val2 ; + int ecode2 = 0 ; + PyObject *swig_obj[2] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "GrpcConfig_setCompressAlgorithm", 2, 2, swig_obj)) SWIG_fail; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__GrpcConfig_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GrpcConfig_setCompressAlgorithm" "', argument " "1"" of type '" "ppc::protocol::GrpcConfig *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::protocol::GrpcConfig > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::protocol::GrpcConfig > * >(argp1); + arg1 = const_cast< ppc::protocol::GrpcConfig * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::protocol::GrpcConfig > * >(argp1); + arg1 = const_cast< ppc::protocol::GrpcConfig * >((smartarg1 ? smartarg1->get() : 0)); + } + } + ecode2 = SWIG_AsVal_int(swig_obj[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "GrpcConfig_setCompressAlgorithm" "', argument " "2"" of type '" "int""'"); + } + arg2 = static_cast< int >(val2); + { + try { + (arg1)->setCompressAlgorithm(arg2); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_GrpcConfig_maxMsgSize(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::GrpcConfig *arg1 = (ppc::protocol::GrpcConfig *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::GrpcConfig const > tempshared1 ; + std::shared_ptr< ppc::protocol::GrpcConfig const > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + uint64_t result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__GrpcConfig_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GrpcConfig_maxMsgSize" "', argument " "1"" of type '" "ppc::protocol::GrpcConfig const *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< const ppc::protocol::GrpcConfig > * >(argp1); + delete reinterpret_cast< std::shared_ptr< const ppc::protocol::GrpcConfig > * >(argp1); + arg1 = const_cast< ppc::protocol::GrpcConfig * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< const ppc::protocol::GrpcConfig > * >(argp1); + arg1 = const_cast< ppc::protocol::GrpcConfig * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + result = (uint64_t)((ppc::protocol::GrpcConfig const *)arg1)->maxMsgSize(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_From_unsigned_SS_long_SS_long(static_cast< unsigned long long >(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_GrpcConfig_setMaxMsgSize(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::GrpcConfig *arg1 = (ppc::protocol::GrpcConfig *) 0 ; + uint64_t arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::GrpcConfig > tempshared1 ; + std::shared_ptr< ppc::protocol::GrpcConfig > *smartarg1 = 0 ; + unsigned long long val2 ; + int ecode2 = 0 ; + PyObject *swig_obj[2] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "GrpcConfig_setMaxMsgSize", 2, 2, swig_obj)) SWIG_fail; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__GrpcConfig_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GrpcConfig_setMaxMsgSize" "', argument " "1"" of type '" "ppc::protocol::GrpcConfig *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::protocol::GrpcConfig > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::protocol::GrpcConfig > * >(argp1); + arg1 = const_cast< ppc::protocol::GrpcConfig * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::protocol::GrpcConfig > * >(argp1); + arg1 = const_cast< ppc::protocol::GrpcConfig * >((smartarg1 ? smartarg1->get() : 0)); + } + } + ecode2 = SWIG_AsVal_unsigned_SS_long_SS_long(swig_obj[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "GrpcConfig_setMaxMsgSize" "', argument " "2"" of type '" "uint64_t""'"); + } + arg2 = static_cast< uint64_t >(val2); + { + try { + (arg1)->setMaxMsgSize(arg2); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *GrpcConfig_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *obj; + if (!SWIG_Python_UnpackTuple(args, "swigregister", 1, 1, &obj)) return NULL; + SWIG_TypeNewClientData(SWIGTYPE_p_std__shared_ptrT_ppc__protocol__GrpcConfig_t, SWIG_NewClientData(obj)); + return SWIG_Py_Void(); +} + +SWIGINTERN PyObject *GrpcConfig_swiginit(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + return SWIG_Python_InitShadowInstance(args); +} + +SWIGINTERN PyObject *_wrap_new_GrpcServerConfig__SWIG_0(PyObject *self, Py_ssize_t nobjs, PyObject **SWIGUNUSEDPARM(swig_obj)) { + PyObject *resultobj = 0; + ppc::protocol::GrpcServerConfig *result = 0 ; + + (void)self; + if ((nobjs < 0) || (nobjs > 0)) SWIG_fail; + { + try { + result = (ppc::protocol::GrpcServerConfig *)new ppc::protocol::GrpcServerConfig(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_ppc__protocol__GrpcServerConfig, SWIG_POINTER_NEW | 0 ); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_new_GrpcServerConfig__SWIG_1(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + ppc::protocol::EndPoint arg1 ; + bool arg2 ; + void *argp1 ; + int res1 = 0 ; + bool val2 ; + int ecode2 = 0 ; + ppc::protocol::GrpcServerConfig *result = 0 ; + + (void)self; + if ((nobjs < 2) || (nobjs > 2)) SWIG_fail; + { + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1, SWIGTYPE_p_ppc__protocol__EndPoint, 0 | 0); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "new_GrpcServerConfig" "', argument " "1"" of type '" "ppc::protocol::EndPoint""'"); + } + if (!argp1) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_GrpcServerConfig" "', argument " "1"" of type '" "ppc::protocol::EndPoint""'"); + } else { + ppc::protocol::EndPoint * temp = reinterpret_cast< ppc::protocol::EndPoint * >(argp1); + arg1 = *temp; + if (SWIG_IsNewObj(res1)) delete temp; + } + } + ecode2 = SWIG_AsVal_bool(swig_obj[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "new_GrpcServerConfig" "', argument " "2"" of type '" "bool""'"); + } + arg2 = static_cast< bool >(val2); + { + try { + result = (ppc::protocol::GrpcServerConfig *)new ppc::protocol::GrpcServerConfig(arg1,arg2); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_ppc__protocol__GrpcServerConfig, SWIG_POINTER_NEW | 0 ); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_new_GrpcServerConfig(PyObject *self, PyObject *args) { + Py_ssize_t argc; + PyObject *argv[3] = { + 0 + }; + + if (!(argc = SWIG_Python_UnpackTuple(args, "new_GrpcServerConfig", 0, 2, argv))) SWIG_fail; + --argc; + if (argc == 0) { + return _wrap_new_GrpcServerConfig__SWIG_0(self, argc, argv); + } + if (argc == 2) { + int _v = 0; + int res = SWIG_ConvertPtr(argv[0], 0, SWIGTYPE_p_ppc__protocol__EndPoint, SWIG_POINTER_NO_NULL | 0); + _v = SWIG_CheckState(res); + if (_v) { + { + int res = SWIG_AsVal_bool(argv[1], NULL); + _v = SWIG_CheckState(res); + } + if (_v) { + return _wrap_new_GrpcServerConfig__SWIG_1(self, argc, argv); + } + } + } + +fail: + SWIG_Python_RaiseOrModifyTypeError("Wrong number or type of arguments for overloaded function 'new_GrpcServerConfig'.\n" + " Possible C/C++ prototypes are:\n" + " ppc::protocol::GrpcServerConfig::GrpcServerConfig()\n" + " ppc::protocol::GrpcServerConfig::GrpcServerConfig(ppc::protocol::EndPoint,bool)\n"); + return 0; +} + + +SWIGINTERN PyObject *_wrap_GrpcServerConfig_listenEndPoint(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::GrpcServerConfig *arg1 = (ppc::protocol::GrpcServerConfig *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + std::string result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_ppc__protocol__GrpcServerConfig, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GrpcServerConfig_listenEndPoint" "', argument " "1"" of type '" "ppc::protocol::GrpcServerConfig const *""'"); + } + arg1 = reinterpret_cast< ppc::protocol::GrpcServerConfig * >(argp1); + { + try { + result = ((ppc::protocol::GrpcServerConfig const *)arg1)->listenEndPoint(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_From_std_string(static_cast< std::string >(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_GrpcServerConfig_setEndPoint(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::GrpcServerConfig *arg1 = (ppc::protocol::GrpcServerConfig *) 0 ; + ppc::protocol::EndPoint arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + void *argp2 ; + int res2 = 0 ; + PyObject *swig_obj[2] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "GrpcServerConfig_setEndPoint", 2, 2, swig_obj)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_ppc__protocol__GrpcServerConfig, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GrpcServerConfig_setEndPoint" "', argument " "1"" of type '" "ppc::protocol::GrpcServerConfig *""'"); + } + arg1 = reinterpret_cast< ppc::protocol::GrpcServerConfig * >(argp1); + { + res2 = SWIG_ConvertPtr(swig_obj[1], &argp2, SWIGTYPE_p_ppc__protocol__EndPoint, 0 | 0); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "GrpcServerConfig_setEndPoint" "', argument " "2"" of type '" "ppc::protocol::EndPoint""'"); + } + if (!argp2) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "GrpcServerConfig_setEndPoint" "', argument " "2"" of type '" "ppc::protocol::EndPoint""'"); + } else { + ppc::protocol::EndPoint * temp = reinterpret_cast< ppc::protocol::EndPoint * >(argp2); + arg2 = *temp; + if (SWIG_IsNewObj(res2)) delete temp; + } + } + { + try { + (arg1)->setEndPoint(arg2); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_GrpcServerConfig_setEnableHealthCheck(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::GrpcServerConfig *arg1 = (ppc::protocol::GrpcServerConfig *) 0 ; + bool arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + bool val2 ; + int ecode2 = 0 ; + PyObject *swig_obj[2] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "GrpcServerConfig_setEnableHealthCheck", 2, 2, swig_obj)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_ppc__protocol__GrpcServerConfig, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GrpcServerConfig_setEnableHealthCheck" "', argument " "1"" of type '" "ppc::protocol::GrpcServerConfig *""'"); + } + arg1 = reinterpret_cast< ppc::protocol::GrpcServerConfig * >(argp1); + ecode2 = SWIG_AsVal_bool(swig_obj[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "GrpcServerConfig_setEnableHealthCheck" "', argument " "2"" of type '" "bool""'"); + } + arg2 = static_cast< bool >(val2); + { + try { + (arg1)->setEnableHealthCheck(arg2); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_GrpcServerConfig_endPoint(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::GrpcServerConfig *arg1 = (ppc::protocol::GrpcServerConfig *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + ppc::protocol::EndPoint *result = 0 ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_ppc__protocol__GrpcServerConfig, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GrpcServerConfig_endPoint" "', argument " "1"" of type '" "ppc::protocol::GrpcServerConfig const *""'"); + } + arg1 = reinterpret_cast< ppc::protocol::GrpcServerConfig * >(argp1); + { + try { + result = (ppc::protocol::EndPoint *) &((ppc::protocol::GrpcServerConfig const *)arg1)->endPoint(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_ppc__protocol__EndPoint, 0 | 0 ); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_GrpcServerConfig_mutableEndPoint(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::GrpcServerConfig *arg1 = (ppc::protocol::GrpcServerConfig *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + ppc::protocol::EndPoint *result = 0 ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_ppc__protocol__GrpcServerConfig, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GrpcServerConfig_mutableEndPoint" "', argument " "1"" of type '" "ppc::protocol::GrpcServerConfig *""'"); + } + arg1 = reinterpret_cast< ppc::protocol::GrpcServerConfig * >(argp1); + { + try { + result = (ppc::protocol::EndPoint *) &(arg1)->mutableEndPoint(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_ppc__protocol__EndPoint, 0 | 0 ); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_GrpcServerConfig_enableHealthCheck(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::GrpcServerConfig *arg1 = (ppc::protocol::GrpcServerConfig *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + bool result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_ppc__protocol__GrpcServerConfig, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GrpcServerConfig_enableHealthCheck" "', argument " "1"" of type '" "ppc::protocol::GrpcServerConfig const *""'"); + } + arg1 = reinterpret_cast< ppc::protocol::GrpcServerConfig * >(argp1); + { + try { + result = (bool)((ppc::protocol::GrpcServerConfig const *)arg1)->enableHealthCheck(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_From_bool(static_cast< bool >(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_GrpcServerConfig_grpcConfig(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::GrpcServerConfig *arg1 = (ppc::protocol::GrpcServerConfig *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + ppc::protocol::GrpcConfig::Ptr *result = 0 ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_ppc__protocol__GrpcServerConfig, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GrpcServerConfig_grpcConfig" "', argument " "1"" of type '" "ppc::protocol::GrpcServerConfig const *""'"); + } + arg1 = reinterpret_cast< ppc::protocol::GrpcServerConfig * >(argp1); + { + try { + result = (ppc::protocol::GrpcConfig::Ptr *) &((ppc::protocol::GrpcServerConfig const *)arg1)->grpcConfig(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + { + std::shared_ptr< ppc::protocol::GrpcConfig > *smartresult = *result ? new std::shared_ptr< ppc::protocol::GrpcConfig >(*result) : 0; + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(smartresult), SWIGTYPE_p_std__shared_ptrT_ppc__protocol__GrpcConfig_t, SWIG_POINTER_OWN); + } + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *GrpcServerConfig_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *obj; + if (!SWIG_Python_UnpackTuple(args, "swigregister", 1, 1, &obj)) return NULL; + SWIG_TypeNewClientData(SWIGTYPE_p_ppc__protocol__GrpcServerConfig, SWIG_NewClientData(obj)); + return SWIG_Py_Void(); +} + +SWIGINTERN PyObject *GrpcServerConfig_swiginit(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + return SWIG_Python_InitShadowInstance(args); +} + +SWIGINTERN PyObject *_wrap_printGrpcConfig(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::GrpcConfig::Ptr *arg1 = 0 ; + void *argp1 ; + int res1 = 0 ; + ppc::protocol::GrpcConfig::Ptr tempshared1 ; + PyObject *swig_obj[1] ; + std::string result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__GrpcConfig_t, 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "printGrpcConfig" "', argument " "1"" of type '" "ppc::protocol::GrpcConfig::Ptr const &""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + if (argp1) tempshared1 = *reinterpret_cast< ppc::protocol::GrpcConfig::Ptr * >(argp1); + delete reinterpret_cast< ppc::protocol::GrpcConfig::Ptr * >(argp1); + arg1 = &tempshared1; + } else { + arg1 = (argp1) ? reinterpret_cast< ppc::protocol::GrpcConfig::Ptr * >(argp1) : &tempshared1; + } + } + { + try { + result = ppc::protocol::printGrpcConfig((std::shared_ptr< ppc::protocol::GrpcConfig > const &)*arg1); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_From_std_string(static_cast< std::string >(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_delete_MessageOptionalHeader(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::MessageOptionalHeader *arg1 = (ppc::protocol::MessageOptionalHeader *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::MessageOptionalHeader > tempshared1 ; + std::shared_ptr< ppc::protocol::MessageOptionalHeader > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageOptionalHeader_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_MessageOptionalHeader" "', argument " "1"" of type '" "ppc::protocol::MessageOptionalHeader *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::protocol::MessageOptionalHeader > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::protocol::MessageOptionalHeader > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageOptionalHeader * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::protocol::MessageOptionalHeader > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageOptionalHeader * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + (void)arg1; delete smartarg1; + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_MessageOptionalHeader_encode(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::MessageOptionalHeader *arg1 = (ppc::protocol::MessageOptionalHeader *) 0 ; + bcos::bytes *arg2 = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::MessageOptionalHeader const > tempshared1 ; + std::shared_ptr< ppc::protocol::MessageOptionalHeader const > *smartarg1 = 0 ; + void *argp2 = 0 ; + int res2 = 0 ; + std::shared_ptr< bcos::bytes > tempshared2 ; + PyObject *swig_obj[2] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "MessageOptionalHeader_encode", 2, 2, swig_obj)) SWIG_fail; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageOptionalHeader_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "MessageOptionalHeader_encode" "', argument " "1"" of type '" "ppc::protocol::MessageOptionalHeader const *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< const ppc::protocol::MessageOptionalHeader > * >(argp1); + delete reinterpret_cast< std::shared_ptr< const ppc::protocol::MessageOptionalHeader > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageOptionalHeader * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< const ppc::protocol::MessageOptionalHeader > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageOptionalHeader * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + int newmem = 0; + res2 = SWIG_ConvertPtrAndOwn(swig_obj[1], &argp2, SWIGTYPE_p_std__shared_ptrT_bcos__bytes_t, 0 , &newmem); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "MessageOptionalHeader_encode" "', argument " "2"" of type '" "bcos::bytes &""'"); + } + if (!argp2) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "MessageOptionalHeader_encode" "', argument " "2"" of type '" "bcos::bytes &""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared2 = *reinterpret_cast< std::shared_ptr< bcos::bytes > * >(argp2); + delete reinterpret_cast< std::shared_ptr< bcos::bytes > * >(argp2); + arg2 = const_cast< bcos::bytes * >(tempshared2.get()); + } else { + arg2 = const_cast< bcos::bytes * >(reinterpret_cast< std::shared_ptr< bcos::bytes > * >(argp2)->get()); + } + } + { + try { + ((ppc::protocol::MessageOptionalHeader const *)arg1)->encode(*arg2); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_MessageOptionalHeader_decode(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::MessageOptionalHeader *arg1 = (ppc::protocol::MessageOptionalHeader *) 0 ; + bcos::bytesConstRef arg2 ; + uint64_t arg3 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::MessageOptionalHeader > tempshared1 ; + std::shared_ptr< ppc::protocol::MessageOptionalHeader > *smartarg1 = 0 ; + void *argp2 ; + int res2 = 0 ; + unsigned long long val3 ; + int ecode3 = 0 ; + PyObject *swig_obj[3] ; + int64_t result; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "MessageOptionalHeader_decode", 3, 3, swig_obj)) SWIG_fail; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageOptionalHeader_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "MessageOptionalHeader_decode" "', argument " "1"" of type '" "ppc::protocol::MessageOptionalHeader *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::protocol::MessageOptionalHeader > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::protocol::MessageOptionalHeader > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageOptionalHeader * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::protocol::MessageOptionalHeader > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageOptionalHeader * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + res2 = SWIG_ConvertPtr(swig_obj[1], &argp2, SWIGTYPE_p_bcos__bytesConstRef, 0 | 0); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "MessageOptionalHeader_decode" "', argument " "2"" of type '" "bcos::bytesConstRef""'"); + } + if (!argp2) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "MessageOptionalHeader_decode" "', argument " "2"" of type '" "bcos::bytesConstRef""'"); + } else { + bcos::bytesConstRef * temp = reinterpret_cast< bcos::bytesConstRef * >(argp2); + arg2 = *temp; + if (SWIG_IsNewObj(res2)) delete temp; + } + } + ecode3 = SWIG_AsVal_unsigned_SS_long_SS_long(swig_obj[2], &val3); + if (!SWIG_IsOK(ecode3)) { + SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "MessageOptionalHeader_decode" "', argument " "3"" of type '" "uint64_t""'"); + } + arg3 = static_cast< uint64_t >(val3); + { + try { + result = (int64_t)(arg1)->decode(arg2,arg3); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_From_long_SS_long(static_cast< long long >(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_MessageOptionalHeader_componentType(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::MessageOptionalHeader *arg1 = (ppc::protocol::MessageOptionalHeader *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::MessageOptionalHeader const > tempshared1 ; + std::shared_ptr< ppc::protocol::MessageOptionalHeader const > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + std::string result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageOptionalHeader_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "MessageOptionalHeader_componentType" "', argument " "1"" of type '" "ppc::protocol::MessageOptionalHeader const *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< const ppc::protocol::MessageOptionalHeader > * >(argp1); + delete reinterpret_cast< std::shared_ptr< const ppc::protocol::MessageOptionalHeader > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageOptionalHeader * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< const ppc::protocol::MessageOptionalHeader > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageOptionalHeader * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + result = ((ppc::protocol::MessageOptionalHeader const *)arg1)->componentType(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_From_std_string(static_cast< std::string >(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_MessageOptionalHeader_setComponentType(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::MessageOptionalHeader *arg1 = (ppc::protocol::MessageOptionalHeader *) 0 ; + std::string arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::MessageOptionalHeader > tempshared1 ; + std::shared_ptr< ppc::protocol::MessageOptionalHeader > *smartarg1 = 0 ; + PyObject *swig_obj[2] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "MessageOptionalHeader_setComponentType", 2, 2, swig_obj)) SWIG_fail; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageOptionalHeader_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "MessageOptionalHeader_setComponentType" "', argument " "1"" of type '" "ppc::protocol::MessageOptionalHeader *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::protocol::MessageOptionalHeader > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::protocol::MessageOptionalHeader > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageOptionalHeader * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::protocol::MessageOptionalHeader > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageOptionalHeader * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + std::string *ptr = (std::string *)0; + int res = SWIG_AsPtr_std_string(swig_obj[1], &ptr); + if (!SWIG_IsOK(res) || !ptr) { + SWIG_exception_fail(SWIG_ArgError((ptr ? res : SWIG_TypeError)), "in method '" "MessageOptionalHeader_setComponentType" "', argument " "2"" of type '" "std::string""'"); + } + arg2 = *ptr; + if (SWIG_IsNewObj(res)) delete ptr; + } + { + try { + (arg1)->setComponentType(arg2); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_MessageOptionalHeader_srcNodeBuffer(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::MessageOptionalHeader *arg1 = (ppc::protocol::MessageOptionalHeader *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::MessageOptionalHeader const > tempshared1 ; + std::shared_ptr< ppc::protocol::MessageOptionalHeader const > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + OutputBuffer result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageOptionalHeader_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "MessageOptionalHeader_srcNodeBuffer" "', argument " "1"" of type '" "ppc::protocol::MessageOptionalHeader const *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< const ppc::protocol::MessageOptionalHeader > * >(argp1); + delete reinterpret_cast< std::shared_ptr< const ppc::protocol::MessageOptionalHeader > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageOptionalHeader * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< const ppc::protocol::MessageOptionalHeader > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageOptionalHeader * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + result = ((ppc::protocol::MessageOptionalHeader const *)arg1)->srcNodeBuffer(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + { + resultobj = PyBytes_FromStringAndSize((const char *)(&result)->data, (&result)->len); + } + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_MessageOptionalHeader_setSrcNodeBuffer(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::MessageOptionalHeader *arg1 = (ppc::protocol::MessageOptionalHeader *) 0 ; + char *arg2 = (char *) 0 ; + uint64_t arg3 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::MessageOptionalHeader > tempshared1 ; + std::shared_ptr< ppc::protocol::MessageOptionalHeader > *smartarg1 = 0 ; + PyObject *swig_obj[2] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "MessageOptionalHeader_setSrcNodeBuffer", 2, 2, swig_obj)) SWIG_fail; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageOptionalHeader_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "MessageOptionalHeader_setSrcNodeBuffer" "', argument " "1"" of type '" "ppc::protocol::MessageOptionalHeader *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::protocol::MessageOptionalHeader > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::protocol::MessageOptionalHeader > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageOptionalHeader * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::protocol::MessageOptionalHeader > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageOptionalHeader * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + int res; Py_ssize_t size = 0; const void *buf = 0; +#ifndef Py_LIMITED_API + Py_buffer view; + res = PyObject_GetBuffer(swig_obj[1], &view, PyBUF_CONTIG_RO); +#else +#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated" +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#elif defined(_MSC_VER) +#pragma warning(push) +#pragma warning(disable: 4996) +#endif + res = PyObject_AsReadBuffer(swig_obj[1], &buf, &size); +#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) +#pragma GCC diagnostic pop +#elif defined(_MSC_VER) +#pragma warning(pop) +#endif +#endif + if (res < 0) { + PyErr_Clear(); + SWIG_exception_fail(SWIG_ArgError(res), "in method '" "MessageOptionalHeader_setSrcNodeBuffer" "', argument " "2"" of type '" "(char* data, uint64_t length)""'"); + } +#ifndef Py_LIMITED_API + size = view.len; + buf = view.buf; + PyBuffer_Release(&view); +#endif + arg2 = (char *) buf; + arg3 = (uint64_t) (size / sizeof(char)); + } + { + try { + (arg1)->setSrcNodeBuffer(arg2,arg3); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_MessageOptionalHeader_dstNodeBuffer(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::MessageOptionalHeader *arg1 = (ppc::protocol::MessageOptionalHeader *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::MessageOptionalHeader const > tempshared1 ; + std::shared_ptr< ppc::protocol::MessageOptionalHeader const > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + OutputBuffer result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageOptionalHeader_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "MessageOptionalHeader_dstNodeBuffer" "', argument " "1"" of type '" "ppc::protocol::MessageOptionalHeader const *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< const ppc::protocol::MessageOptionalHeader > * >(argp1); + delete reinterpret_cast< std::shared_ptr< const ppc::protocol::MessageOptionalHeader > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageOptionalHeader * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< const ppc::protocol::MessageOptionalHeader > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageOptionalHeader * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + result = ((ppc::protocol::MessageOptionalHeader const *)arg1)->dstNodeBuffer(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + { + resultobj = PyBytes_FromStringAndSize((const char *)(&result)->data, (&result)->len); + } + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_MessageOptionalHeader_setDstNodeBuffer(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::MessageOptionalHeader *arg1 = (ppc::protocol::MessageOptionalHeader *) 0 ; + char *arg2 = (char *) 0 ; + uint64_t arg3 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::MessageOptionalHeader > tempshared1 ; + std::shared_ptr< ppc::protocol::MessageOptionalHeader > *smartarg1 = 0 ; + PyObject *swig_obj[2] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "MessageOptionalHeader_setDstNodeBuffer", 2, 2, swig_obj)) SWIG_fail; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageOptionalHeader_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "MessageOptionalHeader_setDstNodeBuffer" "', argument " "1"" of type '" "ppc::protocol::MessageOptionalHeader *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::protocol::MessageOptionalHeader > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::protocol::MessageOptionalHeader > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageOptionalHeader * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::protocol::MessageOptionalHeader > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageOptionalHeader * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + int res; Py_ssize_t size = 0; const void *buf = 0; +#ifndef Py_LIMITED_API + Py_buffer view; + res = PyObject_GetBuffer(swig_obj[1], &view, PyBUF_CONTIG_RO); +#else +#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated" +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#elif defined(_MSC_VER) +#pragma warning(push) +#pragma warning(disable: 4996) +#endif + res = PyObject_AsReadBuffer(swig_obj[1], &buf, &size); +#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) +#pragma GCC diagnostic pop +#elif defined(_MSC_VER) +#pragma warning(pop) +#endif +#endif + if (res < 0) { + PyErr_Clear(); + SWIG_exception_fail(SWIG_ArgError(res), "in method '" "MessageOptionalHeader_setDstNodeBuffer" "', argument " "2"" of type '" "(char* data, uint64_t length)""'"); + } +#ifndef Py_LIMITED_API + size = view.len; + buf = view.buf; + PyBuffer_Release(&view); +#endif + arg2 = (char *) buf; + arg3 = (uint64_t) (size / sizeof(char)); + } + { + try { + (arg1)->setDstNodeBuffer(arg2,arg3); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_MessageOptionalHeader_dstInst(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::MessageOptionalHeader *arg1 = (ppc::protocol::MessageOptionalHeader *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::MessageOptionalHeader const > tempshared1 ; + std::shared_ptr< ppc::protocol::MessageOptionalHeader const > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + std::string *result = 0 ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageOptionalHeader_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "MessageOptionalHeader_dstInst" "', argument " "1"" of type '" "ppc::protocol::MessageOptionalHeader const *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< const ppc::protocol::MessageOptionalHeader > * >(argp1); + delete reinterpret_cast< std::shared_ptr< const ppc::protocol::MessageOptionalHeader > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageOptionalHeader * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< const ppc::protocol::MessageOptionalHeader > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageOptionalHeader * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + result = (std::string *) &((ppc::protocol::MessageOptionalHeader const *)arg1)->dstInst(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_From_std_string(static_cast< std::string >(*result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_MessageOptionalHeader_setDstInst(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::MessageOptionalHeader *arg1 = (ppc::protocol::MessageOptionalHeader *) 0 ; + std::string *arg2 = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::MessageOptionalHeader > tempshared1 ; + std::shared_ptr< ppc::protocol::MessageOptionalHeader > *smartarg1 = 0 ; + int res2 = SWIG_OLDOBJ ; + PyObject *swig_obj[2] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "MessageOptionalHeader_setDstInst", 2, 2, swig_obj)) SWIG_fail; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageOptionalHeader_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "MessageOptionalHeader_setDstInst" "', argument " "1"" of type '" "ppc::protocol::MessageOptionalHeader *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::protocol::MessageOptionalHeader > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::protocol::MessageOptionalHeader > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageOptionalHeader * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::protocol::MessageOptionalHeader > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageOptionalHeader * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + std::string *ptr = (std::string *)0; + res2 = SWIG_AsPtr_std_string(swig_obj[1], &ptr); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "MessageOptionalHeader_setDstInst" "', argument " "2"" of type '" "std::string const &""'"); + } + if (!ptr) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "MessageOptionalHeader_setDstInst" "', argument " "2"" of type '" "std::string const &""'"); + } + arg2 = ptr; + } + { + try { + (arg1)->setDstInst((std::string const &)*arg2); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + if (SWIG_IsNewObj(res2)) delete arg2; + return resultobj; +fail: + if (SWIG_IsNewObj(res2)) delete arg2; + return NULL; +} + + +SWIGINTERN PyObject *_wrap_MessageOptionalHeader_topic(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::MessageOptionalHeader *arg1 = (ppc::protocol::MessageOptionalHeader *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::MessageOptionalHeader const > tempshared1 ; + std::shared_ptr< ppc::protocol::MessageOptionalHeader const > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + std::string *result = 0 ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageOptionalHeader_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "MessageOptionalHeader_topic" "', argument " "1"" of type '" "ppc::protocol::MessageOptionalHeader const *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< const ppc::protocol::MessageOptionalHeader > * >(argp1); + delete reinterpret_cast< std::shared_ptr< const ppc::protocol::MessageOptionalHeader > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageOptionalHeader * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< const ppc::protocol::MessageOptionalHeader > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageOptionalHeader * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + result = (std::string *) &((ppc::protocol::MessageOptionalHeader const *)arg1)->topic(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_From_std_string(static_cast< std::string >(*result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_MessageOptionalHeader_setTopic__SWIG_0(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + ppc::protocol::MessageOptionalHeader *arg1 = (ppc::protocol::MessageOptionalHeader *) 0 ; + std::string *arg2 = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::MessageOptionalHeader > tempshared1 ; + std::shared_ptr< ppc::protocol::MessageOptionalHeader > *smartarg1 = 0 ; + void *argp2 = 0 ; + int res2 = 0 ; + std::unique_ptr< std::string > rvrdeleter2 ; + + (void)self; + if ((nobjs < 2) || (nobjs > 2)) SWIG_fail; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageOptionalHeader_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "MessageOptionalHeader_setTopic" "', argument " "1"" of type '" "ppc::protocol::MessageOptionalHeader *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::protocol::MessageOptionalHeader > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::protocol::MessageOptionalHeader > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageOptionalHeader * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::protocol::MessageOptionalHeader > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageOptionalHeader * >((smartarg1 ? smartarg1->get() : 0)); + } + } + res2 = SWIG_ConvertPtr(swig_obj[1], &argp2, SWIGTYPE_p_std__string, SWIG_POINTER_RELEASE | 0 ); + if (!SWIG_IsOK(res2)) { + if (res2 == SWIG_ERROR_RELEASE_NOT_OWNED) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "MessageOptionalHeader_setTopic" "', cannot release ownership as memory is not owned for argument " "2"" of type '" "std::string &&""'"); + } else { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "MessageOptionalHeader_setTopic" "', argument " "2"" of type '" "std::string &&""'"); + } + } + if (!argp2) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "MessageOptionalHeader_setTopic" "', argument " "2"" of type '" "std::string &&""'"); + } + arg2 = reinterpret_cast< std::string * >(argp2); + rvrdeleter2.reset(arg2); + { + try { + (arg1)->setTopic((std::string &&)*arg2); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_MessageOptionalHeader_setTopic__SWIG_1(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + ppc::protocol::MessageOptionalHeader *arg1 = (ppc::protocol::MessageOptionalHeader *) 0 ; + std::string *arg2 = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::MessageOptionalHeader > tempshared1 ; + std::shared_ptr< ppc::protocol::MessageOptionalHeader > *smartarg1 = 0 ; + int res2 = SWIG_OLDOBJ ; + + (void)self; + if ((nobjs < 2) || (nobjs > 2)) SWIG_fail; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageOptionalHeader_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "MessageOptionalHeader_setTopic" "', argument " "1"" of type '" "ppc::protocol::MessageOptionalHeader *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::protocol::MessageOptionalHeader > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::protocol::MessageOptionalHeader > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageOptionalHeader * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::protocol::MessageOptionalHeader > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageOptionalHeader * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + std::string *ptr = (std::string *)0; + res2 = SWIG_AsPtr_std_string(swig_obj[1], &ptr); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "MessageOptionalHeader_setTopic" "', argument " "2"" of type '" "std::string const &""'"); + } + if (!ptr) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "MessageOptionalHeader_setTopic" "', argument " "2"" of type '" "std::string const &""'"); + } + arg2 = ptr; + } + { + try { + (arg1)->setTopic((std::string const &)*arg2); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + if (SWIG_IsNewObj(res2)) delete arg2; + return resultobj; +fail: + if (SWIG_IsNewObj(res2)) delete arg2; + return NULL; +} + + +SWIGINTERN PyObject *_wrap_MessageOptionalHeader_setTopic(PyObject *self, PyObject *args) { + Py_ssize_t argc; + PyObject *argv[3] = { + 0 + }; + + if (!(argc = SWIG_Python_UnpackTuple(args, "MessageOptionalHeader_setTopic", 0, 2, argv))) SWIG_fail; + --argc; + if (argc == 2) { + int _v = 0; + int res = SWIG_ConvertPtr(argv[0], 0, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageOptionalHeader_t, 0); + _v = SWIG_CheckState(res); + if (_v) { + void *vptr = 0; + int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_std__string, SWIG_POINTER_NO_NULL); + _v = SWIG_CheckState(res); + if (_v) { + return _wrap_MessageOptionalHeader_setTopic__SWIG_0(self, argc, argv); + } + } + } + if (argc == 2) { + int _v = 0; + int res = SWIG_ConvertPtr(argv[0], 0, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageOptionalHeader_t, 0); + _v = SWIG_CheckState(res); + if (_v) { + int res = SWIG_AsPtr_std_string(argv[1], (std::string**)(0)); + _v = SWIG_CheckState(res); + if (_v) { + return _wrap_MessageOptionalHeader_setTopic__SWIG_1(self, argc, argv); + } + } + } + +fail: + SWIG_Python_RaiseOrModifyTypeError("Wrong number or type of arguments for overloaded function 'MessageOptionalHeader_setTopic'.\n" + " Possible C/C++ prototypes are:\n" + " ppc::protocol::MessageOptionalHeader::setTopic(std::string &&)\n" + " ppc::protocol::MessageOptionalHeader::setTopic(std::string const &)\n"); + return 0; +} + + +SWIGINTERN PyObject *_wrap_MessageOptionalHeader_srcInst(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::MessageOptionalHeader *arg1 = (ppc::protocol::MessageOptionalHeader *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::MessageOptionalHeader const > tempshared1 ; + std::shared_ptr< ppc::protocol::MessageOptionalHeader const > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + std::string result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageOptionalHeader_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "MessageOptionalHeader_srcInst" "', argument " "1"" of type '" "ppc::protocol::MessageOptionalHeader const *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< const ppc::protocol::MessageOptionalHeader > * >(argp1); + delete reinterpret_cast< std::shared_ptr< const ppc::protocol::MessageOptionalHeader > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageOptionalHeader * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< const ppc::protocol::MessageOptionalHeader > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageOptionalHeader * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + result = ((ppc::protocol::MessageOptionalHeader const *)arg1)->srcInst(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_From_std_string(static_cast< std::string >(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_MessageOptionalHeader_setSrcInst(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::MessageOptionalHeader *arg1 = (ppc::protocol::MessageOptionalHeader *) 0 ; + std::string *arg2 = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::MessageOptionalHeader > tempshared1 ; + std::shared_ptr< ppc::protocol::MessageOptionalHeader > *smartarg1 = 0 ; + int res2 = SWIG_OLDOBJ ; + PyObject *swig_obj[2] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "MessageOptionalHeader_setSrcInst", 2, 2, swig_obj)) SWIG_fail; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageOptionalHeader_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "MessageOptionalHeader_setSrcInst" "', argument " "1"" of type '" "ppc::protocol::MessageOptionalHeader *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::protocol::MessageOptionalHeader > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::protocol::MessageOptionalHeader > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageOptionalHeader * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::protocol::MessageOptionalHeader > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageOptionalHeader * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + std::string *ptr = (std::string *)0; + res2 = SWIG_AsPtr_std_string(swig_obj[1], &ptr); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "MessageOptionalHeader_setSrcInst" "', argument " "2"" of type '" "std::string const &""'"); + } + if (!ptr) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "MessageOptionalHeader_setSrcInst" "', argument " "2"" of type '" "std::string const &""'"); + } + arg2 = ptr; + } + { + try { + (arg1)->setSrcInst((std::string const &)*arg2); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + if (SWIG_IsNewObj(res2)) delete arg2; + return resultobj; +fail: + if (SWIG_IsNewObj(res2)) delete arg2; + return NULL; +} + + +SWIGINTERN PyObject *MessageOptionalHeader_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *obj; + if (!SWIG_Python_UnpackTuple(args, "swigregister", 1, 1, &obj)) return NULL; + SWIG_TypeNewClientData(SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageOptionalHeader_t, SWIG_NewClientData(obj)); + return SWIG_Py_Void(); +} + +SWIGINTERN PyObject *_wrap_delete_MessageHeader(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::MessageHeader *arg1 = (ppc::protocol::MessageHeader *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::MessageHeader > tempshared1 ; + std::shared_ptr< ppc::protocol::MessageHeader > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageHeader_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_MessageHeader" "', argument " "1"" of type '" "ppc::protocol::MessageHeader *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::protocol::MessageHeader > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::protocol::MessageHeader > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageHeader * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::protocol::MessageHeader > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageHeader * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + (void)arg1; delete smartarg1; + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_MessageHeader_encode(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::MessageHeader *arg1 = (ppc::protocol::MessageHeader *) 0 ; + bcos::bytes *arg2 = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::MessageHeader const > tempshared1 ; + std::shared_ptr< ppc::protocol::MessageHeader const > *smartarg1 = 0 ; + void *argp2 = 0 ; + int res2 = 0 ; + std::shared_ptr< bcos::bytes > tempshared2 ; + PyObject *swig_obj[2] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "MessageHeader_encode", 2, 2, swig_obj)) SWIG_fail; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageHeader_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "MessageHeader_encode" "', argument " "1"" of type '" "ppc::protocol::MessageHeader const *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< const ppc::protocol::MessageHeader > * >(argp1); + delete reinterpret_cast< std::shared_ptr< const ppc::protocol::MessageHeader > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageHeader * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< const ppc::protocol::MessageHeader > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageHeader * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + int newmem = 0; + res2 = SWIG_ConvertPtrAndOwn(swig_obj[1], &argp2, SWIGTYPE_p_std__shared_ptrT_bcos__bytes_t, 0 , &newmem); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "MessageHeader_encode" "', argument " "2"" of type '" "bcos::bytes &""'"); + } + if (!argp2) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "MessageHeader_encode" "', argument " "2"" of type '" "bcos::bytes &""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared2 = *reinterpret_cast< std::shared_ptr< bcos::bytes > * >(argp2); + delete reinterpret_cast< std::shared_ptr< bcos::bytes > * >(argp2); + arg2 = const_cast< bcos::bytes * >(tempshared2.get()); + } else { + arg2 = const_cast< bcos::bytes * >(reinterpret_cast< std::shared_ptr< bcos::bytes > * >(argp2)->get()); + } + } + { + try { + ((ppc::protocol::MessageHeader const *)arg1)->encode(*arg2); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_MessageHeader_decode(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::MessageHeader *arg1 = (ppc::protocol::MessageHeader *) 0 ; + bcos::bytesConstRef arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::MessageHeader > tempshared1 ; + std::shared_ptr< ppc::protocol::MessageHeader > *smartarg1 = 0 ; + void *argp2 ; + int res2 = 0 ; + PyObject *swig_obj[2] ; + int64_t result; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "MessageHeader_decode", 2, 2, swig_obj)) SWIG_fail; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageHeader_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "MessageHeader_decode" "', argument " "1"" of type '" "ppc::protocol::MessageHeader *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::protocol::MessageHeader > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::protocol::MessageHeader > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageHeader * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::protocol::MessageHeader > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageHeader * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + res2 = SWIG_ConvertPtr(swig_obj[1], &argp2, SWIGTYPE_p_bcos__bytesConstRef, 0 | 0); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "MessageHeader_decode" "', argument " "2"" of type '" "bcos::bytesConstRef""'"); + } + if (!argp2) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "MessageHeader_decode" "', argument " "2"" of type '" "bcos::bytesConstRef""'"); + } else { + bcos::bytesConstRef * temp = reinterpret_cast< bcos::bytesConstRef * >(argp2); + arg2 = *temp; + if (SWIG_IsNewObj(res2)) delete temp; + } + } + { + try { + result = (int64_t)(arg1)->decode(arg2); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_From_long_SS_long(static_cast< long long >(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_MessageHeader_version(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::MessageHeader *arg1 = (ppc::protocol::MessageHeader *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::MessageHeader const > tempshared1 ; + std::shared_ptr< ppc::protocol::MessageHeader const > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + uint8_t result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageHeader_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "MessageHeader_version" "', argument " "1"" of type '" "ppc::protocol::MessageHeader const *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< const ppc::protocol::MessageHeader > * >(argp1); + delete reinterpret_cast< std::shared_ptr< const ppc::protocol::MessageHeader > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageHeader * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< const ppc::protocol::MessageHeader > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageHeader * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + result = (uint8_t)((ppc::protocol::MessageHeader const *)arg1)->version(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_From_unsigned_SS_char(static_cast< unsigned char >(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_MessageHeader_setVersion(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::MessageHeader *arg1 = (ppc::protocol::MessageHeader *) 0 ; + uint16_t arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::MessageHeader > tempshared1 ; + std::shared_ptr< ppc::protocol::MessageHeader > *smartarg1 = 0 ; + unsigned short val2 ; + int ecode2 = 0 ; + PyObject *swig_obj[2] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "MessageHeader_setVersion", 2, 2, swig_obj)) SWIG_fail; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageHeader_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "MessageHeader_setVersion" "', argument " "1"" of type '" "ppc::protocol::MessageHeader *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::protocol::MessageHeader > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::protocol::MessageHeader > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageHeader * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::protocol::MessageHeader > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageHeader * >((smartarg1 ? smartarg1->get() : 0)); + } + } + ecode2 = SWIG_AsVal_unsigned_SS_short(swig_obj[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "MessageHeader_setVersion" "', argument " "2"" of type '" "uint16_t""'"); + } + arg2 = static_cast< uint16_t >(val2); + { + try { + (arg1)->setVersion(arg2); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_MessageHeader_traceID(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::MessageHeader *arg1 = (ppc::protocol::MessageHeader *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::MessageHeader const > tempshared1 ; + std::shared_ptr< ppc::protocol::MessageHeader const > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + std::string *result = 0 ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageHeader_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "MessageHeader_traceID" "', argument " "1"" of type '" "ppc::protocol::MessageHeader const *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< const ppc::protocol::MessageHeader > * >(argp1); + delete reinterpret_cast< std::shared_ptr< const ppc::protocol::MessageHeader > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageHeader * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< const ppc::protocol::MessageHeader > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageHeader * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + result = (std::string *) &((ppc::protocol::MessageHeader const *)arg1)->traceID(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_From_std_string(static_cast< std::string >(*result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_MessageHeader_setTraceID(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::MessageHeader *arg1 = (ppc::protocol::MessageHeader *) 0 ; + std::string arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::MessageHeader > tempshared1 ; + std::shared_ptr< ppc::protocol::MessageHeader > *smartarg1 = 0 ; + PyObject *swig_obj[2] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "MessageHeader_setTraceID", 2, 2, swig_obj)) SWIG_fail; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageHeader_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "MessageHeader_setTraceID" "', argument " "1"" of type '" "ppc::protocol::MessageHeader *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::protocol::MessageHeader > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::protocol::MessageHeader > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageHeader * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::protocol::MessageHeader > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageHeader * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + std::string *ptr = (std::string *)0; + int res = SWIG_AsPtr_std_string(swig_obj[1], &ptr); + if (!SWIG_IsOK(res) || !ptr) { + SWIG_exception_fail(SWIG_ArgError((ptr ? res : SWIG_TypeError)), "in method '" "MessageHeader_setTraceID" "', argument " "2"" of type '" "std::string""'"); + } + arg2 = *ptr; + if (SWIG_IsNewObj(res)) delete ptr; + } + { + try { + (arg1)->setTraceID(arg2); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_MessageHeader_srcGwNode(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::MessageHeader *arg1 = (ppc::protocol::MessageHeader *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::MessageHeader const > tempshared1 ; + std::shared_ptr< ppc::protocol::MessageHeader const > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + std::string *result = 0 ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageHeader_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "MessageHeader_srcGwNode" "', argument " "1"" of type '" "ppc::protocol::MessageHeader const *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< const ppc::protocol::MessageHeader > * >(argp1); + delete reinterpret_cast< std::shared_ptr< const ppc::protocol::MessageHeader > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageHeader * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< const ppc::protocol::MessageHeader > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageHeader * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + result = (std::string *) &((ppc::protocol::MessageHeader const *)arg1)->srcGwNode(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_From_std_string(static_cast< std::string >(*result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_MessageHeader_setSrcGwNode(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::MessageHeader *arg1 = (ppc::protocol::MessageHeader *) 0 ; + std::string *arg2 = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::MessageHeader > tempshared1 ; + std::shared_ptr< ppc::protocol::MessageHeader > *smartarg1 = 0 ; + int res2 = SWIG_OLDOBJ ; + PyObject *swig_obj[2] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "MessageHeader_setSrcGwNode", 2, 2, swig_obj)) SWIG_fail; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageHeader_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "MessageHeader_setSrcGwNode" "', argument " "1"" of type '" "ppc::protocol::MessageHeader *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::protocol::MessageHeader > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::protocol::MessageHeader > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageHeader * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::protocol::MessageHeader > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageHeader * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + std::string *ptr = (std::string *)0; + res2 = SWIG_AsPtr_std_string(swig_obj[1], &ptr); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "MessageHeader_setSrcGwNode" "', argument " "2"" of type '" "std::string const &""'"); + } + if (!ptr) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "MessageHeader_setSrcGwNode" "', argument " "2"" of type '" "std::string const &""'"); + } + arg2 = ptr; + } + { + try { + (arg1)->setSrcGwNode((std::string const &)*arg2); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + if (SWIG_IsNewObj(res2)) delete arg2; + return resultobj; +fail: + if (SWIG_IsNewObj(res2)) delete arg2; + return NULL; +} + + +SWIGINTERN PyObject *_wrap_MessageHeader_dstGwNode(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::MessageHeader *arg1 = (ppc::protocol::MessageHeader *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::MessageHeader const > tempshared1 ; + std::shared_ptr< ppc::protocol::MessageHeader const > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + std::string *result = 0 ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageHeader_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "MessageHeader_dstGwNode" "', argument " "1"" of type '" "ppc::protocol::MessageHeader const *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< const ppc::protocol::MessageHeader > * >(argp1); + delete reinterpret_cast< std::shared_ptr< const ppc::protocol::MessageHeader > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageHeader * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< const ppc::protocol::MessageHeader > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageHeader * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + result = (std::string *) &((ppc::protocol::MessageHeader const *)arg1)->dstGwNode(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_From_std_string(static_cast< std::string >(*result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_MessageHeader_setDstGwNode(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::MessageHeader *arg1 = (ppc::protocol::MessageHeader *) 0 ; + std::string *arg2 = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::MessageHeader > tempshared1 ; + std::shared_ptr< ppc::protocol::MessageHeader > *smartarg1 = 0 ; + int res2 = SWIG_OLDOBJ ; + PyObject *swig_obj[2] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "MessageHeader_setDstGwNode", 2, 2, swig_obj)) SWIG_fail; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageHeader_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "MessageHeader_setDstGwNode" "', argument " "1"" of type '" "ppc::protocol::MessageHeader *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::protocol::MessageHeader > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::protocol::MessageHeader > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageHeader * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::protocol::MessageHeader > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageHeader * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + std::string *ptr = (std::string *)0; + res2 = SWIG_AsPtr_std_string(swig_obj[1], &ptr); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "MessageHeader_setDstGwNode" "', argument " "2"" of type '" "std::string const &""'"); + } + if (!ptr) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "MessageHeader_setDstGwNode" "', argument " "2"" of type '" "std::string const &""'"); + } + arg2 = ptr; + } + { + try { + (arg1)->setDstGwNode((std::string const &)*arg2); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + if (SWIG_IsNewObj(res2)) delete arg2; + return resultobj; +fail: + if (SWIG_IsNewObj(res2)) delete arg2; + return NULL; +} + + +SWIGINTERN PyObject *_wrap_MessageHeader_packetType(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::MessageHeader *arg1 = (ppc::protocol::MessageHeader *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::MessageHeader const > tempshared1 ; + std::shared_ptr< ppc::protocol::MessageHeader const > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + uint16_t result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageHeader_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "MessageHeader_packetType" "', argument " "1"" of type '" "ppc::protocol::MessageHeader const *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< const ppc::protocol::MessageHeader > * >(argp1); + delete reinterpret_cast< std::shared_ptr< const ppc::protocol::MessageHeader > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageHeader * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< const ppc::protocol::MessageHeader > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageHeader * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + result = (uint16_t)((ppc::protocol::MessageHeader const *)arg1)->packetType(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_From_unsigned_SS_short(static_cast< unsigned short >(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_MessageHeader_setPacketType(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::MessageHeader *arg1 = (ppc::protocol::MessageHeader *) 0 ; + uint16_t arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::MessageHeader > tempshared1 ; + std::shared_ptr< ppc::protocol::MessageHeader > *smartarg1 = 0 ; + unsigned short val2 ; + int ecode2 = 0 ; + PyObject *swig_obj[2] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "MessageHeader_setPacketType", 2, 2, swig_obj)) SWIG_fail; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageHeader_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "MessageHeader_setPacketType" "', argument " "1"" of type '" "ppc::protocol::MessageHeader *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::protocol::MessageHeader > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::protocol::MessageHeader > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageHeader * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::protocol::MessageHeader > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageHeader * >((smartarg1 ? smartarg1->get() : 0)); + } + } + ecode2 = SWIG_AsVal_unsigned_SS_short(swig_obj[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "MessageHeader_setPacketType" "', argument " "2"" of type '" "uint16_t""'"); + } + arg2 = static_cast< uint16_t >(val2); + { + try { + (arg1)->setPacketType(arg2); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_MessageHeader_ttl(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::MessageHeader *arg1 = (ppc::protocol::MessageHeader *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::MessageHeader const > tempshared1 ; + std::shared_ptr< ppc::protocol::MessageHeader const > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + int16_t result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageHeader_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "MessageHeader_ttl" "', argument " "1"" of type '" "ppc::protocol::MessageHeader const *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< const ppc::protocol::MessageHeader > * >(argp1); + delete reinterpret_cast< std::shared_ptr< const ppc::protocol::MessageHeader > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageHeader * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< const ppc::protocol::MessageHeader > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageHeader * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + result = (int16_t)((ppc::protocol::MessageHeader const *)arg1)->ttl(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_From_short(static_cast< short >(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_MessageHeader_setTTL(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::MessageHeader *arg1 = (ppc::protocol::MessageHeader *) 0 ; + uint16_t arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::MessageHeader > tempshared1 ; + std::shared_ptr< ppc::protocol::MessageHeader > *smartarg1 = 0 ; + unsigned short val2 ; + int ecode2 = 0 ; + PyObject *swig_obj[2] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "MessageHeader_setTTL", 2, 2, swig_obj)) SWIG_fail; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageHeader_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "MessageHeader_setTTL" "', argument " "1"" of type '" "ppc::protocol::MessageHeader *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::protocol::MessageHeader > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::protocol::MessageHeader > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageHeader * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::protocol::MessageHeader > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageHeader * >((smartarg1 ? smartarg1->get() : 0)); + } + } + ecode2 = SWIG_AsVal_unsigned_SS_short(swig_obj[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "MessageHeader_setTTL" "', argument " "2"" of type '" "uint16_t""'"); + } + arg2 = static_cast< uint16_t >(val2); + { + try { + (arg1)->setTTL(arg2); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_MessageHeader_ext(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::MessageHeader *arg1 = (ppc::protocol::MessageHeader *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::MessageHeader const > tempshared1 ; + std::shared_ptr< ppc::protocol::MessageHeader const > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + uint16_t result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageHeader_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "MessageHeader_ext" "', argument " "1"" of type '" "ppc::protocol::MessageHeader const *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< const ppc::protocol::MessageHeader > * >(argp1); + delete reinterpret_cast< std::shared_ptr< const ppc::protocol::MessageHeader > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageHeader * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< const ppc::protocol::MessageHeader > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageHeader * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + result = (uint16_t)((ppc::protocol::MessageHeader const *)arg1)->ext(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_From_unsigned_SS_short(static_cast< unsigned short >(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_MessageHeader_setExt(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::MessageHeader *arg1 = (ppc::protocol::MessageHeader *) 0 ; + uint16_t arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::MessageHeader > tempshared1 ; + std::shared_ptr< ppc::protocol::MessageHeader > *smartarg1 = 0 ; + unsigned short val2 ; + int ecode2 = 0 ; + PyObject *swig_obj[2] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "MessageHeader_setExt", 2, 2, swig_obj)) SWIG_fail; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageHeader_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "MessageHeader_setExt" "', argument " "1"" of type '" "ppc::protocol::MessageHeader *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::protocol::MessageHeader > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::protocol::MessageHeader > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageHeader * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::protocol::MessageHeader > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageHeader * >((smartarg1 ? smartarg1->get() : 0)); + } + } + ecode2 = SWIG_AsVal_unsigned_SS_short(swig_obj[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "MessageHeader_setExt" "', argument " "2"" of type '" "uint16_t""'"); + } + arg2 = static_cast< uint16_t >(val2); + { + try { + (arg1)->setExt(arg2); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_MessageHeader_optionalField(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::MessageHeader *arg1 = (ppc::protocol::MessageHeader *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::MessageHeader const > tempshared1 ; + std::shared_ptr< ppc::protocol::MessageHeader const > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + ppc::protocol::MessageOptionalHeader::Ptr result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageHeader_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "MessageHeader_optionalField" "', argument " "1"" of type '" "ppc::protocol::MessageHeader const *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< const ppc::protocol::MessageHeader > * >(argp1); + delete reinterpret_cast< std::shared_ptr< const ppc::protocol::MessageHeader > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageHeader * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< const ppc::protocol::MessageHeader > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageHeader * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + result = ((ppc::protocol::MessageHeader const *)arg1)->optionalField(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + { + std::shared_ptr< ppc::protocol::MessageOptionalHeader > *smartresult = result ? new std::shared_ptr< ppc::protocol::MessageOptionalHeader >(result) : 0; + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(smartresult), SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageOptionalHeader_t, SWIG_POINTER_OWN); + } + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_MessageHeader_setOptionalField(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::MessageHeader *arg1 = (ppc::protocol::MessageHeader *) 0 ; + ppc::protocol::MessageOptionalHeader::Ptr arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::MessageHeader > tempshared1 ; + std::shared_ptr< ppc::protocol::MessageHeader > *smartarg1 = 0 ; + void *argp2 ; + int res2 = 0 ; + PyObject *swig_obj[2] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "MessageHeader_setOptionalField", 2, 2, swig_obj)) SWIG_fail; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageHeader_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "MessageHeader_setOptionalField" "', argument " "1"" of type '" "ppc::protocol::MessageHeader *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::protocol::MessageHeader > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::protocol::MessageHeader > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageHeader * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::protocol::MessageHeader > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageHeader * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + int newmem = 0; + res2 = SWIG_ConvertPtrAndOwn(swig_obj[1], &argp2, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageOptionalHeader_t, 0 , &newmem); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "MessageHeader_setOptionalField" "', argument " "2"" of type '" "ppc::protocol::MessageOptionalHeader::Ptr""'"); + } + if (argp2) arg2 = *(reinterpret_cast< ppc::protocol::MessageOptionalHeader::Ptr * >(argp2)); + if (newmem & SWIG_CAST_NEW_MEMORY) delete reinterpret_cast< ppc::protocol::MessageOptionalHeader::Ptr * >(argp2); + } + { + try { + (arg1)->setOptionalField(arg2); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_MessageHeader_length(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::MessageHeader *arg1 = (ppc::protocol::MessageHeader *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::MessageHeader const > tempshared1 ; + std::shared_ptr< ppc::protocol::MessageHeader const > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + uint16_t result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageHeader_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "MessageHeader_length" "', argument " "1"" of type '" "ppc::protocol::MessageHeader const *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< const ppc::protocol::MessageHeader > * >(argp1); + delete reinterpret_cast< std::shared_ptr< const ppc::protocol::MessageHeader > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageHeader * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< const ppc::protocol::MessageHeader > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageHeader * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + result = (uint16_t)((ppc::protocol::MessageHeader const *)arg1)->length(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_From_unsigned_SS_short(static_cast< unsigned short >(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_MessageHeader_isRespPacket(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::MessageHeader *arg1 = (ppc::protocol::MessageHeader *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::MessageHeader const > tempshared1 ; + std::shared_ptr< ppc::protocol::MessageHeader const > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + bool result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageHeader_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "MessageHeader_isRespPacket" "', argument " "1"" of type '" "ppc::protocol::MessageHeader const *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< const ppc::protocol::MessageHeader > * >(argp1); + delete reinterpret_cast< std::shared_ptr< const ppc::protocol::MessageHeader > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageHeader * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< const ppc::protocol::MessageHeader > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageHeader * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + result = (bool)((ppc::protocol::MessageHeader const *)arg1)->isRespPacket(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_From_bool(static_cast< bool >(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_MessageHeader_setRespPacket(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::MessageHeader *arg1 = (ppc::protocol::MessageHeader *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::MessageHeader > tempshared1 ; + std::shared_ptr< ppc::protocol::MessageHeader > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageHeader_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "MessageHeader_setRespPacket" "', argument " "1"" of type '" "ppc::protocol::MessageHeader *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::protocol::MessageHeader > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::protocol::MessageHeader > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageHeader * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::protocol::MessageHeader > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageHeader * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + (arg1)->setRespPacket(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_MessageHeader_srcP2PNodeIDView(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::MessageHeader *arg1 = (ppc::protocol::MessageHeader *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::MessageHeader const > tempshared1 ; + std::shared_ptr< ppc::protocol::MessageHeader const > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + std::string_view result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageHeader_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "MessageHeader_srcP2PNodeIDView" "', argument " "1"" of type '" "ppc::protocol::MessageHeader const *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< const ppc::protocol::MessageHeader > * >(argp1); + delete reinterpret_cast< std::shared_ptr< const ppc::protocol::MessageHeader > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageHeader * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< const ppc::protocol::MessageHeader > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageHeader * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + result = ((ppc::protocol::MessageHeader const *)arg1)->srcP2PNodeIDView(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_NewPointerObj((new std::string_view(result)), SWIGTYPE_p_std__string_view, SWIG_POINTER_OWN | 0 ); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_MessageHeader_dstP2PNodeIDView(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::MessageHeader *arg1 = (ppc::protocol::MessageHeader *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::MessageHeader const > tempshared1 ; + std::shared_ptr< ppc::protocol::MessageHeader const > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + std::string_view result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageHeader_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "MessageHeader_dstP2PNodeIDView" "', argument " "1"" of type '" "ppc::protocol::MessageHeader const *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< const ppc::protocol::MessageHeader > * >(argp1); + delete reinterpret_cast< std::shared_ptr< const ppc::protocol::MessageHeader > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageHeader * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< const ppc::protocol::MessageHeader > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageHeader * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + result = ((ppc::protocol::MessageHeader const *)arg1)->dstP2PNodeIDView(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_NewPointerObj((new std::string_view(result)), SWIGTYPE_p_std__string_view, SWIG_POINTER_OWN | 0 ); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_MessageHeader_routeType(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::MessageHeader *arg1 = (ppc::protocol::MessageHeader *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::MessageHeader const > tempshared1 ; + std::shared_ptr< ppc::protocol::MessageHeader const > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + uint16_t result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageHeader_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "MessageHeader_routeType" "', argument " "1"" of type '" "ppc::protocol::MessageHeader const *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< const ppc::protocol::MessageHeader > * >(argp1); + delete reinterpret_cast< std::shared_ptr< const ppc::protocol::MessageHeader > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageHeader * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< const ppc::protocol::MessageHeader > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageHeader * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + result = (uint16_t)((ppc::protocol::MessageHeader const *)arg1)->routeType(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_From_unsigned_SS_short(static_cast< unsigned short >(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_MessageHeader_setRouteType(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::MessageHeader *arg1 = (ppc::protocol::MessageHeader *) 0 ; + ppc::protocol::RouteType arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::MessageHeader > tempshared1 ; + std::shared_ptr< ppc::protocol::MessageHeader > *smartarg1 = 0 ; + void *argp2 ; + int res2 = 0 ; + PyObject *swig_obj[2] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "MessageHeader_setRouteType", 2, 2, swig_obj)) SWIG_fail; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageHeader_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "MessageHeader_setRouteType" "', argument " "1"" of type '" "ppc::protocol::MessageHeader *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::protocol::MessageHeader > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::protocol::MessageHeader > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageHeader * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::protocol::MessageHeader > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageHeader * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + res2 = SWIG_ConvertPtr(swig_obj[1], &argp2, SWIGTYPE_p_ppc__protocol__RouteType, 0 | 0); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "MessageHeader_setRouteType" "', argument " "2"" of type '" "ppc::protocol::RouteType""'"); + } + if (!argp2) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "MessageHeader_setRouteType" "', argument " "2"" of type '" "ppc::protocol::RouteType""'"); + } else { + ppc::protocol::RouteType * temp = reinterpret_cast< ppc::protocol::RouteType * >(argp2); + arg2 = *temp; + if (SWIG_IsNewObj(res2)) delete temp; + } + } + { + try { + (arg1)->setRouteType(arg2); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_MessageHeader_hasOptionalField(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::MessageHeader *arg1 = (ppc::protocol::MessageHeader *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::MessageHeader const > tempshared1 ; + std::shared_ptr< ppc::protocol::MessageHeader const > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + bool result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageHeader_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "MessageHeader_hasOptionalField" "', argument " "1"" of type '" "ppc::protocol::MessageHeader const *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< const ppc::protocol::MessageHeader > * >(argp1); + delete reinterpret_cast< std::shared_ptr< const ppc::protocol::MessageHeader > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageHeader * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< const ppc::protocol::MessageHeader > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageHeader * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + result = (bool)((ppc::protocol::MessageHeader const *)arg1)->hasOptionalField(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_From_bool(static_cast< bool >(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *MessageHeader_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *obj; + if (!SWIG_Python_UnpackTuple(args, "swigregister", 1, 1, &obj)) return NULL; + SWIG_TypeNewClientData(SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageHeader_t, SWIG_NewClientData(obj)); + return SWIG_Py_Void(); +} + +SWIGINTERN PyObject *_wrap_delete_Message(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::Message *arg1 = (ppc::protocol::Message *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::Message > tempshared1 ; + std::shared_ptr< ppc::protocol::Message > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__Message_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_Message" "', argument " "1"" of type '" "ppc::protocol::Message *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::protocol::Message > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::protocol::Message > * >(argp1); + arg1 = const_cast< ppc::protocol::Message * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::protocol::Message > * >(argp1); + arg1 = const_cast< ppc::protocol::Message * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + (void)arg1; delete smartarg1; + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_Message_header(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::Message *arg1 = (ppc::protocol::Message *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::Message const > tempshared1 ; + std::shared_ptr< ppc::protocol::Message const > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + ppc::protocol::MessageHeader::Ptr result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__Message_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Message_header" "', argument " "1"" of type '" "ppc::protocol::Message const *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< const ppc::protocol::Message > * >(argp1); + delete reinterpret_cast< std::shared_ptr< const ppc::protocol::Message > * >(argp1); + arg1 = const_cast< ppc::protocol::Message * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< const ppc::protocol::Message > * >(argp1); + arg1 = const_cast< ppc::protocol::Message * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + result = ((ppc::protocol::Message const *)arg1)->header(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + { + std::shared_ptr< ppc::protocol::MessageHeader > *smartresult = result ? new std::shared_ptr< ppc::protocol::MessageHeader >(result) : 0; + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(smartresult), SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageHeader_t, SWIG_POINTER_OWN); + } + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_Message_setHeader(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::Message *arg1 = (ppc::protocol::Message *) 0 ; + ppc::protocol::MessageHeader::Ptr arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::Message > tempshared1 ; + std::shared_ptr< ppc::protocol::Message > *smartarg1 = 0 ; + void *argp2 ; + int res2 = 0 ; + PyObject *swig_obj[2] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "Message_setHeader", 2, 2, swig_obj)) SWIG_fail; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__Message_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Message_setHeader" "', argument " "1"" of type '" "ppc::protocol::Message *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::protocol::Message > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::protocol::Message > * >(argp1); + arg1 = const_cast< ppc::protocol::Message * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::protocol::Message > * >(argp1); + arg1 = const_cast< ppc::protocol::Message * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + int newmem = 0; + res2 = SWIG_ConvertPtrAndOwn(swig_obj[1], &argp2, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageHeader_t, 0 , &newmem); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Message_setHeader" "', argument " "2"" of type '" "ppc::protocol::MessageHeader::Ptr""'"); + } + if (argp2) arg2 = *(reinterpret_cast< ppc::protocol::MessageHeader::Ptr * >(argp2)); + if (newmem & SWIG_CAST_NEW_MEMORY) delete reinterpret_cast< ppc::protocol::MessageHeader::Ptr * >(argp2); + } + { + try { + (arg1)->setHeader(arg2); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_Message_version(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::Message *arg1 = (ppc::protocol::Message *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::Message const > tempshared1 ; + std::shared_ptr< ppc::protocol::Message const > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + uint16_t result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__Message_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Message_version" "', argument " "1"" of type '" "ppc::protocol::Message const *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< const ppc::protocol::Message > * >(argp1); + delete reinterpret_cast< std::shared_ptr< const ppc::protocol::Message > * >(argp1); + arg1 = const_cast< ppc::protocol::Message * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< const ppc::protocol::Message > * >(argp1); + arg1 = const_cast< ppc::protocol::Message * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + result = (uint16_t)((ppc::protocol::Message const *)arg1)->version(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_From_unsigned_SS_short(static_cast< unsigned short >(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_Message_setVersion(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::Message *arg1 = (ppc::protocol::Message *) 0 ; + uint16_t arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::Message > tempshared1 ; + std::shared_ptr< ppc::protocol::Message > *smartarg1 = 0 ; + unsigned short val2 ; + int ecode2 = 0 ; + PyObject *swig_obj[2] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "Message_setVersion", 2, 2, swig_obj)) SWIG_fail; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__Message_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Message_setVersion" "', argument " "1"" of type '" "ppc::protocol::Message *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::protocol::Message > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::protocol::Message > * >(argp1); + arg1 = const_cast< ppc::protocol::Message * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::protocol::Message > * >(argp1); + arg1 = const_cast< ppc::protocol::Message * >((smartarg1 ? smartarg1->get() : 0)); + } + } + ecode2 = SWIG_AsVal_unsigned_SS_short(swig_obj[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "Message_setVersion" "', argument " "2"" of type '" "uint16_t""'"); + } + arg2 = static_cast< uint16_t >(val2); + { + try { + (arg1)->setVersion(arg2); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_Message_packetType(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::Message *arg1 = (ppc::protocol::Message *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::Message const > tempshared1 ; + std::shared_ptr< ppc::protocol::Message const > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + uint16_t result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__Message_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Message_packetType" "', argument " "1"" of type '" "ppc::protocol::Message const *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< const ppc::protocol::Message > * >(argp1); + delete reinterpret_cast< std::shared_ptr< const ppc::protocol::Message > * >(argp1); + arg1 = const_cast< ppc::protocol::Message * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< const ppc::protocol::Message > * >(argp1); + arg1 = const_cast< ppc::protocol::Message * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + result = (uint16_t)((ppc::protocol::Message const *)arg1)->packetType(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_From_unsigned_SS_short(static_cast< unsigned short >(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_Message_setPacketType(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::Message *arg1 = (ppc::protocol::Message *) 0 ; + uint16_t arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::Message > tempshared1 ; + std::shared_ptr< ppc::protocol::Message > *smartarg1 = 0 ; + unsigned short val2 ; + int ecode2 = 0 ; + PyObject *swig_obj[2] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "Message_setPacketType", 2, 2, swig_obj)) SWIG_fail; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__Message_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Message_setPacketType" "', argument " "1"" of type '" "ppc::protocol::Message *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::protocol::Message > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::protocol::Message > * >(argp1); + arg1 = const_cast< ppc::protocol::Message * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::protocol::Message > * >(argp1); + arg1 = const_cast< ppc::protocol::Message * >((smartarg1 ? smartarg1->get() : 0)); + } + } + ecode2 = SWIG_AsVal_unsigned_SS_short(swig_obj[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "Message_setPacketType" "', argument " "2"" of type '" "uint16_t""'"); + } + arg2 = static_cast< uint16_t >(val2); + { + try { + (arg1)->setPacketType(arg2); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_Message_seq(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::Message *arg1 = (ppc::protocol::Message *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::Message const > tempshared1 ; + std::shared_ptr< ppc::protocol::Message const > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + std::string *result = 0 ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__Message_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Message_seq" "', argument " "1"" of type '" "ppc::protocol::Message const *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< const ppc::protocol::Message > * >(argp1); + delete reinterpret_cast< std::shared_ptr< const ppc::protocol::Message > * >(argp1); + arg1 = const_cast< ppc::protocol::Message * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< const ppc::protocol::Message > * >(argp1); + arg1 = const_cast< ppc::protocol::Message * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + result = (std::string *) &((ppc::protocol::Message const *)arg1)->seq(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_From_std_string(static_cast< std::string >(*result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_Message_setSeq(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::Message *arg1 = (ppc::protocol::Message *) 0 ; + std::string arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::Message > tempshared1 ; + std::shared_ptr< ppc::protocol::Message > *smartarg1 = 0 ; + PyObject *swig_obj[2] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "Message_setSeq", 2, 2, swig_obj)) SWIG_fail; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__Message_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Message_setSeq" "', argument " "1"" of type '" "ppc::protocol::Message *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::protocol::Message > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::protocol::Message > * >(argp1); + arg1 = const_cast< ppc::protocol::Message * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::protocol::Message > * >(argp1); + arg1 = const_cast< ppc::protocol::Message * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + std::string *ptr = (std::string *)0; + int res = SWIG_AsPtr_std_string(swig_obj[1], &ptr); + if (!SWIG_IsOK(res) || !ptr) { + SWIG_exception_fail(SWIG_ArgError((ptr ? res : SWIG_TypeError)), "in method '" "Message_setSeq" "', argument " "2"" of type '" "std::string""'"); + } + arg2 = *ptr; + if (SWIG_IsNewObj(res)) delete ptr; + } + { + try { + (arg1)->setSeq(arg2); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_Message_ext(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::Message *arg1 = (ppc::protocol::Message *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::Message const > tempshared1 ; + std::shared_ptr< ppc::protocol::Message const > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + uint16_t result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__Message_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Message_ext" "', argument " "1"" of type '" "ppc::protocol::Message const *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< const ppc::protocol::Message > * >(argp1); + delete reinterpret_cast< std::shared_ptr< const ppc::protocol::Message > * >(argp1); + arg1 = const_cast< ppc::protocol::Message * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< const ppc::protocol::Message > * >(argp1); + arg1 = const_cast< ppc::protocol::Message * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + result = (uint16_t)((ppc::protocol::Message const *)arg1)->ext(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_From_unsigned_SS_short(static_cast< unsigned short >(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_Message_setExt(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::Message *arg1 = (ppc::protocol::Message *) 0 ; + uint16_t arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::Message > tempshared1 ; + std::shared_ptr< ppc::protocol::Message > *smartarg1 = 0 ; + unsigned short val2 ; + int ecode2 = 0 ; + PyObject *swig_obj[2] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "Message_setExt", 2, 2, swig_obj)) SWIG_fail; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__Message_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Message_setExt" "', argument " "1"" of type '" "ppc::protocol::Message *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::protocol::Message > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::protocol::Message > * >(argp1); + arg1 = const_cast< ppc::protocol::Message * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::protocol::Message > * >(argp1); + arg1 = const_cast< ppc::protocol::Message * >((smartarg1 ? smartarg1->get() : 0)); + } + } + ecode2 = SWIG_AsVal_unsigned_SS_short(swig_obj[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "Message_setExt" "', argument " "2"" of type '" "uint16_t""'"); + } + arg2 = static_cast< uint16_t >(val2); + { + try { + (arg1)->setExt(arg2); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_Message_isRespPacket(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::Message *arg1 = (ppc::protocol::Message *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::Message const > tempshared1 ; + std::shared_ptr< ppc::protocol::Message const > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + bool result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__Message_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Message_isRespPacket" "', argument " "1"" of type '" "ppc::protocol::Message const *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< const ppc::protocol::Message > * >(argp1); + delete reinterpret_cast< std::shared_ptr< const ppc::protocol::Message > * >(argp1); + arg1 = const_cast< ppc::protocol::Message * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< const ppc::protocol::Message > * >(argp1); + arg1 = const_cast< ppc::protocol::Message * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + result = (bool)((ppc::protocol::Message const *)arg1)->isRespPacket(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_From_bool(static_cast< bool >(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_Message_setRespPacket(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::Message *arg1 = (ppc::protocol::Message *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::Message > tempshared1 ; + std::shared_ptr< ppc::protocol::Message > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__Message_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Message_setRespPacket" "', argument " "1"" of type '" "ppc::protocol::Message *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::protocol::Message > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::protocol::Message > * >(argp1); + arg1 = const_cast< ppc::protocol::Message * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::protocol::Message > * >(argp1); + arg1 = const_cast< ppc::protocol::Message * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + (arg1)->setRespPacket(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_Message_setPayload(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::Message *arg1 = (ppc::protocol::Message *) 0 ; + std::shared_ptr< bcos::bytes > arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::Message > tempshared1 ; + std::shared_ptr< ppc::protocol::Message > *smartarg1 = 0 ; + void *argp2 ; + int res2 = 0 ; + PyObject *swig_obj[2] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "Message_setPayload", 2, 2, swig_obj)) SWIG_fail; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__Message_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Message_setPayload" "', argument " "1"" of type '" "ppc::protocol::Message *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::protocol::Message > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::protocol::Message > * >(argp1); + arg1 = const_cast< ppc::protocol::Message * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::protocol::Message > * >(argp1); + arg1 = const_cast< ppc::protocol::Message * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + int newmem = 0; + res2 = SWIG_ConvertPtrAndOwn(swig_obj[1], &argp2, SWIGTYPE_p_std__shared_ptrT_bcos__bytes_t, 0 , &newmem); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Message_setPayload" "', argument " "2"" of type '" "std::shared_ptr< bcos::bytes >""'"); + } + if (argp2) arg2 = *(reinterpret_cast< std::shared_ptr< bcos::bytes > * >(argp2)); + if (newmem & SWIG_CAST_NEW_MEMORY) delete reinterpret_cast< std::shared_ptr< bcos::bytes > * >(argp2); + } + { + try { + (arg1)->setPayload(arg2); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_Message_payloadBuffer(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::Message *arg1 = (ppc::protocol::Message *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::Message const > tempshared1 ; + std::shared_ptr< ppc::protocol::Message const > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + OutputBuffer result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__Message_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Message_payloadBuffer" "', argument " "1"" of type '" "ppc::protocol::Message const *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< const ppc::protocol::Message > * >(argp1); + delete reinterpret_cast< std::shared_ptr< const ppc::protocol::Message > * >(argp1); + arg1 = const_cast< ppc::protocol::Message * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< const ppc::protocol::Message > * >(argp1); + arg1 = const_cast< ppc::protocol::Message * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + result = ((ppc::protocol::Message const *)arg1)->payloadBuffer(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + { + resultobj = PyBytes_FromStringAndSize((const char *)(&result)->data, (&result)->len); + } + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_Message_frontMessage(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::Message *arg1 = (ppc::protocol::Message *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::Message const > tempshared1 ; + std::shared_ptr< ppc::protocol::Message const > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + ppc::protocol::MessagePayload::Ptr *result = 0 ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__Message_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Message_frontMessage" "', argument " "1"" of type '" "ppc::protocol::Message const *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< const ppc::protocol::Message > * >(argp1); + delete reinterpret_cast< std::shared_ptr< const ppc::protocol::Message > * >(argp1); + arg1 = const_cast< ppc::protocol::Message * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< const ppc::protocol::Message > * >(argp1); + arg1 = const_cast< ppc::protocol::Message * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + result = (ppc::protocol::MessagePayload::Ptr *) &((ppc::protocol::Message const *)arg1)->frontMessage(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + { + std::shared_ptr< ppc::protocol::MessagePayload > *smartresult = *result ? new std::shared_ptr< ppc::protocol::MessagePayload >(*result) : 0; + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(smartresult), SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessagePayload_t, SWIG_POINTER_OWN); + } + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_Message_encode(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::Message *arg1 = (ppc::protocol::Message *) 0 ; + bcos::bytes *arg2 = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::Message > tempshared1 ; + std::shared_ptr< ppc::protocol::Message > *smartarg1 = 0 ; + void *argp2 = 0 ; + int res2 = 0 ; + std::shared_ptr< bcos::bytes > tempshared2 ; + PyObject *swig_obj[2] ; + bool result; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "Message_encode", 2, 2, swig_obj)) SWIG_fail; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__Message_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Message_encode" "', argument " "1"" of type '" "ppc::protocol::Message *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::protocol::Message > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::protocol::Message > * >(argp1); + arg1 = const_cast< ppc::protocol::Message * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::protocol::Message > * >(argp1); + arg1 = const_cast< ppc::protocol::Message * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + int newmem = 0; + res2 = SWIG_ConvertPtrAndOwn(swig_obj[1], &argp2, SWIGTYPE_p_std__shared_ptrT_bcos__bytes_t, 0 , &newmem); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Message_encode" "', argument " "2"" of type '" "bcos::bytes &""'"); + } + if (!argp2) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "Message_encode" "', argument " "2"" of type '" "bcos::bytes &""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared2 = *reinterpret_cast< std::shared_ptr< bcos::bytes > * >(argp2); + delete reinterpret_cast< std::shared_ptr< bcos::bytes > * >(argp2); + arg2 = const_cast< bcos::bytes * >(tempshared2.get()); + } else { + arg2 = const_cast< bcos::bytes * >(reinterpret_cast< std::shared_ptr< bcos::bytes > * >(argp2)->get()); + } + } + { + try { + result = (bool)(arg1)->encode(*arg2); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_From_bool(static_cast< bool >(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_Message_decode(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::Message *arg1 = (ppc::protocol::Message *) 0 ; + bcos::bytesConstRef arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::Message > tempshared1 ; + std::shared_ptr< ppc::protocol::Message > *smartarg1 = 0 ; + void *argp2 ; + int res2 = 0 ; + PyObject *swig_obj[2] ; + int64_t result; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "Message_decode", 2, 2, swig_obj)) SWIG_fail; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__Message_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Message_decode" "', argument " "1"" of type '" "ppc::protocol::Message *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::protocol::Message > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::protocol::Message > * >(argp1); + arg1 = const_cast< ppc::protocol::Message * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::protocol::Message > * >(argp1); + arg1 = const_cast< ppc::protocol::Message * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + res2 = SWIG_ConvertPtr(swig_obj[1], &argp2, SWIGTYPE_p_bcos__bytesConstRef, 0 | 0); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Message_decode" "', argument " "2"" of type '" "bcos::bytesConstRef""'"); + } + if (!argp2) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "Message_decode" "', argument " "2"" of type '" "bcos::bytesConstRef""'"); + } else { + bcos::bytesConstRef * temp = reinterpret_cast< bcos::bytesConstRef * >(argp2); + arg2 = *temp; + if (SWIG_IsNewObj(res2)) delete temp; + } + } + { + try { + result = (int64_t)(arg1)->decode(arg2); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_From_long_SS_long(static_cast< long long >(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_Message_length(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::Message *arg1 = (ppc::protocol::Message *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::Message const > tempshared1 ; + std::shared_ptr< ppc::protocol::Message const > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + uint32_t result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__Message_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Message_length" "', argument " "1"" of type '" "ppc::protocol::Message const *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< const ppc::protocol::Message > * >(argp1); + delete reinterpret_cast< std::shared_ptr< const ppc::protocol::Message > * >(argp1); + arg1 = const_cast< ppc::protocol::Message * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< const ppc::protocol::Message > * >(argp1); + arg1 = const_cast< ppc::protocol::Message * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + result = (uint32_t)((ppc::protocol::Message const *)arg1)->length(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_From_unsigned_SS_int(static_cast< unsigned int >(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_Message_payload(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::Message *arg1 = (ppc::protocol::Message *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::Message const > tempshared1 ; + std::shared_ptr< ppc::protocol::Message const > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + std::shared_ptr< bcos::bytes > result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__Message_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Message_payload" "', argument " "1"" of type '" "ppc::protocol::Message const *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< const ppc::protocol::Message > * >(argp1); + delete reinterpret_cast< std::shared_ptr< const ppc::protocol::Message > * >(argp1); + arg1 = const_cast< ppc::protocol::Message * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< const ppc::protocol::Message > * >(argp1); + arg1 = const_cast< ppc::protocol::Message * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + result = ((ppc::protocol::Message const *)arg1)->payload(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + { + std::shared_ptr< bcos::bytes > *smartresult = result ? new std::shared_ptr< bcos::bytes >(result) : 0; + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(smartresult), SWIGTYPE_p_std__shared_ptrT_bcos__bytes_t, SWIG_POINTER_OWN); + } + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_Message_releasePayload(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::Message *arg1 = (ppc::protocol::Message *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::Message > tempshared1 ; + std::shared_ptr< ppc::protocol::Message > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__Message_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Message_releasePayload" "', argument " "1"" of type '" "ppc::protocol::Message *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::protocol::Message > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::protocol::Message > * >(argp1); + arg1 = const_cast< ppc::protocol::Message * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::protocol::Message > * >(argp1); + arg1 = const_cast< ppc::protocol::Message * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + (arg1)->releasePayload(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *Message_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *obj; + if (!SWIG_Python_UnpackTuple(args, "swigregister", 1, 1, &obj)) return NULL; + SWIG_TypeNewClientData(SWIGTYPE_p_std__shared_ptrT_ppc__protocol__Message_t, SWIG_NewClientData(obj)); + return SWIG_Py_Void(); +} + +SWIGINTERN PyObject *_wrap_delete_MessageHeaderBuilder(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::MessageHeaderBuilder *arg1 = (ppc::protocol::MessageHeaderBuilder *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::MessageHeaderBuilder > tempshared1 ; + std::shared_ptr< ppc::protocol::MessageHeaderBuilder > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageHeaderBuilder_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_MessageHeaderBuilder" "', argument " "1"" of type '" "ppc::protocol::MessageHeaderBuilder *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::protocol::MessageHeaderBuilder > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::protocol::MessageHeaderBuilder > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageHeaderBuilder * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::protocol::MessageHeaderBuilder > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageHeaderBuilder * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + (void)arg1; delete smartarg1; + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_MessageHeaderBuilder_build__SWIG_0(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + ppc::protocol::MessageHeaderBuilder *arg1 = (ppc::protocol::MessageHeaderBuilder *) 0 ; + bcos::bytesConstRef arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::MessageHeaderBuilder > tempshared1 ; + std::shared_ptr< ppc::protocol::MessageHeaderBuilder > *smartarg1 = 0 ; + void *argp2 ; + int res2 = 0 ; + ppc::protocol::MessageHeader::Ptr result; + + (void)self; + if ((nobjs < 2) || (nobjs > 2)) SWIG_fail; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageHeaderBuilder_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "MessageHeaderBuilder_build" "', argument " "1"" of type '" "ppc::protocol::MessageHeaderBuilder *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::protocol::MessageHeaderBuilder > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::protocol::MessageHeaderBuilder > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageHeaderBuilder * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::protocol::MessageHeaderBuilder > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageHeaderBuilder * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + res2 = SWIG_ConvertPtr(swig_obj[1], &argp2, SWIGTYPE_p_bcos__bytesConstRef, 0 | 0); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "MessageHeaderBuilder_build" "', argument " "2"" of type '" "bcos::bytesConstRef""'"); + } + if (!argp2) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "MessageHeaderBuilder_build" "', argument " "2"" of type '" "bcos::bytesConstRef""'"); + } else { + bcos::bytesConstRef * temp = reinterpret_cast< bcos::bytesConstRef * >(argp2); + arg2 = *temp; + if (SWIG_IsNewObj(res2)) delete temp; + } + } + { + try { + result = (arg1)->build(arg2); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + { + std::shared_ptr< ppc::protocol::MessageHeader > *smartresult = result ? new std::shared_ptr< ppc::protocol::MessageHeader >(result) : 0; + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(smartresult), SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageHeader_t, SWIG_POINTER_OWN); + } + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_MessageHeaderBuilder_build__SWIG_1(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + ppc::protocol::MessageHeaderBuilder *arg1 = (ppc::protocol::MessageHeaderBuilder *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::MessageHeaderBuilder > tempshared1 ; + std::shared_ptr< ppc::protocol::MessageHeaderBuilder > *smartarg1 = 0 ; + ppc::protocol::MessageHeader::Ptr result; + + (void)self; + if ((nobjs < 1) || (nobjs > 1)) SWIG_fail; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageHeaderBuilder_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "MessageHeaderBuilder_build" "', argument " "1"" of type '" "ppc::protocol::MessageHeaderBuilder *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::protocol::MessageHeaderBuilder > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::protocol::MessageHeaderBuilder > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageHeaderBuilder * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::protocol::MessageHeaderBuilder > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageHeaderBuilder * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + result = (arg1)->build(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + { + std::shared_ptr< ppc::protocol::MessageHeader > *smartresult = result ? new std::shared_ptr< ppc::protocol::MessageHeader >(result) : 0; + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(smartresult), SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageHeader_t, SWIG_POINTER_OWN); + } + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_MessageHeaderBuilder_build__SWIG_2(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + ppc::protocol::MessageHeaderBuilder *arg1 = (ppc::protocol::MessageHeaderBuilder *) 0 ; + ppc::protocol::MessageOptionalHeader::Ptr *arg2 = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::MessageHeaderBuilder > tempshared1 ; + std::shared_ptr< ppc::protocol::MessageHeaderBuilder > *smartarg1 = 0 ; + void *argp2 ; + int res2 = 0 ; + ppc::protocol::MessageOptionalHeader::Ptr tempshared2 ; + ppc::protocol::MessageOptionalHeader::Ptr result; + + (void)self; + if ((nobjs < 2) || (nobjs > 2)) SWIG_fail; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageHeaderBuilder_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "MessageHeaderBuilder_build" "', argument " "1"" of type '" "ppc::protocol::MessageHeaderBuilder *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::protocol::MessageHeaderBuilder > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::protocol::MessageHeaderBuilder > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageHeaderBuilder * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::protocol::MessageHeaderBuilder > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageHeaderBuilder * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + int newmem = 0; + res2 = SWIG_ConvertPtrAndOwn(swig_obj[1], &argp2, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageOptionalHeader_t, 0 , &newmem); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "MessageHeaderBuilder_build" "', argument " "2"" of type '" "ppc::protocol::MessageOptionalHeader::Ptr const &""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + if (argp2) tempshared2 = *reinterpret_cast< ppc::protocol::MessageOptionalHeader::Ptr * >(argp2); + delete reinterpret_cast< ppc::protocol::MessageOptionalHeader::Ptr * >(argp2); + arg2 = &tempshared2; + } else { + arg2 = (argp2) ? reinterpret_cast< ppc::protocol::MessageOptionalHeader::Ptr * >(argp2) : &tempshared2; + } + } + { + try { + result = (arg1)->build((ppc::protocol::MessageOptionalHeader::Ptr const &)*arg2); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + { + std::shared_ptr< ppc::protocol::MessageOptionalHeader > *smartresult = result ? new std::shared_ptr< ppc::protocol::MessageOptionalHeader >(result) : 0; + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(smartresult), SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageOptionalHeader_t, SWIG_POINTER_OWN); + } + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_MessageHeaderBuilder_build(PyObject *self, PyObject *args) { + Py_ssize_t argc; + PyObject *argv[3] = { + 0 + }; + + if (!(argc = SWIG_Python_UnpackTuple(args, "MessageHeaderBuilder_build", 0, 2, argv))) SWIG_fail; + --argc; + if (argc == 1) { + int _v = 0; + int res = SWIG_ConvertPtr(argv[0], 0, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageHeaderBuilder_t, 0); + _v = SWIG_CheckState(res); + if (_v) { + return _wrap_MessageHeaderBuilder_build__SWIG_1(self, argc, argv); + } + } + if (argc == 2) { + int _v = 0; + int res = SWIG_ConvertPtr(argv[0], 0, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageHeaderBuilder_t, 0); + _v = SWIG_CheckState(res); + if (_v) { + int res = SWIG_ConvertPtr(argv[1], 0, SWIGTYPE_p_bcos__bytesConstRef, SWIG_POINTER_NO_NULL | 0); + _v = SWIG_CheckState(res); + if (_v) { + return _wrap_MessageHeaderBuilder_build__SWIG_0(self, argc, argv); + } + } + } + if (argc == 2) { + int _v = 0; + int res = SWIG_ConvertPtr(argv[0], 0, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageHeaderBuilder_t, 0); + _v = SWIG_CheckState(res); + if (_v) { + int res = SWIG_ConvertPtr(argv[1], 0, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageOptionalHeader_t, 0); + _v = SWIG_CheckState(res); + if (_v) { + return _wrap_MessageHeaderBuilder_build__SWIG_2(self, argc, argv); + } + } + } + +fail: + SWIG_Python_RaiseOrModifyTypeError("Wrong number or type of arguments for overloaded function 'MessageHeaderBuilder_build'.\n" + " Possible C/C++ prototypes are:\n" + " ppc::protocol::MessageHeaderBuilder::build(bcos::bytesConstRef)\n" + " ppc::protocol::MessageHeaderBuilder::build()\n" + " ppc::protocol::MessageHeaderBuilder::build(ppc::protocol::MessageOptionalHeader::Ptr const &)\n"); + return 0; +} + + +SWIGINTERN PyObject *MessageHeaderBuilder_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *obj; + if (!SWIG_Python_UnpackTuple(args, "swigregister", 1, 1, &obj)) return NULL; + SWIG_TypeNewClientData(SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageHeaderBuilder_t, SWIG_NewClientData(obj)); + return SWIG_Py_Void(); +} + +SWIGINTERN PyObject *_wrap_delete_MessageBuilder(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::MessageBuilder *arg1 = (ppc::protocol::MessageBuilder *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::MessageBuilder > tempshared1 ; + std::shared_ptr< ppc::protocol::MessageBuilder > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageBuilder_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_MessageBuilder" "', argument " "1"" of type '" "ppc::protocol::MessageBuilder *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::protocol::MessageBuilder > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::protocol::MessageBuilder > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageBuilder * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::protocol::MessageBuilder > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageBuilder * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + (void)arg1; delete smartarg1; + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_MessageBuilder_build__SWIG_0(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + ppc::protocol::MessageBuilder *arg1 = (ppc::protocol::MessageBuilder *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::MessageBuilder > tempshared1 ; + std::shared_ptr< ppc::protocol::MessageBuilder > *smartarg1 = 0 ; + ppc::protocol::Message::Ptr result; + + (void)self; + if ((nobjs < 1) || (nobjs > 1)) SWIG_fail; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageBuilder_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "MessageBuilder_build" "', argument " "1"" of type '" "ppc::protocol::MessageBuilder *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::protocol::MessageBuilder > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::protocol::MessageBuilder > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageBuilder * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::protocol::MessageBuilder > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageBuilder * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + result = (arg1)->build(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + { + std::shared_ptr< ppc::protocol::Message > *smartresult = result ? new std::shared_ptr< ppc::protocol::Message >(result) : 0; + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(smartresult), SWIGTYPE_p_std__shared_ptrT_ppc__protocol__Message_t, SWIG_POINTER_OWN); + } + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_MessageBuilder_build__SWIG_1(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + ppc::protocol::MessageBuilder *arg1 = (ppc::protocol::MessageBuilder *) 0 ; + bcos::bytesConstRef arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::MessageBuilder > tempshared1 ; + std::shared_ptr< ppc::protocol::MessageBuilder > *smartarg1 = 0 ; + void *argp2 ; + int res2 = 0 ; + ppc::protocol::Message::Ptr result; + + (void)self; + if ((nobjs < 2) || (nobjs > 2)) SWIG_fail; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageBuilder_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "MessageBuilder_build" "', argument " "1"" of type '" "ppc::protocol::MessageBuilder *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::protocol::MessageBuilder > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::protocol::MessageBuilder > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageBuilder * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::protocol::MessageBuilder > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageBuilder * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + res2 = SWIG_ConvertPtr(swig_obj[1], &argp2, SWIGTYPE_p_bcos__bytesConstRef, 0 | 0); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "MessageBuilder_build" "', argument " "2"" of type '" "bcos::bytesConstRef""'"); + } + if (!argp2) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "MessageBuilder_build" "', argument " "2"" of type '" "bcos::bytesConstRef""'"); + } else { + bcos::bytesConstRef * temp = reinterpret_cast< bcos::bytesConstRef * >(argp2); + arg2 = *temp; + if (SWIG_IsNewObj(res2)) delete temp; + } + } + { + try { + result = (arg1)->build(arg2); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + { + std::shared_ptr< ppc::protocol::Message > *smartresult = result ? new std::shared_ptr< ppc::protocol::Message >(result) : 0; + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(smartresult), SWIGTYPE_p_std__shared_ptrT_ppc__protocol__Message_t, SWIG_POINTER_OWN); + } + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_MessageBuilder_build__SWIG_2(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + ppc::protocol::MessageBuilder *arg1 = (ppc::protocol::MessageBuilder *) 0 ; + ppc::protocol::RouteType arg2 ; + ppc::protocol::MessageOptionalHeader::Ptr *arg3 = 0 ; + bcos::bytes *arg4 = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::MessageBuilder > tempshared1 ; + std::shared_ptr< ppc::protocol::MessageBuilder > *smartarg1 = 0 ; + void *argp2 ; + int res2 = 0 ; + void *argp3 ; + int res3 = 0 ; + ppc::protocol::MessageOptionalHeader::Ptr tempshared3 ; + void *argp4 = 0 ; + int res4 = 0 ; + std::unique_ptr< bcos::bytes > rvrdeleter4 ; + ppc::protocol::Message::Ptr result; + + (void)self; + if ((nobjs < 4) || (nobjs > 4)) SWIG_fail; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageBuilder_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "MessageBuilder_build" "', argument " "1"" of type '" "ppc::protocol::MessageBuilder *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::protocol::MessageBuilder > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::protocol::MessageBuilder > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageBuilder * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::protocol::MessageBuilder > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageBuilder * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + res2 = SWIG_ConvertPtr(swig_obj[1], &argp2, SWIGTYPE_p_ppc__protocol__RouteType, 0 | 0); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "MessageBuilder_build" "', argument " "2"" of type '" "ppc::protocol::RouteType""'"); + } + if (!argp2) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "MessageBuilder_build" "', argument " "2"" of type '" "ppc::protocol::RouteType""'"); + } else { + ppc::protocol::RouteType * temp = reinterpret_cast< ppc::protocol::RouteType * >(argp2); + arg2 = *temp; + if (SWIG_IsNewObj(res2)) delete temp; + } + } + { + int newmem = 0; + res3 = SWIG_ConvertPtrAndOwn(swig_obj[2], &argp3, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageOptionalHeader_t, 0 , &newmem); + if (!SWIG_IsOK(res3)) { + SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "MessageBuilder_build" "', argument " "3"" of type '" "ppc::protocol::MessageOptionalHeader::Ptr const &""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + if (argp3) tempshared3 = *reinterpret_cast< ppc::protocol::MessageOptionalHeader::Ptr * >(argp3); + delete reinterpret_cast< ppc::protocol::MessageOptionalHeader::Ptr * >(argp3); + arg3 = &tempshared3; + } else { + arg3 = (argp3) ? reinterpret_cast< ppc::protocol::MessageOptionalHeader::Ptr * >(argp3) : &tempshared3; + } + } + res4 = SWIG_ConvertPtr(swig_obj[3], &argp4, SWIGTYPE_p_std__vectorT_uint8_t_t, SWIG_POINTER_RELEASE | 0 ); + if (!SWIG_IsOK(res4)) { + if (res4 == SWIG_ERROR_RELEASE_NOT_OWNED) { + SWIG_exception_fail(SWIG_ArgError(res4), "in method '" "MessageBuilder_build" "', cannot release ownership as memory is not owned for argument " "4"" of type '" "bcos::bytes &&""'"); + } else { + SWIG_exception_fail(SWIG_ArgError(res4), "in method '" "MessageBuilder_build" "', argument " "4"" of type '" "bcos::bytes &&""'"); + } + } + if (!argp4) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "MessageBuilder_build" "', argument " "4"" of type '" "bcos::bytes &&""'"); + } + arg4 = reinterpret_cast< bcos::bytes * >(argp4); + rvrdeleter4.reset(arg4); + { + try { + result = (arg1)->build(arg2,(ppc::protocol::MessageOptionalHeader::Ptr const &)*arg3,(bcos::bytes &&)*arg4); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + { + std::shared_ptr< ppc::protocol::Message > *smartresult = result ? new std::shared_ptr< ppc::protocol::Message >(result) : 0; + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(smartresult), SWIGTYPE_p_std__shared_ptrT_ppc__protocol__Message_t, SWIG_POINTER_OWN); + } + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_MessageBuilder_build(PyObject *self, PyObject *args) { + Py_ssize_t argc; + PyObject *argv[5] = { + 0 + }; + + if (!(argc = SWIG_Python_UnpackTuple(args, "MessageBuilder_build", 0, 4, argv))) SWIG_fail; + --argc; + if (argc == 1) { + int _v = 0; + int res = SWIG_ConvertPtr(argv[0], 0, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageBuilder_t, 0); + _v = SWIG_CheckState(res); + if (_v) { + return _wrap_MessageBuilder_build__SWIG_0(self, argc, argv); + } + } + if (argc == 2) { + int _v = 0; + int res = SWIG_ConvertPtr(argv[0], 0, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageBuilder_t, 0); + _v = SWIG_CheckState(res); + if (_v) { + int res = SWIG_ConvertPtr(argv[1], 0, SWIGTYPE_p_bcos__bytesConstRef, SWIG_POINTER_NO_NULL | 0); + _v = SWIG_CheckState(res); + if (_v) { + return _wrap_MessageBuilder_build__SWIG_1(self, argc, argv); + } + } + } + if (argc == 4) { + int _v = 0; + int res = SWIG_ConvertPtr(argv[0], 0, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageBuilder_t, 0); + _v = SWIG_CheckState(res); + if (_v) { + int res = SWIG_ConvertPtr(argv[1], 0, SWIGTYPE_p_ppc__protocol__RouteType, SWIG_POINTER_NO_NULL | 0); + _v = SWIG_CheckState(res); + if (_v) { + int res = SWIG_ConvertPtr(argv[2], 0, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageOptionalHeader_t, 0); + _v = SWIG_CheckState(res); + if (_v) { + void *vptr = 0; + int res = SWIG_ConvertPtr(argv[3], &vptr, SWIGTYPE_p_std__vectorT_uint8_t_t, SWIG_POINTER_NO_NULL); + _v = SWIG_CheckState(res); + if (_v) { + return _wrap_MessageBuilder_build__SWIG_2(self, argc, argv); + } + } + } + } + } + +fail: + SWIG_Python_RaiseOrModifyTypeError("Wrong number or type of arguments for overloaded function 'MessageBuilder_build'.\n" + " Possible C/C++ prototypes are:\n" + " ppc::protocol::MessageBuilder::build()\n" + " ppc::protocol::MessageBuilder::build(bcos::bytesConstRef)\n" + " ppc::protocol::MessageBuilder::build(ppc::protocol::RouteType,ppc::protocol::MessageOptionalHeader::Ptr const &,bcos::bytes &&)\n"); + return 0; +} + + +SWIGINTERN PyObject *MessageBuilder_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *obj; + if (!SWIG_Python_UnpackTuple(args, "swigregister", 1, 1, &obj)) return NULL; + SWIG_TypeNewClientData(SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageBuilder_t, SWIG_NewClientData(obj)); + return SWIG_Py_Void(); +} + +SWIGINTERN PyObject *_wrap_delete_MessageOptionalHeaderBuilder(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::MessageOptionalHeaderBuilder *arg1 = (ppc::protocol::MessageOptionalHeaderBuilder *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::MessageOptionalHeaderBuilder > tempshared1 ; + std::shared_ptr< ppc::protocol::MessageOptionalHeaderBuilder > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageOptionalHeaderBuilder_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_MessageOptionalHeaderBuilder" "', argument " "1"" of type '" "ppc::protocol::MessageOptionalHeaderBuilder *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::protocol::MessageOptionalHeaderBuilder > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::protocol::MessageOptionalHeaderBuilder > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageOptionalHeaderBuilder * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::protocol::MessageOptionalHeaderBuilder > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageOptionalHeaderBuilder * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + (void)arg1; delete smartarg1; + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_MessageOptionalHeaderBuilder_build__SWIG_0(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + ppc::protocol::MessageOptionalHeaderBuilder *arg1 = (ppc::protocol::MessageOptionalHeaderBuilder *) 0 ; + ppc::protocol::MessageOptionalHeader::Ptr *arg2 = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::MessageOptionalHeaderBuilder > tempshared1 ; + std::shared_ptr< ppc::protocol::MessageOptionalHeaderBuilder > *smartarg1 = 0 ; + void *argp2 ; + int res2 = 0 ; + ppc::protocol::MessageOptionalHeader::Ptr tempshared2 ; + ppc::protocol::MessageOptionalHeader::Ptr result; + + (void)self; + if ((nobjs < 2) || (nobjs > 2)) SWIG_fail; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageOptionalHeaderBuilder_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "MessageOptionalHeaderBuilder_build" "', argument " "1"" of type '" "ppc::protocol::MessageOptionalHeaderBuilder *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::protocol::MessageOptionalHeaderBuilder > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::protocol::MessageOptionalHeaderBuilder > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageOptionalHeaderBuilder * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::protocol::MessageOptionalHeaderBuilder > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageOptionalHeaderBuilder * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + int newmem = 0; + res2 = SWIG_ConvertPtrAndOwn(swig_obj[1], &argp2, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageOptionalHeader_t, 0 , &newmem); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "MessageOptionalHeaderBuilder_build" "', argument " "2"" of type '" "ppc::protocol::MessageOptionalHeader::Ptr const &""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + if (argp2) tempshared2 = *reinterpret_cast< ppc::protocol::MessageOptionalHeader::Ptr * >(argp2); + delete reinterpret_cast< ppc::protocol::MessageOptionalHeader::Ptr * >(argp2); + arg2 = &tempshared2; + } else { + arg2 = (argp2) ? reinterpret_cast< ppc::protocol::MessageOptionalHeader::Ptr * >(argp2) : &tempshared2; + } + } + { + try { + result = (arg1)->build((ppc::protocol::MessageOptionalHeader::Ptr const &)*arg2); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + { + std::shared_ptr< ppc::protocol::MessageOptionalHeader > *smartresult = result ? new std::shared_ptr< ppc::protocol::MessageOptionalHeader >(result) : 0; + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(smartresult), SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageOptionalHeader_t, SWIG_POINTER_OWN); + } + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_MessageOptionalHeaderBuilder_build__SWIG_1(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + ppc::protocol::MessageOptionalHeaderBuilder *arg1 = (ppc::protocol::MessageOptionalHeaderBuilder *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::MessageOptionalHeaderBuilder > tempshared1 ; + std::shared_ptr< ppc::protocol::MessageOptionalHeaderBuilder > *smartarg1 = 0 ; + ppc::protocol::MessageOptionalHeader::Ptr result; + + (void)self; + if ((nobjs < 1) || (nobjs > 1)) SWIG_fail; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageOptionalHeaderBuilder_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "MessageOptionalHeaderBuilder_build" "', argument " "1"" of type '" "ppc::protocol::MessageOptionalHeaderBuilder *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::protocol::MessageOptionalHeaderBuilder > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::protocol::MessageOptionalHeaderBuilder > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageOptionalHeaderBuilder * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::protocol::MessageOptionalHeaderBuilder > * >(argp1); + arg1 = const_cast< ppc::protocol::MessageOptionalHeaderBuilder * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + result = (arg1)->build(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + { + std::shared_ptr< ppc::protocol::MessageOptionalHeader > *smartresult = result ? new std::shared_ptr< ppc::protocol::MessageOptionalHeader >(result) : 0; + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(smartresult), SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageOptionalHeader_t, SWIG_POINTER_OWN); + } + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_MessageOptionalHeaderBuilder_build(PyObject *self, PyObject *args) { + Py_ssize_t argc; + PyObject *argv[3] = { + 0 + }; + + if (!(argc = SWIG_Python_UnpackTuple(args, "MessageOptionalHeaderBuilder_build", 0, 2, argv))) SWIG_fail; + --argc; + if (argc == 1) { + int _v = 0; + int res = SWIG_ConvertPtr(argv[0], 0, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageOptionalHeaderBuilder_t, 0); + _v = SWIG_CheckState(res); + if (_v) { + return _wrap_MessageOptionalHeaderBuilder_build__SWIG_1(self, argc, argv); + } + } + if (argc == 2) { + int _v = 0; + int res = SWIG_ConvertPtr(argv[0], 0, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageOptionalHeaderBuilder_t, 0); + _v = SWIG_CheckState(res); + if (_v) { + int res = SWIG_ConvertPtr(argv[1], 0, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageOptionalHeader_t, 0); + _v = SWIG_CheckState(res); + if (_v) { + return _wrap_MessageOptionalHeaderBuilder_build__SWIG_0(self, argc, argv); + } + } + } + +fail: + SWIG_Python_RaiseOrModifyTypeError("Wrong number or type of arguments for overloaded function 'MessageOptionalHeaderBuilder_build'.\n" + " Possible C/C++ prototypes are:\n" + " ppc::protocol::MessageOptionalHeaderBuilder::build(ppc::protocol::MessageOptionalHeader::Ptr const &)\n" + " ppc::protocol::MessageOptionalHeaderBuilder::build()\n"); + return 0; +} + + +SWIGINTERN PyObject *MessageOptionalHeaderBuilder_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *obj; + if (!SWIG_Python_UnpackTuple(args, "swigregister", 1, 1, &obj)) return NULL; + SWIG_TypeNewClientData(SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageOptionalHeaderBuilder_t, SWIG_NewClientData(obj)); + return SWIG_Py_Void(); +} + +SWIGINTERN PyObject *_wrap_printOptionalField(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::MessageOptionalHeader::Ptr arg1 ; + void *argp1 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + std::string result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageOptionalHeader_t, 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "printOptionalField" "', argument " "1"" of type '" "ppc::protocol::MessageOptionalHeader::Ptr""'"); + } + if (argp1) arg1 = *(reinterpret_cast< ppc::protocol::MessageOptionalHeader::Ptr * >(argp1)); + if (newmem & SWIG_CAST_NEW_MEMORY) delete reinterpret_cast< ppc::protocol::MessageOptionalHeader::Ptr * >(argp1); + } + { + try { + result = ppc::protocol::printOptionalField(SWIG_STD_MOVE(arg1)); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_From_std_string(static_cast< std::string >(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_printMessage(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::Message::Ptr *arg1 = 0 ; + void *argp1 ; + int res1 = 0 ; + ppc::protocol::Message::Ptr tempshared1 ; + PyObject *swig_obj[1] ; + std::string result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__Message_t, 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "printMessage" "', argument " "1"" of type '" "ppc::protocol::Message::Ptr const &""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + if (argp1) tempshared1 = *reinterpret_cast< ppc::protocol::Message::Ptr * >(argp1); + delete reinterpret_cast< ppc::protocol::Message::Ptr * >(argp1); + arg1 = &tempshared1; + } else { + arg1 = (argp1) ? reinterpret_cast< ppc::protocol::Message::Ptr * >(argp1) : &tempshared1; + } + } + { + try { + result = ppc::protocol::printMessage((std::shared_ptr< ppc::protocol::Message > const &)*arg1); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_From_std_string(static_cast< std::string >(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_delete_MessagePayload(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::MessagePayload *arg1 = (ppc::protocol::MessagePayload *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::MessagePayload > tempshared1 ; + std::shared_ptr< ppc::protocol::MessagePayload > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessagePayload_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_MessagePayload" "', argument " "1"" of type '" "ppc::protocol::MessagePayload *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::protocol::MessagePayload > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::protocol::MessagePayload > * >(argp1); + arg1 = const_cast< ppc::protocol::MessagePayload * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::protocol::MessagePayload > * >(argp1); + arg1 = const_cast< ppc::protocol::MessagePayload * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + (void)arg1; delete smartarg1; + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_MessagePayload_encode(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::MessagePayload *arg1 = (ppc::protocol::MessagePayload *) 0 ; + bcos::bytes *arg2 = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::MessagePayload const > tempshared1 ; + std::shared_ptr< ppc::protocol::MessagePayload const > *smartarg1 = 0 ; + void *argp2 = 0 ; + int res2 = 0 ; + std::shared_ptr< bcos::bytes > tempshared2 ; + PyObject *swig_obj[2] ; + int64_t result; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "MessagePayload_encode", 2, 2, swig_obj)) SWIG_fail; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessagePayload_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "MessagePayload_encode" "', argument " "1"" of type '" "ppc::protocol::MessagePayload const *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< const ppc::protocol::MessagePayload > * >(argp1); + delete reinterpret_cast< std::shared_ptr< const ppc::protocol::MessagePayload > * >(argp1); + arg1 = const_cast< ppc::protocol::MessagePayload * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< const ppc::protocol::MessagePayload > * >(argp1); + arg1 = const_cast< ppc::protocol::MessagePayload * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + int newmem = 0; + res2 = SWIG_ConvertPtrAndOwn(swig_obj[1], &argp2, SWIGTYPE_p_std__shared_ptrT_bcos__bytes_t, 0 , &newmem); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "MessagePayload_encode" "', argument " "2"" of type '" "bcos::bytes &""'"); + } + if (!argp2) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "MessagePayload_encode" "', argument " "2"" of type '" "bcos::bytes &""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared2 = *reinterpret_cast< std::shared_ptr< bcos::bytes > * >(argp2); + delete reinterpret_cast< std::shared_ptr< bcos::bytes > * >(argp2); + arg2 = const_cast< bcos::bytes * >(tempshared2.get()); + } else { + arg2 = const_cast< bcos::bytes * >(reinterpret_cast< std::shared_ptr< bcos::bytes > * >(argp2)->get()); + } + } + { + try { + result = (int64_t)((ppc::protocol::MessagePayload const *)arg1)->encode(*arg2); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_From_long_SS_long(static_cast< long long >(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_MessagePayload_decode(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::MessagePayload *arg1 = (ppc::protocol::MessagePayload *) 0 ; + bcos::bytesConstRef arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::MessagePayload > tempshared1 ; + std::shared_ptr< ppc::protocol::MessagePayload > *smartarg1 = 0 ; + void *argp2 ; + int res2 = 0 ; + PyObject *swig_obj[2] ; + int64_t result; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "MessagePayload_decode", 2, 2, swig_obj)) SWIG_fail; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessagePayload_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "MessagePayload_decode" "', argument " "1"" of type '" "ppc::protocol::MessagePayload *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::protocol::MessagePayload > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::protocol::MessagePayload > * >(argp1); + arg1 = const_cast< ppc::protocol::MessagePayload * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::protocol::MessagePayload > * >(argp1); + arg1 = const_cast< ppc::protocol::MessagePayload * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + res2 = SWIG_ConvertPtr(swig_obj[1], &argp2, SWIGTYPE_p_bcos__bytesConstRef, 0 | 0); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "MessagePayload_decode" "', argument " "2"" of type '" "bcos::bytesConstRef""'"); + } + if (!argp2) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "MessagePayload_decode" "', argument " "2"" of type '" "bcos::bytesConstRef""'"); + } else { + bcos::bytesConstRef * temp = reinterpret_cast< bcos::bytesConstRef * >(argp2); + arg2 = *temp; + if (SWIG_IsNewObj(res2)) delete temp; + } + } + { + try { + result = (int64_t)(arg1)->decode(arg2); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_From_long_SS_long(static_cast< long long >(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_MessagePayload_version(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::MessagePayload *arg1 = (ppc::protocol::MessagePayload *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::MessagePayload const > tempshared1 ; + std::shared_ptr< ppc::protocol::MessagePayload const > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + uint8_t result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessagePayload_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "MessagePayload_version" "', argument " "1"" of type '" "ppc::protocol::MessagePayload const *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< const ppc::protocol::MessagePayload > * >(argp1); + delete reinterpret_cast< std::shared_ptr< const ppc::protocol::MessagePayload > * >(argp1); + arg1 = const_cast< ppc::protocol::MessagePayload * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< const ppc::protocol::MessagePayload > * >(argp1); + arg1 = const_cast< ppc::protocol::MessagePayload * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + result = (uint8_t)((ppc::protocol::MessagePayload const *)arg1)->version(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_From_unsigned_SS_char(static_cast< unsigned char >(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_MessagePayload_setVersion(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::MessagePayload *arg1 = (ppc::protocol::MessagePayload *) 0 ; + uint8_t arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::MessagePayload > tempshared1 ; + std::shared_ptr< ppc::protocol::MessagePayload > *smartarg1 = 0 ; + unsigned char val2 ; + int ecode2 = 0 ; + PyObject *swig_obj[2] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "MessagePayload_setVersion", 2, 2, swig_obj)) SWIG_fail; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessagePayload_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "MessagePayload_setVersion" "', argument " "1"" of type '" "ppc::protocol::MessagePayload *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::protocol::MessagePayload > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::protocol::MessagePayload > * >(argp1); + arg1 = const_cast< ppc::protocol::MessagePayload * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::protocol::MessagePayload > * >(argp1); + arg1 = const_cast< ppc::protocol::MessagePayload * >((smartarg1 ? smartarg1->get() : 0)); + } + } + ecode2 = SWIG_AsVal_unsigned_SS_char(swig_obj[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "MessagePayload_setVersion" "', argument " "2"" of type '" "uint8_t""'"); + } + arg2 = static_cast< uint8_t >(val2); + { + try { + (arg1)->setVersion(arg2); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_MessagePayload_dataBuffer(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::MessagePayload *arg1 = (ppc::protocol::MessagePayload *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::MessagePayload const > tempshared1 ; + std::shared_ptr< ppc::protocol::MessagePayload const > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + OutputBuffer result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessagePayload_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "MessagePayload_dataBuffer" "', argument " "1"" of type '" "ppc::protocol::MessagePayload const *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< const ppc::protocol::MessagePayload > * >(argp1); + delete reinterpret_cast< std::shared_ptr< const ppc::protocol::MessagePayload > * >(argp1); + arg1 = const_cast< ppc::protocol::MessagePayload * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< const ppc::protocol::MessagePayload > * >(argp1); + arg1 = const_cast< ppc::protocol::MessagePayload * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + result = ((ppc::protocol::MessagePayload const *)arg1)->dataBuffer(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + { + resultobj = PyBytes_FromStringAndSize((const char *)(&result)->data, (&result)->len); + } + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_MessagePayload_seq(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::MessagePayload *arg1 = (ppc::protocol::MessagePayload *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::MessagePayload const > tempshared1 ; + std::shared_ptr< ppc::protocol::MessagePayload const > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + uint16_t result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessagePayload_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "MessagePayload_seq" "', argument " "1"" of type '" "ppc::protocol::MessagePayload const *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< const ppc::protocol::MessagePayload > * >(argp1); + delete reinterpret_cast< std::shared_ptr< const ppc::protocol::MessagePayload > * >(argp1); + arg1 = const_cast< ppc::protocol::MessagePayload * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< const ppc::protocol::MessagePayload > * >(argp1); + arg1 = const_cast< ppc::protocol::MessagePayload * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + result = (uint16_t)((ppc::protocol::MessagePayload const *)arg1)->seq(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_From_unsigned_SS_short(static_cast< unsigned short >(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_MessagePayload_setSeq(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::MessagePayload *arg1 = (ppc::protocol::MessagePayload *) 0 ; + uint16_t arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::MessagePayload > tempshared1 ; + std::shared_ptr< ppc::protocol::MessagePayload > *smartarg1 = 0 ; + unsigned short val2 ; + int ecode2 = 0 ; + PyObject *swig_obj[2] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "MessagePayload_setSeq", 2, 2, swig_obj)) SWIG_fail; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessagePayload_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "MessagePayload_setSeq" "', argument " "1"" of type '" "ppc::protocol::MessagePayload *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::protocol::MessagePayload > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::protocol::MessagePayload > * >(argp1); + arg1 = const_cast< ppc::protocol::MessagePayload * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::protocol::MessagePayload > * >(argp1); + arg1 = const_cast< ppc::protocol::MessagePayload * >((smartarg1 ? smartarg1->get() : 0)); + } + } + ecode2 = SWIG_AsVal_unsigned_SS_short(swig_obj[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "MessagePayload_setSeq" "', argument " "2"" of type '" "uint16_t""'"); + } + arg2 = static_cast< uint16_t >(val2); + { + try { + (arg1)->setSeq(arg2); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_MessagePayload_length(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::MessagePayload *arg1 = (ppc::protocol::MessagePayload *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::MessagePayload const > tempshared1 ; + std::shared_ptr< ppc::protocol::MessagePayload const > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + int64_t result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessagePayload_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "MessagePayload_length" "', argument " "1"" of type '" "ppc::protocol::MessagePayload const *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< const ppc::protocol::MessagePayload > * >(argp1); + delete reinterpret_cast< std::shared_ptr< const ppc::protocol::MessagePayload > * >(argp1); + arg1 = const_cast< ppc::protocol::MessagePayload * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< const ppc::protocol::MessagePayload > * >(argp1); + arg1 = const_cast< ppc::protocol::MessagePayload * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + result = (int64_t)((ppc::protocol::MessagePayload const *)arg1)->length(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_From_long_SS_long(static_cast< long long >(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_MessagePayload_traceID(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::MessagePayload *arg1 = (ppc::protocol::MessagePayload *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::MessagePayload const > tempshared1 ; + std::shared_ptr< ppc::protocol::MessagePayload const > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + std::string *result = 0 ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessagePayload_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "MessagePayload_traceID" "', argument " "1"" of type '" "ppc::protocol::MessagePayload const *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< const ppc::protocol::MessagePayload > * >(argp1); + delete reinterpret_cast< std::shared_ptr< const ppc::protocol::MessagePayload > * >(argp1); + arg1 = const_cast< ppc::protocol::MessagePayload * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< const ppc::protocol::MessagePayload > * >(argp1); + arg1 = const_cast< ppc::protocol::MessagePayload * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + result = (std::string *) &((ppc::protocol::MessagePayload const *)arg1)->traceID(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_From_std_string(static_cast< std::string >(*result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_MessagePayload_setTraceID(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::MessagePayload *arg1 = (ppc::protocol::MessagePayload *) 0 ; + std::string *arg2 = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::MessagePayload > tempshared1 ; + std::shared_ptr< ppc::protocol::MessagePayload > *smartarg1 = 0 ; + int res2 = SWIG_OLDOBJ ; + PyObject *swig_obj[2] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "MessagePayload_setTraceID", 2, 2, swig_obj)) SWIG_fail; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessagePayload_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "MessagePayload_setTraceID" "', argument " "1"" of type '" "ppc::protocol::MessagePayload *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::protocol::MessagePayload > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::protocol::MessagePayload > * >(argp1); + arg1 = const_cast< ppc::protocol::MessagePayload * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::protocol::MessagePayload > * >(argp1); + arg1 = const_cast< ppc::protocol::MessagePayload * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + std::string *ptr = (std::string *)0; + res2 = SWIG_AsPtr_std_string(swig_obj[1], &ptr); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "MessagePayload_setTraceID" "', argument " "2"" of type '" "std::string const &""'"); + } + if (!ptr) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "MessagePayload_setTraceID" "', argument " "2"" of type '" "std::string const &""'"); + } + arg2 = ptr; + } + { + try { + (arg1)->setTraceID((std::string const &)*arg2); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + if (SWIG_IsNewObj(res2)) delete arg2; + return resultobj; +fail: + if (SWIG_IsNewObj(res2)) delete arg2; + return NULL; +} + + +SWIGINTERN PyObject *_wrap_MessagePayload_ext(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::MessagePayload *arg1 = (ppc::protocol::MessagePayload *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::MessagePayload const > tempshared1 ; + std::shared_ptr< ppc::protocol::MessagePayload const > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + uint16_t result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessagePayload_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "MessagePayload_ext" "', argument " "1"" of type '" "ppc::protocol::MessagePayload const *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< const ppc::protocol::MessagePayload > * >(argp1); + delete reinterpret_cast< std::shared_ptr< const ppc::protocol::MessagePayload > * >(argp1); + arg1 = const_cast< ppc::protocol::MessagePayload * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< const ppc::protocol::MessagePayload > * >(argp1); + arg1 = const_cast< ppc::protocol::MessagePayload * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + result = (uint16_t)((ppc::protocol::MessagePayload const *)arg1)->ext(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_From_unsigned_SS_short(static_cast< unsigned short >(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_MessagePayload_setExt(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::MessagePayload *arg1 = (ppc::protocol::MessagePayload *) 0 ; + uint16_t arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::MessagePayload > tempshared1 ; + std::shared_ptr< ppc::protocol::MessagePayload > *smartarg1 = 0 ; + unsigned short val2 ; + int ecode2 = 0 ; + PyObject *swig_obj[2] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "MessagePayload_setExt", 2, 2, swig_obj)) SWIG_fail; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessagePayload_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "MessagePayload_setExt" "', argument " "1"" of type '" "ppc::protocol::MessagePayload *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::protocol::MessagePayload > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::protocol::MessagePayload > * >(argp1); + arg1 = const_cast< ppc::protocol::MessagePayload * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::protocol::MessagePayload > * >(argp1); + arg1 = const_cast< ppc::protocol::MessagePayload * >((smartarg1 ? smartarg1->get() : 0)); + } + } + ecode2 = SWIG_AsVal_unsigned_SS_short(swig_obj[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "MessagePayload_setExt" "', argument " "2"" of type '" "uint16_t""'"); + } + arg2 = static_cast< uint16_t >(val2); + { + try { + (arg1)->setExt(arg2); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_MessagePayload_setRespPacket(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::MessagePayload *arg1 = (ppc::protocol::MessagePayload *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::MessagePayload > tempshared1 ; + std::shared_ptr< ppc::protocol::MessagePayload > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessagePayload_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "MessagePayload_setRespPacket" "', argument " "1"" of type '" "ppc::protocol::MessagePayload *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::protocol::MessagePayload > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::protocol::MessagePayload > * >(argp1); + arg1 = const_cast< ppc::protocol::MessagePayload * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::protocol::MessagePayload > * >(argp1); + arg1 = const_cast< ppc::protocol::MessagePayload * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + (arg1)->setRespPacket(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_MessagePayload_isRespPacket(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::MessagePayload *arg1 = (ppc::protocol::MessagePayload *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::MessagePayload > tempshared1 ; + std::shared_ptr< ppc::protocol::MessagePayload > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + bool result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessagePayload_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "MessagePayload_isRespPacket" "', argument " "1"" of type '" "ppc::protocol::MessagePayload *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::protocol::MessagePayload > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::protocol::MessagePayload > * >(argp1); + arg1 = const_cast< ppc::protocol::MessagePayload * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::protocol::MessagePayload > * >(argp1); + arg1 = const_cast< ppc::protocol::MessagePayload * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + result = (bool)(arg1)->isRespPacket(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_From_bool(static_cast< bool >(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_MessagePayload_releasePayload(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::MessagePayload *arg1 = (ppc::protocol::MessagePayload *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::MessagePayload > tempshared1 ; + std::shared_ptr< ppc::protocol::MessagePayload > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessagePayload_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "MessagePayload_releasePayload" "', argument " "1"" of type '" "ppc::protocol::MessagePayload *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::protocol::MessagePayload > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::protocol::MessagePayload > * >(argp1); + arg1 = const_cast< ppc::protocol::MessagePayload * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::protocol::MessagePayload > * >(argp1); + arg1 = const_cast< ppc::protocol::MessagePayload * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + (arg1)->releasePayload(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *MessagePayload_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *obj; + if (!SWIG_Python_UnpackTuple(args, "swigregister", 1, 1, &obj)) return NULL; + SWIG_TypeNewClientData(SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessagePayload_t, SWIG_NewClientData(obj)); + return SWIG_Py_Void(); +} + +SWIGINTERN PyObject *_wrap_delete_MessagePayloadBuilder(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::MessagePayloadBuilder *arg1 = (ppc::protocol::MessagePayloadBuilder *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::MessagePayloadBuilder > tempshared1 ; + std::shared_ptr< ppc::protocol::MessagePayloadBuilder > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessagePayloadBuilder_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_MessagePayloadBuilder" "', argument " "1"" of type '" "ppc::protocol::MessagePayloadBuilder *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::protocol::MessagePayloadBuilder > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::protocol::MessagePayloadBuilder > * >(argp1); + arg1 = const_cast< ppc::protocol::MessagePayloadBuilder * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::protocol::MessagePayloadBuilder > * >(argp1); + arg1 = const_cast< ppc::protocol::MessagePayloadBuilder * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + (void)arg1; delete smartarg1; + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_MessagePayloadBuilder_build__SWIG_0(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + ppc::protocol::MessagePayloadBuilder *arg1 = (ppc::protocol::MessagePayloadBuilder *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::MessagePayloadBuilder > tempshared1 ; + std::shared_ptr< ppc::protocol::MessagePayloadBuilder > *smartarg1 = 0 ; + ppc::protocol::MessagePayload::Ptr result; + + (void)self; + if ((nobjs < 1) || (nobjs > 1)) SWIG_fail; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessagePayloadBuilder_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "MessagePayloadBuilder_build" "', argument " "1"" of type '" "ppc::protocol::MessagePayloadBuilder *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::protocol::MessagePayloadBuilder > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::protocol::MessagePayloadBuilder > * >(argp1); + arg1 = const_cast< ppc::protocol::MessagePayloadBuilder * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::protocol::MessagePayloadBuilder > * >(argp1); + arg1 = const_cast< ppc::protocol::MessagePayloadBuilder * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + result = (arg1)->build(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + { + std::shared_ptr< ppc::protocol::MessagePayload > *smartresult = result ? new std::shared_ptr< ppc::protocol::MessagePayload >(result) : 0; + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(smartresult), SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessagePayload_t, SWIG_POINTER_OWN); + } + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_MessagePayloadBuilder_build__SWIG_1(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + ppc::protocol::MessagePayloadBuilder *arg1 = (ppc::protocol::MessagePayloadBuilder *) 0 ; + bcos::bytesConstRef arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::MessagePayloadBuilder > tempshared1 ; + std::shared_ptr< ppc::protocol::MessagePayloadBuilder > *smartarg1 = 0 ; + void *argp2 ; + int res2 = 0 ; + ppc::protocol::MessagePayload::Ptr result; + + (void)self; + if ((nobjs < 2) || (nobjs > 2)) SWIG_fail; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessagePayloadBuilder_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "MessagePayloadBuilder_build" "', argument " "1"" of type '" "ppc::protocol::MessagePayloadBuilder *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::protocol::MessagePayloadBuilder > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::protocol::MessagePayloadBuilder > * >(argp1); + arg1 = const_cast< ppc::protocol::MessagePayloadBuilder * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::protocol::MessagePayloadBuilder > * >(argp1); + arg1 = const_cast< ppc::protocol::MessagePayloadBuilder * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + res2 = SWIG_ConvertPtr(swig_obj[1], &argp2, SWIGTYPE_p_bcos__bytesConstRef, 0 | 0); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "MessagePayloadBuilder_build" "', argument " "2"" of type '" "bcos::bytesConstRef""'"); + } + if (!argp2) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "MessagePayloadBuilder_build" "', argument " "2"" of type '" "bcos::bytesConstRef""'"); + } else { + bcos::bytesConstRef * temp = reinterpret_cast< bcos::bytesConstRef * >(argp2); + arg2 = *temp; + if (SWIG_IsNewObj(res2)) delete temp; + } + } + { + try { + result = (arg1)->build(arg2); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + { + std::shared_ptr< ppc::protocol::MessagePayload > *smartresult = result ? new std::shared_ptr< ppc::protocol::MessagePayload >(result) : 0; + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(smartresult), SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessagePayload_t, SWIG_POINTER_OWN); + } + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_MessagePayloadBuilder_build(PyObject *self, PyObject *args) { + Py_ssize_t argc; + PyObject *argv[3] = { + 0 + }; + + if (!(argc = SWIG_Python_UnpackTuple(args, "MessagePayloadBuilder_build", 0, 2, argv))) SWIG_fail; + --argc; + if (argc == 1) { + int _v = 0; + int res = SWIG_ConvertPtr(argv[0], 0, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessagePayloadBuilder_t, 0); + _v = SWIG_CheckState(res); + if (_v) { + return _wrap_MessagePayloadBuilder_build__SWIG_0(self, argc, argv); + } + } + if (argc == 2) { + int _v = 0; + int res = SWIG_ConvertPtr(argv[0], 0, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessagePayloadBuilder_t, 0); + _v = SWIG_CheckState(res); + if (_v) { + int res = SWIG_ConvertPtr(argv[1], 0, SWIGTYPE_p_bcos__bytesConstRef, SWIG_POINTER_NO_NULL | 0); + _v = SWIG_CheckState(res); + if (_v) { + return _wrap_MessagePayloadBuilder_build__SWIG_1(self, argc, argv); + } + } + } + +fail: + SWIG_Python_RaiseOrModifyTypeError("Wrong number or type of arguments for overloaded function 'MessagePayloadBuilder_build'.\n" + " Possible C/C++ prototypes are:\n" + " ppc::protocol::MessagePayloadBuilder::build()\n" + " ppc::protocol::MessagePayloadBuilder::build(bcos::bytesConstRef)\n"); + return 0; +} + + +SWIGINTERN PyObject *MessagePayloadBuilder_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *obj; + if (!SWIG_Python_UnpackTuple(args, "swigregister", 1, 1, &obj)) return NULL; + SWIG_TypeNewClientData(SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessagePayloadBuilder_t, SWIG_NewClientData(obj)); + return SWIG_Py_Void(); +} + +SWIGINTERN PyObject *_wrap_delete_IFrontClient(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::front::IFrontClient *arg1 = (ppc::front::IFrontClient *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::front::IFrontClient > tempshared1 ; + std::shared_ptr< ppc::front::IFrontClient > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__front__IFrontClient_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_IFrontClient" "', argument " "1"" of type '" "ppc::front::IFrontClient *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::front::IFrontClient > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::front::IFrontClient > * >(argp1); + arg1 = const_cast< ppc::front::IFrontClient * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::front::IFrontClient > * >(argp1); + arg1 = const_cast< ppc::front::IFrontClient * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + (void)arg1; delete smartarg1; + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_IFrontClient_onReceiveMessage(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::front::IFrontClient *arg1 = (ppc::front::IFrontClient *) 0 ; + ppc::protocol::Message::Ptr *arg2 = 0 ; + SwigValueWrapper< std::function< void (std::shared_ptr< bcos::Error >) > > arg3 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::front::IFrontClient > tempshared1 ; + std::shared_ptr< ppc::front::IFrontClient > *smartarg1 = 0 ; + void *argp2 ; + int res2 = 0 ; + ppc::protocol::Message::Ptr tempshared2 ; + void *argp3 ; + int res3 = 0 ; + PyObject *swig_obj[3] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "IFrontClient_onReceiveMessage", 3, 3, swig_obj)) SWIG_fail; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__front__IFrontClient_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IFrontClient_onReceiveMessage" "', argument " "1"" of type '" "ppc::front::IFrontClient *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::front::IFrontClient > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::front::IFrontClient > * >(argp1); + arg1 = const_cast< ppc::front::IFrontClient * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::front::IFrontClient > * >(argp1); + arg1 = const_cast< ppc::front::IFrontClient * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + int newmem = 0; + res2 = SWIG_ConvertPtrAndOwn(swig_obj[1], &argp2, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__Message_t, 0 , &newmem); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "IFrontClient_onReceiveMessage" "', argument " "2"" of type '" "ppc::protocol::Message::Ptr const &""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + if (argp2) tempshared2 = *reinterpret_cast< ppc::protocol::Message::Ptr * >(argp2); + delete reinterpret_cast< ppc::protocol::Message::Ptr * >(argp2); + arg2 = &tempshared2; + } else { + arg2 = (argp2) ? reinterpret_cast< ppc::protocol::Message::Ptr * >(argp2) : &tempshared2; + } + } + { + res3 = SWIG_ConvertPtr(swig_obj[2], &argp3, SWIGTYPE_p_std__functionT_void_fstd__shared_ptrT_bcos__Error_tF_t, 0 | 0); + if (!SWIG_IsOK(res3)) { + SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "IFrontClient_onReceiveMessage" "', argument " "3"" of type '" "ppc::protocol::ReceiveMsgFunc""'"); + } + if (!argp3) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "IFrontClient_onReceiveMessage" "', argument " "3"" of type '" "ppc::protocol::ReceiveMsgFunc""'"); + } else { + ppc::protocol::ReceiveMsgFunc * temp = reinterpret_cast< ppc::protocol::ReceiveMsgFunc * >(argp3); + arg3 = *temp; + if (SWIG_IsNewObj(res3)) delete temp; + } + } + { + try { + (arg1)->onReceiveMessage((ppc::protocol::Message::Ptr const &)*arg2,arg3); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *IFrontClient_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *obj; + if (!SWIG_Python_UnpackTuple(args, "swigregister", 1, 1, &obj)) return NULL; + SWIG_TypeNewClientData(SWIGTYPE_p_std__shared_ptrT_ppc__front__IFrontClient_t, SWIG_NewClientData(obj)); + return SWIG_Py_Void(); +} + +SWIGINTERN PyObject *_wrap_new_ErrorCallback(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + PyObject *arg1 = (PyObject *) 0 ; + PyObject *swig_obj[1] ; + ppc::front::ErrorCallback *result = 0 ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + arg1 = swig_obj[0]; + { + try { + if ( arg1 != Py_None ) { + /* subclassed */ + result = (ppc::front::ErrorCallback *)new SwigDirector_ErrorCallback(arg1); + } else { + SWIG_SetErrorMsg(PyExc_RuntimeError,"accessing abstract class or protected constructor"); + SWIG_fail; + } + + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + { + std::shared_ptr< ppc::front::ErrorCallback > *smartresult = result ? new std::shared_ptr< ppc::front::ErrorCallback >(result SWIG_NO_NULL_DELETER_SWIG_POINTER_NEW) : 0; + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(smartresult), SWIGTYPE_p_std__shared_ptrT_ppc__front__ErrorCallback_t, SWIG_POINTER_NEW | SWIG_POINTER_OWN); + } + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_delete_ErrorCallback(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::front::ErrorCallback *arg1 = (ppc::front::ErrorCallback *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::front::ErrorCallback > tempshared1 ; + std::shared_ptr< ppc::front::ErrorCallback > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__front__ErrorCallback_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_ErrorCallback" "', argument " "1"" of type '" "ppc::front::ErrorCallback *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::front::ErrorCallback > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::front::ErrorCallback > * >(argp1); + arg1 = const_cast< ppc::front::ErrorCallback * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::front::ErrorCallback > * >(argp1); + arg1 = const_cast< ppc::front::ErrorCallback * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + (void)arg1; delete smartarg1; + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ErrorCallback_onError(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::front::ErrorCallback *arg1 = (ppc::front::ErrorCallback *) 0 ; + bcos::Error::Ptr arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::front::ErrorCallback > tempshared1 ; + std::shared_ptr< ppc::front::ErrorCallback > *smartarg1 = 0 ; + void *argp2 ; + int res2 = 0 ; + PyObject *swig_obj[2] ; + Swig::Director *director = 0; + bool upcall = false; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "ErrorCallback_onError", 2, 2, swig_obj)) SWIG_fail; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__front__ErrorCallback_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ErrorCallback_onError" "', argument " "1"" of type '" "ppc::front::ErrorCallback *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::front::ErrorCallback > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::front::ErrorCallback > * >(argp1); + arg1 = const_cast< ppc::front::ErrorCallback * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::front::ErrorCallback > * >(argp1); + arg1 = const_cast< ppc::front::ErrorCallback * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + int newmem = 0; + res2 = SWIG_ConvertPtrAndOwn(swig_obj[1], &argp2, SWIGTYPE_p_std__shared_ptrT_bcos__Error_t, 0 , &newmem); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "ErrorCallback_onError" "', argument " "2"" of type '" "bcos::Error::Ptr""'"); + } + if (argp2) arg2 = *(reinterpret_cast< bcos::Error::Ptr * >(argp2)); + if (newmem & SWIG_CAST_NEW_MEMORY) delete reinterpret_cast< bcos::Error::Ptr * >(argp2); + } + director = SWIG_DIRECTOR_CAST(arg1); + upcall = (director && (director->swig_get_self()==swig_obj[0])); + try { + { + try { + if (upcall) { + Swig::DirectorPureVirtualException::raise("ppc::front::ErrorCallback::onError"); + } else { + (arg1)->onError(arg2); + } + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + } catch (Swig::DirectorException&) { + SWIG_fail; + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_disown_ErrorCallback(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::front::ErrorCallback *arg1 = (ppc::front::ErrorCallback *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::front::ErrorCallback > tempshared1 ; + std::shared_ptr< ppc::front::ErrorCallback > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__front__ErrorCallback_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "disown_ErrorCallback" "', argument " "1"" of type '" "ppc::front::ErrorCallback *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::front::ErrorCallback > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::front::ErrorCallback > * >(argp1); + arg1 = const_cast< ppc::front::ErrorCallback * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::front::ErrorCallback > * >(argp1); + arg1 = const_cast< ppc::front::ErrorCallback * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + Swig::Director *director = SWIG_DIRECTOR_CAST(arg1); + if (director) director->swig_disown(); + } + + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *ErrorCallback_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *obj; + if (!SWIG_Python_UnpackTuple(args, "swigregister", 1, 1, &obj)) return NULL; + SWIG_TypeNewClientData(SWIGTYPE_p_std__shared_ptrT_ppc__front__ErrorCallback_t, SWIG_NewClientData(obj)); + return SWIG_Py_Void(); +} + +SWIGINTERN PyObject *ErrorCallback_swiginit(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + return SWIG_Python_InitShadowInstance(args); +} + +SWIGINTERN PyObject *_wrap_new_MessageDispatcherHandler(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + PyObject *arg1 = (PyObject *) 0 ; + PyObject *swig_obj[1] ; + ppc::front::MessageDispatcherHandler *result = 0 ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + arg1 = swig_obj[0]; + { + try { + if ( arg1 != Py_None ) { + /* subclassed */ + result = (ppc::front::MessageDispatcherHandler *)new SwigDirector_MessageDispatcherHandler(arg1); + } else { + SWIG_SetErrorMsg(PyExc_RuntimeError,"accessing abstract class or protected constructor"); + SWIG_fail; + } + + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + { + std::shared_ptr< ppc::front::MessageDispatcherHandler > *smartresult = result ? new std::shared_ptr< ppc::front::MessageDispatcherHandler >(result SWIG_NO_NULL_DELETER_SWIG_POINTER_NEW) : 0; + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(smartresult), SWIGTYPE_p_std__shared_ptrT_ppc__front__MessageDispatcherHandler_t, SWIG_POINTER_NEW | SWIG_POINTER_OWN); + } + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_delete_MessageDispatcherHandler(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::front::MessageDispatcherHandler *arg1 = (ppc::front::MessageDispatcherHandler *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::front::MessageDispatcherHandler > tempshared1 ; + std::shared_ptr< ppc::front::MessageDispatcherHandler > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__front__MessageDispatcherHandler_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_MessageDispatcherHandler" "', argument " "1"" of type '" "ppc::front::MessageDispatcherHandler *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::front::MessageDispatcherHandler > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::front::MessageDispatcherHandler > * >(argp1); + arg1 = const_cast< ppc::front::MessageDispatcherHandler * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::front::MessageDispatcherHandler > * >(argp1); + arg1 = const_cast< ppc::front::MessageDispatcherHandler * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + (void)arg1; delete smartarg1; + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_MessageDispatcherHandler_onMessage(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::front::MessageDispatcherHandler *arg1 = (ppc::front::MessageDispatcherHandler *) 0 ; + ppc::protocol::Message::Ptr arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::front::MessageDispatcherHandler > tempshared1 ; + std::shared_ptr< ppc::front::MessageDispatcherHandler > *smartarg1 = 0 ; + void *argp2 ; + int res2 = 0 ; + PyObject *swig_obj[2] ; + Swig::Director *director = 0; + bool upcall = false; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "MessageDispatcherHandler_onMessage", 2, 2, swig_obj)) SWIG_fail; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__front__MessageDispatcherHandler_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "MessageDispatcherHandler_onMessage" "', argument " "1"" of type '" "ppc::front::MessageDispatcherHandler *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::front::MessageDispatcherHandler > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::front::MessageDispatcherHandler > * >(argp1); + arg1 = const_cast< ppc::front::MessageDispatcherHandler * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::front::MessageDispatcherHandler > * >(argp1); + arg1 = const_cast< ppc::front::MessageDispatcherHandler * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + int newmem = 0; + res2 = SWIG_ConvertPtrAndOwn(swig_obj[1], &argp2, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__Message_t, 0 , &newmem); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "MessageDispatcherHandler_onMessage" "', argument " "2"" of type '" "ppc::protocol::Message::Ptr""'"); + } + if (argp2) arg2 = *(reinterpret_cast< ppc::protocol::Message::Ptr * >(argp2)); + if (newmem & SWIG_CAST_NEW_MEMORY) delete reinterpret_cast< ppc::protocol::Message::Ptr * >(argp2); + } + director = SWIG_DIRECTOR_CAST(arg1); + upcall = (director && (director->swig_get_self()==swig_obj[0])); + try { + { + try { + if (upcall) { + Swig::DirectorPureVirtualException::raise("ppc::front::MessageDispatcherHandler::onMessage"); + } else { + (arg1)->onMessage(arg2); + } + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + } catch (Swig::DirectorException&) { + SWIG_fail; + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_disown_MessageDispatcherHandler(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::front::MessageDispatcherHandler *arg1 = (ppc::front::MessageDispatcherHandler *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::front::MessageDispatcherHandler > tempshared1 ; + std::shared_ptr< ppc::front::MessageDispatcherHandler > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__front__MessageDispatcherHandler_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "disown_MessageDispatcherHandler" "', argument " "1"" of type '" "ppc::front::MessageDispatcherHandler *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::front::MessageDispatcherHandler > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::front::MessageDispatcherHandler > * >(argp1); + arg1 = const_cast< ppc::front::MessageDispatcherHandler * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::front::MessageDispatcherHandler > * >(argp1); + arg1 = const_cast< ppc::front::MessageDispatcherHandler * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + Swig::Director *director = SWIG_DIRECTOR_CAST(arg1); + if (director) director->swig_disown(); + } + + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *MessageDispatcherHandler_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *obj; + if (!SWIG_Python_UnpackTuple(args, "swigregister", 1, 1, &obj)) return NULL; + SWIG_TypeNewClientData(SWIGTYPE_p_std__shared_ptrT_ppc__front__MessageDispatcherHandler_t, SWIG_NewClientData(obj)); + return SWIG_Py_Void(); +} + +SWIGINTERN PyObject *MessageDispatcherHandler_swiginit(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + return SWIG_Python_InitShadowInstance(args); +} + +SWIGINTERN PyObject *_wrap_new_SendResponseHandler(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + SwigValueWrapper< std::function< void (std::shared_ptr< bcos::bytes > &&) > > arg1 ; + void *argp1 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + ppc::front::SendResponseHandler *result = 0 ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1, SWIGTYPE_p_std__functionT_void_fstd__shared_ptrT_bcos__bytes_t_RRF_t, 0 | 0); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "new_SendResponseHandler" "', argument " "1"" of type '" "ppc::protocol::SendResponseFunction""'"); + } + if (!argp1) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_SendResponseHandler" "', argument " "1"" of type '" "ppc::protocol::SendResponseFunction""'"); + } else { + ppc::protocol::SendResponseFunction * temp = reinterpret_cast< ppc::protocol::SendResponseFunction * >(argp1); + arg1 = *temp; + if (SWIG_IsNewObj(res1)) delete temp; + } + } + { + try { + result = (ppc::front::SendResponseHandler *)new ppc::front::SendResponseHandler(arg1); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_ppc__front__SendResponseHandler, SWIG_POINTER_NEW | 0 ); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_delete_SendResponseHandler(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::front::SendResponseHandler *arg1 = (ppc::front::SendResponseHandler *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_ppc__front__SendResponseHandler, SWIG_POINTER_DISOWN | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_SendResponseHandler" "', argument " "1"" of type '" "ppc::front::SendResponseHandler *""'"); + } + arg1 = reinterpret_cast< ppc::front::SendResponseHandler * >(argp1); + { + try { + delete arg1; + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_SendResponseHandler_sendResponse(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::front::SendResponseHandler *arg1 = (ppc::front::SendResponseHandler *) 0 ; + std::shared_ptr< bcos::bytes > *arg2 = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + void *argp2 = 0 ; + int res2 = 0 ; + std::unique_ptr< std::shared_ptr< bcos::bytes > > rvrdeleter2 ; + PyObject *swig_obj[2] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "SendResponseHandler_sendResponse", 2, 2, swig_obj)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_ppc__front__SendResponseHandler, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SendResponseHandler_sendResponse" "', argument " "1"" of type '" "ppc::front::SendResponseHandler *""'"); + } + arg1 = reinterpret_cast< ppc::front::SendResponseHandler * >(argp1); + res2 = SWIG_ConvertPtr(swig_obj[1], &argp2, SWIGTYPE_p_std__shared_ptrT_bcos__bytes_t, SWIG_POINTER_RELEASE | 0 ); + if (!SWIG_IsOK(res2)) { + if (res2 == SWIG_ERROR_RELEASE_NOT_OWNED) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "SendResponseHandler_sendResponse" "', cannot release ownership as memory is not owned for argument " "2"" of type '" "std::shared_ptr< bcos::bytes > &&""'"); + } else { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "SendResponseHandler_sendResponse" "', argument " "2"" of type '" "std::shared_ptr< bcos::bytes > &&""'"); + } + } + if (!argp2) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "SendResponseHandler_sendResponse" "', argument " "2"" of type '" "std::shared_ptr< bcos::bytes > &&""'"); + } + arg2 = reinterpret_cast< std::shared_ptr< bcos::bytes > * >(argp2); + rvrdeleter2.reset(arg2); + { + try { + (arg1)->sendResponse((std::shared_ptr< bcos::bytes > &&)*arg2); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *SendResponseHandler_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *obj; + if (!SWIG_Python_UnpackTuple(args, "swigregister", 1, 1, &obj)) return NULL; + SWIG_TypeNewClientData(SWIGTYPE_p_ppc__front__SendResponseHandler, SWIG_NewClientData(obj)); + return SWIG_Py_Void(); +} + +SWIGINTERN PyObject *SendResponseHandler_swiginit(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + return SWIG_Python_InitShadowInstance(args); +} + +SWIGINTERN PyObject *_wrap_new_IMessageHandler(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + PyObject *arg1 = (PyObject *) 0 ; + PyObject *swig_obj[1] ; + ppc::front::IMessageHandler *result = 0 ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + arg1 = swig_obj[0]; + { + try { + if ( arg1 != Py_None ) { + /* subclassed */ + result = (ppc::front::IMessageHandler *)new SwigDirector_IMessageHandler(arg1); + } else { + SWIG_SetErrorMsg(PyExc_RuntimeError,"accessing abstract class or protected constructor"); + SWIG_fail; + } + + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + { + std::shared_ptr< ppc::front::IMessageHandler > *smartresult = result ? new std::shared_ptr< ppc::front::IMessageHandler >(result SWIG_NO_NULL_DELETER_SWIG_POINTER_NEW) : 0; + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(smartresult), SWIGTYPE_p_std__shared_ptrT_ppc__front__IMessageHandler_t, SWIG_POINTER_NEW | SWIG_POINTER_OWN); + } + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_delete_IMessageHandler(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::front::IMessageHandler *arg1 = (ppc::front::IMessageHandler *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::front::IMessageHandler > tempshared1 ; + std::shared_ptr< ppc::front::IMessageHandler > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__front__IMessageHandler_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_IMessageHandler" "', argument " "1"" of type '" "ppc::front::IMessageHandler *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::front::IMessageHandler > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::front::IMessageHandler > * >(argp1); + arg1 = const_cast< ppc::front::IMessageHandler * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::front::IMessageHandler > * >(argp1); + arg1 = const_cast< ppc::front::IMessageHandler * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + (void)arg1; delete smartarg1; + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_IMessageHandler_onMessage(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::front::IMessageHandler *arg1 = (ppc::front::IMessageHandler *) 0 ; + bcos::Error::Ptr arg2 ; + ppc::protocol::Message::Ptr arg3 ; + SwigValueWrapper< ppc::front::SendResponseHandler > arg4 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::front::IMessageHandler > tempshared1 ; + std::shared_ptr< ppc::front::IMessageHandler > *smartarg1 = 0 ; + void *argp2 ; + int res2 = 0 ; + void *argp3 ; + int res3 = 0 ; + void *argp4 ; + int res4 = 0 ; + PyObject *swig_obj[4] ; + Swig::Director *director = 0; + bool upcall = false; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "IMessageHandler_onMessage", 4, 4, swig_obj)) SWIG_fail; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__front__IMessageHandler_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IMessageHandler_onMessage" "', argument " "1"" of type '" "ppc::front::IMessageHandler *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::front::IMessageHandler > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::front::IMessageHandler > * >(argp1); + arg1 = const_cast< ppc::front::IMessageHandler * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::front::IMessageHandler > * >(argp1); + arg1 = const_cast< ppc::front::IMessageHandler * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + int newmem = 0; + res2 = SWIG_ConvertPtrAndOwn(swig_obj[1], &argp2, SWIGTYPE_p_std__shared_ptrT_bcos__Error_t, 0 , &newmem); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "IMessageHandler_onMessage" "', argument " "2"" of type '" "bcos::Error::Ptr""'"); + } + if (argp2) arg2 = *(reinterpret_cast< bcos::Error::Ptr * >(argp2)); + if (newmem & SWIG_CAST_NEW_MEMORY) delete reinterpret_cast< bcos::Error::Ptr * >(argp2); + } + { + int newmem = 0; + res3 = SWIG_ConvertPtrAndOwn(swig_obj[2], &argp3, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__Message_t, 0 , &newmem); + if (!SWIG_IsOK(res3)) { + SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "IMessageHandler_onMessage" "', argument " "3"" of type '" "ppc::protocol::Message::Ptr""'"); + } + if (argp3) arg3 = *(reinterpret_cast< ppc::protocol::Message::Ptr * >(argp3)); + if (newmem & SWIG_CAST_NEW_MEMORY) delete reinterpret_cast< ppc::protocol::Message::Ptr * >(argp3); + } + { + res4 = SWIG_ConvertPtr(swig_obj[3], &argp4, SWIGTYPE_p_ppc__front__SendResponseHandler, 0 | 0); + if (!SWIG_IsOK(res4)) { + SWIG_exception_fail(SWIG_ArgError(res4), "in method '" "IMessageHandler_onMessage" "', argument " "4"" of type '" "ppc::front::SendResponseHandler""'"); + } + if (!argp4) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "IMessageHandler_onMessage" "', argument " "4"" of type '" "ppc::front::SendResponseHandler""'"); + } else { + ppc::front::SendResponseHandler * temp = reinterpret_cast< ppc::front::SendResponseHandler * >(argp4); + arg4 = *temp; + if (SWIG_IsNewObj(res4)) delete temp; + } + } + director = SWIG_DIRECTOR_CAST(arg1); + upcall = (director && (director->swig_get_self()==swig_obj[0])); + try { + { + try { + if (upcall) { + Swig::DirectorPureVirtualException::raise("ppc::front::IMessageHandler::onMessage"); + } else { + (arg1)->onMessage(arg2,arg3,arg4); + } + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + } catch (Swig::DirectorException&) { + SWIG_fail; + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_disown_IMessageHandler(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::front::IMessageHandler *arg1 = (ppc::front::IMessageHandler *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::front::IMessageHandler > tempshared1 ; + std::shared_ptr< ppc::front::IMessageHandler > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__front__IMessageHandler_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "disown_IMessageHandler" "', argument " "1"" of type '" "ppc::front::IMessageHandler *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::front::IMessageHandler > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::front::IMessageHandler > * >(argp1); + arg1 = const_cast< ppc::front::IMessageHandler * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::front::IMessageHandler > * >(argp1); + arg1 = const_cast< ppc::front::IMessageHandler * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + Swig::Director *director = SWIG_DIRECTOR_CAST(arg1); + if (director) director->swig_disown(); + } + + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *IMessageHandler_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *obj; + if (!SWIG_Python_UnpackTuple(args, "swigregister", 1, 1, &obj)) return NULL; + SWIG_TypeNewClientData(SWIGTYPE_p_std__shared_ptrT_ppc__front__IMessageHandler_t, SWIG_NewClientData(obj)); + return SWIG_Py_Void(); +} + +SWIGINTERN PyObject *IMessageHandler_swiginit(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + return SWIG_Python_InitShadowInstance(args); +} + +SWIGINTERN PyObject *_wrap_new_GetPeersInfoHandler(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + PyObject *arg1 = (PyObject *) 0 ; + PyObject *swig_obj[1] ; + ppc::front::GetPeersInfoHandler *result = 0 ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + arg1 = swig_obj[0]; + { + try { + if ( arg1 != Py_None ) { + /* subclassed */ + result = (ppc::front::GetPeersInfoHandler *)new SwigDirector_GetPeersInfoHandler(arg1); + } else { + SWIG_SetErrorMsg(PyExc_RuntimeError,"accessing abstract class or protected constructor"); + SWIG_fail; + } + + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + { + std::shared_ptr< ppc::front::GetPeersInfoHandler > *smartresult = result ? new std::shared_ptr< ppc::front::GetPeersInfoHandler >(result SWIG_NO_NULL_DELETER_SWIG_POINTER_NEW) : 0; + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(smartresult), SWIGTYPE_p_std__shared_ptrT_ppc__front__GetPeersInfoHandler_t, SWIG_POINTER_NEW | SWIG_POINTER_OWN); + } + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_delete_GetPeersInfoHandler(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::front::GetPeersInfoHandler *arg1 = (ppc::front::GetPeersInfoHandler *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::front::GetPeersInfoHandler > tempshared1 ; + std::shared_ptr< ppc::front::GetPeersInfoHandler > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__front__GetPeersInfoHandler_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_GetPeersInfoHandler" "', argument " "1"" of type '" "ppc::front::GetPeersInfoHandler *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::front::GetPeersInfoHandler > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::front::GetPeersInfoHandler > * >(argp1); + arg1 = const_cast< ppc::front::GetPeersInfoHandler * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::front::GetPeersInfoHandler > * >(argp1); + arg1 = const_cast< ppc::front::GetPeersInfoHandler * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + (void)arg1; delete smartarg1; + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_GetPeersInfoHandler_onPeersInfo(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::front::GetPeersInfoHandler *arg1 = (ppc::front::GetPeersInfoHandler *) 0 ; + bcos::Error::Ptr arg2 ; + std::string *arg3 = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::front::GetPeersInfoHandler > tempshared1 ; + std::shared_ptr< ppc::front::GetPeersInfoHandler > *smartarg1 = 0 ; + void *argp2 ; + int res2 = 0 ; + int res3 = SWIG_OLDOBJ ; + PyObject *swig_obj[3] ; + Swig::Director *director = 0; + bool upcall = false; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "GetPeersInfoHandler_onPeersInfo", 3, 3, swig_obj)) SWIG_fail; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__front__GetPeersInfoHandler_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GetPeersInfoHandler_onPeersInfo" "', argument " "1"" of type '" "ppc::front::GetPeersInfoHandler *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::front::GetPeersInfoHandler > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::front::GetPeersInfoHandler > * >(argp1); + arg1 = const_cast< ppc::front::GetPeersInfoHandler * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::front::GetPeersInfoHandler > * >(argp1); + arg1 = const_cast< ppc::front::GetPeersInfoHandler * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + int newmem = 0; + res2 = SWIG_ConvertPtrAndOwn(swig_obj[1], &argp2, SWIGTYPE_p_std__shared_ptrT_bcos__Error_t, 0 , &newmem); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "GetPeersInfoHandler_onPeersInfo" "', argument " "2"" of type '" "bcos::Error::Ptr""'"); + } + if (argp2) arg2 = *(reinterpret_cast< bcos::Error::Ptr * >(argp2)); + if (newmem & SWIG_CAST_NEW_MEMORY) delete reinterpret_cast< bcos::Error::Ptr * >(argp2); + } + { + std::string *ptr = (std::string *)0; + res3 = SWIG_AsPtr_std_string(swig_obj[2], &ptr); + if (!SWIG_IsOK(res3)) { + SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "GetPeersInfoHandler_onPeersInfo" "', argument " "3"" of type '" "std::string const &""'"); + } + if (!ptr) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "GetPeersInfoHandler_onPeersInfo" "', argument " "3"" of type '" "std::string const &""'"); + } + arg3 = ptr; + } + director = SWIG_DIRECTOR_CAST(arg1); + upcall = (director && (director->swig_get_self()==swig_obj[0])); + try { + { + try { + if (upcall) { + Swig::DirectorPureVirtualException::raise("ppc::front::GetPeersInfoHandler::onPeersInfo"); + } else { + (arg1)->onPeersInfo(arg2,(std::string const &)*arg3); + } + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + } catch (Swig::DirectorException&) { + SWIG_fail; + } + resultobj = SWIG_Py_Void(); + if (SWIG_IsNewObj(res3)) delete arg3; + return resultobj; +fail: + if (SWIG_IsNewObj(res3)) delete arg3; + return NULL; +} + + +SWIGINTERN PyObject *_wrap_disown_GetPeersInfoHandler(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::front::GetPeersInfoHandler *arg1 = (ppc::front::GetPeersInfoHandler *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::front::GetPeersInfoHandler > tempshared1 ; + std::shared_ptr< ppc::front::GetPeersInfoHandler > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__front__GetPeersInfoHandler_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "disown_GetPeersInfoHandler" "', argument " "1"" of type '" "ppc::front::GetPeersInfoHandler *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::front::GetPeersInfoHandler > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::front::GetPeersInfoHandler > * >(argp1); + arg1 = const_cast< ppc::front::GetPeersInfoHandler * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::front::GetPeersInfoHandler > * >(argp1); + arg1 = const_cast< ppc::front::GetPeersInfoHandler * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + Swig::Director *director = SWIG_DIRECTOR_CAST(arg1); + if (director) director->swig_disown(); + } + + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *GetPeersInfoHandler_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *obj; + if (!SWIG_Python_UnpackTuple(args, "swigregister", 1, 1, &obj)) return NULL; + SWIG_TypeNewClientData(SWIGTYPE_p_std__shared_ptrT_ppc__front__GetPeersInfoHandler_t, SWIG_NewClientData(obj)); + return SWIG_Py_Void(); +} + +SWIGINTERN PyObject *GetPeersInfoHandler_swiginit(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + return SWIG_Python_InitShadowInstance(args); +} + +SWIGINTERN PyObject *_wrap_delete_IFront(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::front::IFront *arg1 = (ppc::front::IFront *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::front::IFront > tempshared1 ; + std::shared_ptr< ppc::front::IFront > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__front__IFront_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_IFront" "', argument " "1"" of type '" "ppc::front::IFront *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::front::IFront > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::front::IFront > * >(argp1); + arg1 = const_cast< ppc::front::IFront * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::front::IFront > * >(argp1); + arg1 = const_cast< ppc::front::IFront * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + (void)arg1; delete smartarg1; + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_IFront_start(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::front::IFront *arg1 = (ppc::front::IFront *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::front::IFront > tempshared1 ; + std::shared_ptr< ppc::front::IFront > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__front__IFront_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IFront_start" "', argument " "1"" of type '" "ppc::front::IFront *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::front::IFront > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::front::IFront > * >(argp1); + arg1 = const_cast< ppc::front::IFront * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::front::IFront > * >(argp1); + arg1 = const_cast< ppc::front::IFront * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + (arg1)->start(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_IFront_stop(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::front::IFront *arg1 = (ppc::front::IFront *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::front::IFront > tempshared1 ; + std::shared_ptr< ppc::front::IFront > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__front__IFront_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IFront_stop" "', argument " "1"" of type '" "ppc::front::IFront *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::front::IFront > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::front::IFront > * >(argp1); + arg1 = const_cast< ppc::front::IFront * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::front::IFront > * >(argp1); + arg1 = const_cast< ppc::front::IFront * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + (arg1)->stop(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_IFront_register_topic_handler(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::front::IFront *arg1 = (ppc::front::IFront *) 0 ; + std::string *arg2 = 0 ; + ppc::front::MessageDispatcherHandler::Ptr arg3 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::front::IFront > tempshared1 ; + std::shared_ptr< ppc::front::IFront > *smartarg1 = 0 ; + int res2 = SWIG_OLDOBJ ; + void *argp3 ; + int res3 = 0 ; + PyObject *swig_obj[3] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "IFront_register_topic_handler", 3, 3, swig_obj)) SWIG_fail; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__front__IFront_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IFront_register_topic_handler" "', argument " "1"" of type '" "ppc::front::IFront *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::front::IFront > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::front::IFront > * >(argp1); + arg1 = const_cast< ppc::front::IFront * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::front::IFront > * >(argp1); + arg1 = const_cast< ppc::front::IFront * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + std::string *ptr = (std::string *)0; + res2 = SWIG_AsPtr_std_string(swig_obj[1], &ptr); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "IFront_register_topic_handler" "', argument " "2"" of type '" "std::string const &""'"); + } + if (!ptr) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "IFront_register_topic_handler" "', argument " "2"" of type '" "std::string const &""'"); + } + arg2 = ptr; + } + { + int newmem = 0; + res3 = SWIG_ConvertPtrAndOwn(swig_obj[2], &argp3, SWIGTYPE_p_std__shared_ptrT_ppc__front__MessageDispatcherHandler_t, 0 , &newmem); + if (!SWIG_IsOK(res3)) { + SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "IFront_register_topic_handler" "', argument " "3"" of type '" "ppc::front::MessageDispatcherHandler::Ptr""'"); + } + if (argp3) arg3 = *(reinterpret_cast< ppc::front::MessageDispatcherHandler::Ptr * >(argp3)); + if (newmem & SWIG_CAST_NEW_MEMORY) delete reinterpret_cast< ppc::front::MessageDispatcherHandler::Ptr * >(argp3); + } + { + try { + (arg1)->register_topic_handler((std::string const &)*arg2,arg3); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + if (SWIG_IsNewObj(res2)) delete arg2; + return resultobj; +fail: + if (SWIG_IsNewObj(res2)) delete arg2; + return NULL; +} + + +SWIGINTERN PyObject *_wrap_IFront_register_msg_handler(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::front::IFront *arg1 = (ppc::front::IFront *) 0 ; + std::string *arg2 = 0 ; + ppc::front::MessageDispatcherHandler::Ptr arg3 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::front::IFront > tempshared1 ; + std::shared_ptr< ppc::front::IFront > *smartarg1 = 0 ; + int res2 = SWIG_OLDOBJ ; + void *argp3 ; + int res3 = 0 ; + PyObject *swig_obj[3] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "IFront_register_msg_handler", 3, 3, swig_obj)) SWIG_fail; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__front__IFront_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IFront_register_msg_handler" "', argument " "1"" of type '" "ppc::front::IFront *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::front::IFront > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::front::IFront > * >(argp1); + arg1 = const_cast< ppc::front::IFront * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::front::IFront > * >(argp1); + arg1 = const_cast< ppc::front::IFront * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + std::string *ptr = (std::string *)0; + res2 = SWIG_AsPtr_std_string(swig_obj[1], &ptr); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "IFront_register_msg_handler" "', argument " "2"" of type '" "std::string const &""'"); + } + if (!ptr) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "IFront_register_msg_handler" "', argument " "2"" of type '" "std::string const &""'"); + } + arg2 = ptr; + } + { + int newmem = 0; + res3 = SWIG_ConvertPtrAndOwn(swig_obj[2], &argp3, SWIGTYPE_p_std__shared_ptrT_ppc__front__MessageDispatcherHandler_t, 0 , &newmem); + if (!SWIG_IsOK(res3)) { + SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "IFront_register_msg_handler" "', argument " "3"" of type '" "ppc::front::MessageDispatcherHandler::Ptr""'"); + } + if (argp3) arg3 = *(reinterpret_cast< ppc::front::MessageDispatcherHandler::Ptr * >(argp3)); + if (newmem & SWIG_CAST_NEW_MEMORY) delete reinterpret_cast< ppc::front::MessageDispatcherHandler::Ptr * >(argp3); + } + { + try { + (arg1)->register_msg_handler((std::string const &)*arg2,arg3); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + if (SWIG_IsNewObj(res2)) delete arg2; + return resultobj; +fail: + if (SWIG_IsNewObj(res2)) delete arg2; + return NULL; +} + + +SWIGINTERN PyObject *_wrap_IFront_async_send_message(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::front::IFront *arg1 = (ppc::front::IFront *) 0 ; + uint16_t arg2 ; + ppc::protocol::MessageOptionalHeader::Ptr *arg3 = 0 ; + char *arg4 = (char *) 0 ; + uint64_t arg5 ; + int arg6 ; + long arg7 ; + ppc::front::ErrorCallback::Ptr arg8 ; + ppc::front::IMessageHandler::Ptr arg9 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::front::IFront > tempshared1 ; + std::shared_ptr< ppc::front::IFront > *smartarg1 = 0 ; + unsigned short val2 ; + int ecode2 = 0 ; + void *argp3 ; + int res3 = 0 ; + ppc::protocol::MessageOptionalHeader::Ptr tempshared3 ; + int val6 ; + int ecode6 = 0 ; + long val7 ; + int ecode7 = 0 ; + void *argp8 ; + int res8 = 0 ; + void *argp9 ; + int res9 = 0 ; + PyObject *swig_obj[8] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "IFront_async_send_message", 8, 8, swig_obj)) SWIG_fail; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__front__IFront_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IFront_async_send_message" "', argument " "1"" of type '" "ppc::front::IFront *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::front::IFront > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::front::IFront > * >(argp1); + arg1 = const_cast< ppc::front::IFront * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::front::IFront > * >(argp1); + arg1 = const_cast< ppc::front::IFront * >((smartarg1 ? smartarg1->get() : 0)); + } + } + ecode2 = SWIG_AsVal_unsigned_SS_short(swig_obj[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "IFront_async_send_message" "', argument " "2"" of type '" "uint16_t""'"); + } + arg2 = static_cast< uint16_t >(val2); + { + int newmem = 0; + res3 = SWIG_ConvertPtrAndOwn(swig_obj[2], &argp3, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageOptionalHeader_t, 0 , &newmem); + if (!SWIG_IsOK(res3)) { + SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "IFront_async_send_message" "', argument " "3"" of type '" "ppc::protocol::MessageOptionalHeader::Ptr const &""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + if (argp3) tempshared3 = *reinterpret_cast< ppc::protocol::MessageOptionalHeader::Ptr * >(argp3); + delete reinterpret_cast< ppc::protocol::MessageOptionalHeader::Ptr * >(argp3); + arg3 = &tempshared3; + } else { + arg3 = (argp3) ? reinterpret_cast< ppc::protocol::MessageOptionalHeader::Ptr * >(argp3) : &tempshared3; + } + } + { + int res; Py_ssize_t size = 0; const void *buf = 0; +#ifndef Py_LIMITED_API + Py_buffer view; + res = PyObject_GetBuffer(swig_obj[3], &view, PyBUF_CONTIG_RO); +#else +#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated" +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#elif defined(_MSC_VER) +#pragma warning(push) +#pragma warning(disable: 4996) +#endif + res = PyObject_AsReadBuffer(swig_obj[3], &buf, &size); +#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) +#pragma GCC diagnostic pop +#elif defined(_MSC_VER) +#pragma warning(pop) +#endif +#endif + if (res < 0) { + PyErr_Clear(); + SWIG_exception_fail(SWIG_ArgError(res), "in method '" "IFront_async_send_message" "', argument " "4"" of type '" "(char* payload, uint64_t payloadSize)""'"); + } +#ifndef Py_LIMITED_API + size = view.len; + buf = view.buf; + PyBuffer_Release(&view); +#endif + arg4 = (char *) buf; + arg5 = (uint64_t) (size / sizeof(char)); + } + ecode6 = SWIG_AsVal_int(swig_obj[4], &val6); + if (!SWIG_IsOK(ecode6)) { + SWIG_exception_fail(SWIG_ArgError(ecode6), "in method '" "IFront_async_send_message" "', argument " "6"" of type '" "int""'"); + } + arg6 = static_cast< int >(val6); + ecode7 = SWIG_AsVal_long(swig_obj[5], &val7); + if (!SWIG_IsOK(ecode7)) { + SWIG_exception_fail(SWIG_ArgError(ecode7), "in method '" "IFront_async_send_message" "', argument " "7"" of type '" "long""'"); + } + arg7 = static_cast< long >(val7); + { + int newmem = 0; + res8 = SWIG_ConvertPtrAndOwn(swig_obj[6], &argp8, SWIGTYPE_p_std__shared_ptrT_ppc__front__ErrorCallback_t, 0 , &newmem); + if (!SWIG_IsOK(res8)) { + SWIG_exception_fail(SWIG_ArgError(res8), "in method '" "IFront_async_send_message" "', argument " "8"" of type '" "ppc::front::ErrorCallback::Ptr""'"); + } + if (argp8) arg8 = *(reinterpret_cast< ppc::front::ErrorCallback::Ptr * >(argp8)); + if (newmem & SWIG_CAST_NEW_MEMORY) delete reinterpret_cast< ppc::front::ErrorCallback::Ptr * >(argp8); + } + { + int newmem = 0; + res9 = SWIG_ConvertPtrAndOwn(swig_obj[7], &argp9, SWIGTYPE_p_std__shared_ptrT_ppc__front__IMessageHandler_t, 0 , &newmem); + if (!SWIG_IsOK(res9)) { + SWIG_exception_fail(SWIG_ArgError(res9), "in method '" "IFront_async_send_message" "', argument " "9"" of type '" "ppc::front::IMessageHandler::Ptr""'"); + } + if (argp9) arg9 = *(reinterpret_cast< ppc::front::IMessageHandler::Ptr * >(argp9)); + if (newmem & SWIG_CAST_NEW_MEMORY) delete reinterpret_cast< ppc::front::IMessageHandler::Ptr * >(argp9); + } + { + try { + (arg1)->async_send_message(arg2,(ppc::protocol::MessageOptionalHeader::Ptr const &)*arg3,arg4,arg5,arg6,arg7,arg8,arg9); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_IFront_async_send_response(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::front::IFront *arg1 = (ppc::front::IFront *) 0 ; + char *arg2 = (char *) 0 ; + uint64_t arg3 ; + std::string *arg4 = 0 ; + char *arg5 = (char *) 0 ; + uint64_t arg6 ; + int arg7 ; + ppc::front::ErrorCallback::Ptr arg8 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::front::IFront > tempshared1 ; + std::shared_ptr< ppc::front::IFront > *smartarg1 = 0 ; + int res2 ; + char *buf2 = 0 ; + int alloc2 = 0 ; + unsigned long long val3 ; + int ecode3 = 0 ; + int res4 = SWIG_OLDOBJ ; + int val7 ; + int ecode7 = 0 ; + void *argp8 ; + int res8 = 0 ; + PyObject *swig_obj[7] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "IFront_async_send_response", 7, 7, swig_obj)) SWIG_fail; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__front__IFront_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IFront_async_send_response" "', argument " "1"" of type '" "ppc::front::IFront *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::front::IFront > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::front::IFront > * >(argp1); + arg1 = const_cast< ppc::front::IFront * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::front::IFront > * >(argp1); + arg1 = const_cast< ppc::front::IFront * >((smartarg1 ? smartarg1->get() : 0)); + } + } + res2 = SWIG_AsCharPtrAndSize(swig_obj[1], &buf2, NULL, &alloc2); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "IFront_async_send_response" "', argument " "2"" of type '" "char *""'"); + } + arg2 = reinterpret_cast< char * >(buf2); + ecode3 = SWIG_AsVal_unsigned_SS_long_SS_long(swig_obj[2], &val3); + if (!SWIG_IsOK(ecode3)) { + SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "IFront_async_send_response" "', argument " "3"" of type '" "uint64_t""'"); + } + arg3 = static_cast< uint64_t >(val3); + { + std::string *ptr = (std::string *)0; + res4 = SWIG_AsPtr_std_string(swig_obj[3], &ptr); + if (!SWIG_IsOK(res4)) { + SWIG_exception_fail(SWIG_ArgError(res4), "in method '" "IFront_async_send_response" "', argument " "4"" of type '" "std::string const &""'"); + } + if (!ptr) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "IFront_async_send_response" "', argument " "4"" of type '" "std::string const &""'"); + } + arg4 = ptr; + } + { + int res; Py_ssize_t size = 0; const void *buf = 0; +#ifndef Py_LIMITED_API + Py_buffer view; + res = PyObject_GetBuffer(swig_obj[4], &view, PyBUF_CONTIG_RO); +#else +#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated" +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#elif defined(_MSC_VER) +#pragma warning(push) +#pragma warning(disable: 4996) +#endif + res = PyObject_AsReadBuffer(swig_obj[4], &buf, &size); +#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) +#pragma GCC diagnostic pop +#elif defined(_MSC_VER) +#pragma warning(pop) +#endif +#endif + if (res < 0) { + PyErr_Clear(); + SWIG_exception_fail(SWIG_ArgError(res), "in method '" "IFront_async_send_response" "', argument " "5"" of type '" "(char* payload, uint64_t payloadSize)""'"); + } +#ifndef Py_LIMITED_API + size = view.len; + buf = view.buf; + PyBuffer_Release(&view); +#endif + arg5 = (char *) buf; + arg6 = (uint64_t) (size / sizeof(char)); + } + ecode7 = SWIG_AsVal_int(swig_obj[5], &val7); + if (!SWIG_IsOK(ecode7)) { + SWIG_exception_fail(SWIG_ArgError(ecode7), "in method '" "IFront_async_send_response" "', argument " "7"" of type '" "int""'"); + } + arg7 = static_cast< int >(val7); + { + int newmem = 0; + res8 = SWIG_ConvertPtrAndOwn(swig_obj[6], &argp8, SWIGTYPE_p_std__shared_ptrT_ppc__front__ErrorCallback_t, 0 , &newmem); + if (!SWIG_IsOK(res8)) { + SWIG_exception_fail(SWIG_ArgError(res8), "in method '" "IFront_async_send_response" "', argument " "8"" of type '" "ppc::front::ErrorCallback::Ptr""'"); + } + if (argp8) arg8 = *(reinterpret_cast< ppc::front::ErrorCallback::Ptr * >(argp8)); + if (newmem & SWIG_CAST_NEW_MEMORY) delete reinterpret_cast< ppc::front::ErrorCallback::Ptr * >(argp8); + } + { + try { + (arg1)->async_send_response(arg2,arg3,(std::string const &)*arg4,arg5,arg6,arg7,arg8); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + if (alloc2 == SWIG_NEWOBJ) delete[] buf2; + if (SWIG_IsNewObj(res4)) delete arg4; + return resultobj; +fail: + if (alloc2 == SWIG_NEWOBJ) delete[] buf2; + if (SWIG_IsNewObj(res4)) delete arg4; + return NULL; +} + + +SWIGINTERN PyObject *_wrap_IFront_push_msg(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::front::IFront *arg1 = (ppc::front::IFront *) 0 ; + uint16_t arg2 ; + ppc::protocol::MessageOptionalHeader::Ptr *arg3 = 0 ; + char *arg4 = (char *) 0 ; + uint64_t arg5 ; + int arg6 ; + long arg7 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::front::IFront > tempshared1 ; + std::shared_ptr< ppc::front::IFront > *smartarg1 = 0 ; + unsigned short val2 ; + int ecode2 = 0 ; + void *argp3 ; + int res3 = 0 ; + ppc::protocol::MessageOptionalHeader::Ptr tempshared3 ; + int val6 ; + int ecode6 = 0 ; + long val7 ; + int ecode7 = 0 ; + PyObject *swig_obj[6] ; + bcos::Error::Ptr result; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "IFront_push_msg", 6, 6, swig_obj)) SWIG_fail; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__front__IFront_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IFront_push_msg" "', argument " "1"" of type '" "ppc::front::IFront *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::front::IFront > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::front::IFront > * >(argp1); + arg1 = const_cast< ppc::front::IFront * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::front::IFront > * >(argp1); + arg1 = const_cast< ppc::front::IFront * >((smartarg1 ? smartarg1->get() : 0)); + } + } + ecode2 = SWIG_AsVal_unsigned_SS_short(swig_obj[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "IFront_push_msg" "', argument " "2"" of type '" "uint16_t""'"); + } + arg2 = static_cast< uint16_t >(val2); + { + int newmem = 0; + res3 = SWIG_ConvertPtrAndOwn(swig_obj[2], &argp3, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageOptionalHeader_t, 0 , &newmem); + if (!SWIG_IsOK(res3)) { + SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "IFront_push_msg" "', argument " "3"" of type '" "ppc::protocol::MessageOptionalHeader::Ptr const &""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + if (argp3) tempshared3 = *reinterpret_cast< ppc::protocol::MessageOptionalHeader::Ptr * >(argp3); + delete reinterpret_cast< ppc::protocol::MessageOptionalHeader::Ptr * >(argp3); + arg3 = &tempshared3; + } else { + arg3 = (argp3) ? reinterpret_cast< ppc::protocol::MessageOptionalHeader::Ptr * >(argp3) : &tempshared3; + } + } + { + int res; Py_ssize_t size = 0; const void *buf = 0; +#ifndef Py_LIMITED_API + Py_buffer view; + res = PyObject_GetBuffer(swig_obj[3], &view, PyBUF_CONTIG_RO); +#else +#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated" +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#elif defined(_MSC_VER) +#pragma warning(push) +#pragma warning(disable: 4996) +#endif + res = PyObject_AsReadBuffer(swig_obj[3], &buf, &size); +#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) +#pragma GCC diagnostic pop +#elif defined(_MSC_VER) +#pragma warning(pop) +#endif +#endif + if (res < 0) { + PyErr_Clear(); + SWIG_exception_fail(SWIG_ArgError(res), "in method '" "IFront_push_msg" "', argument " "4"" of type '" "(char* payload, uint64_t payloadSize)""'"); + } +#ifndef Py_LIMITED_API + size = view.len; + buf = view.buf; + PyBuffer_Release(&view); +#endif + arg4 = (char *) buf; + arg5 = (uint64_t) (size / sizeof(char)); + } + ecode6 = SWIG_AsVal_int(swig_obj[4], &val6); + if (!SWIG_IsOK(ecode6)) { + SWIG_exception_fail(SWIG_ArgError(ecode6), "in method '" "IFront_push_msg" "', argument " "6"" of type '" "int""'"); + } + arg6 = static_cast< int >(val6); + ecode7 = SWIG_AsVal_long(swig_obj[5], &val7); + if (!SWIG_IsOK(ecode7)) { + SWIG_exception_fail(SWIG_ArgError(ecode7), "in method '" "IFront_push_msg" "', argument " "7"" of type '" "long""'"); + } + arg7 = static_cast< long >(val7); + { + try { + result = (arg1)->push_msg(arg2,(ppc::protocol::MessageOptionalHeader::Ptr const &)*arg3,arg4,arg5,arg6,arg7); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + { + std::shared_ptr< bcos::Error > *smartresult = result ? new std::shared_ptr< bcos::Error >(result) : 0; + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(smartresult), SWIGTYPE_p_std__shared_ptrT_bcos__Error_t, SWIG_POINTER_OWN); + } + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_IFront_pop(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::front::IFront *arg1 = (ppc::front::IFront *) 0 ; + std::string *arg2 = 0 ; + long arg3 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::front::IFront > tempshared1 ; + std::shared_ptr< ppc::front::IFront > *smartarg1 = 0 ; + int res2 = SWIG_OLDOBJ ; + long val3 ; + int ecode3 = 0 ; + PyObject *swig_obj[3] ; + ppc::protocol::Message::Ptr result; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "IFront_pop", 3, 3, swig_obj)) SWIG_fail; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__front__IFront_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IFront_pop" "', argument " "1"" of type '" "ppc::front::IFront *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::front::IFront > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::front::IFront > * >(argp1); + arg1 = const_cast< ppc::front::IFront * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::front::IFront > * >(argp1); + arg1 = const_cast< ppc::front::IFront * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + std::string *ptr = (std::string *)0; + res2 = SWIG_AsPtr_std_string(swig_obj[1], &ptr); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "IFront_pop" "', argument " "2"" of type '" "std::string const &""'"); + } + if (!ptr) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "IFront_pop" "', argument " "2"" of type '" "std::string const &""'"); + } + arg2 = ptr; + } + ecode3 = SWIG_AsVal_long(swig_obj[2], &val3); + if (!SWIG_IsOK(ecode3)) { + SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "IFront_pop" "', argument " "3"" of type '" "long""'"); + } + arg3 = static_cast< long >(val3); + { + try { + result = (arg1)->pop((std::string const &)*arg2,arg3); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + { + std::shared_ptr< ppc::protocol::Message > *smartresult = result ? new std::shared_ptr< ppc::protocol::Message >(result) : 0; + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(smartresult), SWIGTYPE_p_std__shared_ptrT_ppc__protocol__Message_t, SWIG_POINTER_OWN); + } + if (SWIG_IsNewObj(res2)) delete arg2; + return resultobj; +fail: + if (SWIG_IsNewObj(res2)) delete arg2; + return NULL; +} + + +SWIGINTERN PyObject *_wrap_IFront_peek(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::front::IFront *arg1 = (ppc::front::IFront *) 0 ; + std::string *arg2 = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::front::IFront > tempshared1 ; + std::shared_ptr< ppc::front::IFront > *smartarg1 = 0 ; + int res2 = SWIG_OLDOBJ ; + PyObject *swig_obj[2] ; + ppc::protocol::Message::Ptr result; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "IFront_peek", 2, 2, swig_obj)) SWIG_fail; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__front__IFront_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IFront_peek" "', argument " "1"" of type '" "ppc::front::IFront *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::front::IFront > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::front::IFront > * >(argp1); + arg1 = const_cast< ppc::front::IFront * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::front::IFront > * >(argp1); + arg1 = const_cast< ppc::front::IFront * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + std::string *ptr = (std::string *)0; + res2 = SWIG_AsPtr_std_string(swig_obj[1], &ptr); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "IFront_peek" "', argument " "2"" of type '" "std::string const &""'"); + } + if (!ptr) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "IFront_peek" "', argument " "2"" of type '" "std::string const &""'"); + } + arg2 = ptr; + } + { + try { + result = (arg1)->peek((std::string const &)*arg2); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + { + std::shared_ptr< ppc::protocol::Message > *smartresult = result ? new std::shared_ptr< ppc::protocol::Message >(result) : 0; + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(smartresult), SWIGTYPE_p_std__shared_ptrT_ppc__protocol__Message_t, SWIG_POINTER_OWN); + } + if (SWIG_IsNewObj(res2)) delete arg2; + return resultobj; +fail: + if (SWIG_IsNewObj(res2)) delete arg2; + return NULL; +} + + +SWIGINTERN PyObject *_wrap_IFront_asyncGetPeers(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::front::IFront *arg1 = (ppc::front::IFront *) 0 ; + ppc::front::GetPeersInfoHandler::Ptr arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::front::IFront > tempshared1 ; + std::shared_ptr< ppc::front::IFront > *smartarg1 = 0 ; + void *argp2 ; + int res2 = 0 ; + PyObject *swig_obj[2] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "IFront_asyncGetPeers", 2, 2, swig_obj)) SWIG_fail; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__front__IFront_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IFront_asyncGetPeers" "', argument " "1"" of type '" "ppc::front::IFront *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::front::IFront > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::front::IFront > * >(argp1); + arg1 = const_cast< ppc::front::IFront * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::front::IFront > * >(argp1); + arg1 = const_cast< ppc::front::IFront * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + int newmem = 0; + res2 = SWIG_ConvertPtrAndOwn(swig_obj[1], &argp2, SWIGTYPE_p_std__shared_ptrT_ppc__front__GetPeersInfoHandler_t, 0 , &newmem); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "IFront_asyncGetPeers" "', argument " "2"" of type '" "ppc::front::GetPeersInfoHandler::Ptr""'"); + } + if (argp2) arg2 = *(reinterpret_cast< ppc::front::GetPeersInfoHandler::Ptr * >(argp2)); + if (newmem & SWIG_CAST_NEW_MEMORY) delete reinterpret_cast< ppc::front::GetPeersInfoHandler::Ptr * >(argp2); + } + { + try { + (arg1)->asyncGetPeers(arg2); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_IFront_nodeInfo(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::front::IFront *arg1 = (ppc::front::IFront *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::front::IFront > tempshared1 ; + std::shared_ptr< ppc::front::IFront > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + ppc::protocol::INodeInfo::Ptr *result = 0 ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__front__IFront_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IFront_nodeInfo" "', argument " "1"" of type '" "ppc::front::IFront *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::front::IFront > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::front::IFront > * >(argp1); + arg1 = const_cast< ppc::front::IFront * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::front::IFront > * >(argp1); + arg1 = const_cast< ppc::front::IFront * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + result = (ppc::protocol::INodeInfo::Ptr *) &(arg1)->nodeInfo(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + { + std::shared_ptr< ppc::protocol::INodeInfo > *smartresult = *result ? new std::shared_ptr< ppc::protocol::INodeInfo >(*result) : 0; + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(smartresult), SWIGTYPE_p_std__shared_ptrT_ppc__protocol__INodeInfo_t, SWIG_POINTER_OWN); + } + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_IFront_registerTopic(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::front::IFront *arg1 = (ppc::front::IFront *) 0 ; + std::string *arg2 = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::front::IFront > tempshared1 ; + std::shared_ptr< ppc::front::IFront > *smartarg1 = 0 ; + int res2 = SWIG_OLDOBJ ; + PyObject *swig_obj[2] ; + bcos::Error::Ptr result; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "IFront_registerTopic", 2, 2, swig_obj)) SWIG_fail; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__front__IFront_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IFront_registerTopic" "', argument " "1"" of type '" "ppc::front::IFront *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::front::IFront > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::front::IFront > * >(argp1); + arg1 = const_cast< ppc::front::IFront * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::front::IFront > * >(argp1); + arg1 = const_cast< ppc::front::IFront * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + std::string *ptr = (std::string *)0; + res2 = SWIG_AsPtr_std_string(swig_obj[1], &ptr); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "IFront_registerTopic" "', argument " "2"" of type '" "std::string const &""'"); + } + if (!ptr) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "IFront_registerTopic" "', argument " "2"" of type '" "std::string const &""'"); + } + arg2 = ptr; + } + { + try { + result = (arg1)->registerTopic((std::string const &)*arg2); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + { + std::shared_ptr< bcos::Error > *smartresult = result ? new std::shared_ptr< bcos::Error >(result) : 0; + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(smartresult), SWIGTYPE_p_std__shared_ptrT_bcos__Error_t, SWIG_POINTER_OWN); + } + if (SWIG_IsNewObj(res2)) delete arg2; + return resultobj; +fail: + if (SWIG_IsNewObj(res2)) delete arg2; + return NULL; +} + + +SWIGINTERN PyObject *_wrap_IFront_unRegisterTopic(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::front::IFront *arg1 = (ppc::front::IFront *) 0 ; + std::string *arg2 = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::front::IFront > tempshared1 ; + std::shared_ptr< ppc::front::IFront > *smartarg1 = 0 ; + int res2 = SWIG_OLDOBJ ; + PyObject *swig_obj[2] ; + bcos::Error::Ptr result; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "IFront_unRegisterTopic", 2, 2, swig_obj)) SWIG_fail; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__front__IFront_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IFront_unRegisterTopic" "', argument " "1"" of type '" "ppc::front::IFront *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::front::IFront > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::front::IFront > * >(argp1); + arg1 = const_cast< ppc::front::IFront * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::front::IFront > * >(argp1); + arg1 = const_cast< ppc::front::IFront * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + std::string *ptr = (std::string *)0; + res2 = SWIG_AsPtr_std_string(swig_obj[1], &ptr); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "IFront_unRegisterTopic" "', argument " "2"" of type '" "std::string const &""'"); + } + if (!ptr) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "IFront_unRegisterTopic" "', argument " "2"" of type '" "std::string const &""'"); + } + arg2 = ptr; + } + { + try { + result = (arg1)->unRegisterTopic((std::string const &)*arg2); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + { + std::shared_ptr< bcos::Error > *smartresult = result ? new std::shared_ptr< bcos::Error >(result) : 0; + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(smartresult), SWIGTYPE_p_std__shared_ptrT_bcos__Error_t, SWIG_POINTER_OWN); + } + if (SWIG_IsNewObj(res2)) delete arg2; + return resultobj; +fail: + if (SWIG_IsNewObj(res2)) delete arg2; + return NULL; +} + + +SWIGINTERN PyObject *_wrap_IFront_registerComponent(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::front::IFront *arg1 = (ppc::front::IFront *) 0 ; + std::string *arg2 = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::front::IFront > tempshared1 ; + std::shared_ptr< ppc::front::IFront > *smartarg1 = 0 ; + int res2 = SWIG_OLDOBJ ; + PyObject *swig_obj[2] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "IFront_registerComponent", 2, 2, swig_obj)) SWIG_fail; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__front__IFront_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IFront_registerComponent" "', argument " "1"" of type '" "ppc::front::IFront *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::front::IFront > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::front::IFront > * >(argp1); + arg1 = const_cast< ppc::front::IFront * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::front::IFront > * >(argp1); + arg1 = const_cast< ppc::front::IFront * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + std::string *ptr = (std::string *)0; + res2 = SWIG_AsPtr_std_string(swig_obj[1], &ptr); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "IFront_registerComponent" "', argument " "2"" of type '" "std::string const &""'"); + } + if (!ptr) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "IFront_registerComponent" "', argument " "2"" of type '" "std::string const &""'"); + } + arg2 = ptr; + } + { + try { + (arg1)->registerComponent((std::string const &)*arg2); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + if (SWIG_IsNewObj(res2)) delete arg2; + return resultobj; +fail: + if (SWIG_IsNewObj(res2)) delete arg2; + return NULL; +} + + +SWIGINTERN PyObject *_wrap_IFront_unRegisterComponent(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::front::IFront *arg1 = (ppc::front::IFront *) 0 ; + std::string *arg2 = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::front::IFront > tempshared1 ; + std::shared_ptr< ppc::front::IFront > *smartarg1 = 0 ; + int res2 = SWIG_OLDOBJ ; + PyObject *swig_obj[2] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "IFront_unRegisterComponent", 2, 2, swig_obj)) SWIG_fail; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__front__IFront_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IFront_unRegisterComponent" "', argument " "1"" of type '" "ppc::front::IFront *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::front::IFront > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::front::IFront > * >(argp1); + arg1 = const_cast< ppc::front::IFront * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::front::IFront > * >(argp1); + arg1 = const_cast< ppc::front::IFront * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + std::string *ptr = (std::string *)0; + res2 = SWIG_AsPtr_std_string(swig_obj[1], &ptr); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "IFront_unRegisterComponent" "', argument " "2"" of type '" "std::string const &""'"); + } + if (!ptr) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "IFront_unRegisterComponent" "', argument " "2"" of type '" "std::string const &""'"); + } + arg2 = ptr; + } + { + try { + (arg1)->unRegisterComponent((std::string const &)*arg2); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + if (SWIG_IsNewObj(res2)) delete arg2; + return resultobj; +fail: + if (SWIG_IsNewObj(res2)) delete arg2; + return NULL; +} + + +SWIGINTERN PyObject *_wrap_IFront_updateMetaInfo(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::front::IFront *arg1 = (ppc::front::IFront *) 0 ; + std::string *arg2 = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::front::IFront > tempshared1 ; + std::shared_ptr< ppc::front::IFront > *smartarg1 = 0 ; + int res2 = SWIG_OLDOBJ ; + PyObject *swig_obj[2] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "IFront_updateMetaInfo", 2, 2, swig_obj)) SWIG_fail; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__front__IFront_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IFront_updateMetaInfo" "', argument " "1"" of type '" "ppc::front::IFront *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::front::IFront > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::front::IFront > * >(argp1); + arg1 = const_cast< ppc::front::IFront * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::front::IFront > * >(argp1); + arg1 = const_cast< ppc::front::IFront * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + std::string *ptr = (std::string *)0; + res2 = SWIG_AsPtr_std_string(swig_obj[1], &ptr); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "IFront_updateMetaInfo" "', argument " "2"" of type '" "std::string const &""'"); + } + if (!ptr) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "IFront_updateMetaInfo" "', argument " "2"" of type '" "std::string const &""'"); + } + arg2 = ptr; + } + { + try { + (arg1)->updateMetaInfo((std::string const &)*arg2); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + if (SWIG_IsNewObj(res2)) delete arg2; + return resultobj; +fail: + if (SWIG_IsNewObj(res2)) delete arg2; + return NULL; +} + + +SWIGINTERN PyObject *_wrap_IFront_selectNodesByRoutePolicy(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::front::IFront *arg1 = (ppc::front::IFront *) 0 ; + int16_t arg2 ; + ppc::protocol::MessageOptionalHeader::Ptr *arg3 = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::front::IFront > tempshared1 ; + std::shared_ptr< ppc::front::IFront > *smartarg1 = 0 ; + short val2 ; + int ecode2 = 0 ; + void *argp3 ; + int res3 = 0 ; + ppc::protocol::MessageOptionalHeader::Ptr tempshared3 ; + PyObject *swig_obj[3] ; + std::vector< std::string,std::allocator< std::string > > result; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "IFront_selectNodesByRoutePolicy", 3, 3, swig_obj)) SWIG_fail; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__front__IFront_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IFront_selectNodesByRoutePolicy" "', argument " "1"" of type '" "ppc::front::IFront *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::front::IFront > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::front::IFront > * >(argp1); + arg1 = const_cast< ppc::front::IFront * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::front::IFront > * >(argp1); + arg1 = const_cast< ppc::front::IFront * >((smartarg1 ? smartarg1->get() : 0)); + } + } + ecode2 = SWIG_AsVal_short(swig_obj[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "IFront_selectNodesByRoutePolicy" "', argument " "2"" of type '" "int16_t""'"); + } + arg2 = static_cast< int16_t >(val2); + { + int newmem = 0; + res3 = SWIG_ConvertPtrAndOwn(swig_obj[2], &argp3, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageOptionalHeader_t, 0 , &newmem); + if (!SWIG_IsOK(res3)) { + SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "IFront_selectNodesByRoutePolicy" "', argument " "3"" of type '" "ppc::protocol::MessageOptionalHeader::Ptr const &""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + if (argp3) tempshared3 = *reinterpret_cast< ppc::protocol::MessageOptionalHeader::Ptr * >(argp3); + delete reinterpret_cast< ppc::protocol::MessageOptionalHeader::Ptr * >(argp3); + arg3 = &tempshared3; + } else { + arg3 = (argp3) ? reinterpret_cast< ppc::protocol::MessageOptionalHeader::Ptr * >(argp3) : &tempshared3; + } + } + { + try { + result = (arg1)->selectNodesByRoutePolicy(arg2,(ppc::protocol::MessageOptionalHeader::Ptr const &)*arg3); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = swig::from(static_cast< std::vector< std::string,std::allocator< std::string > > >(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_IFront_getNodeDiscovery(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::front::IFront *arg1 = (ppc::front::IFront *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::front::IFront > tempshared1 ; + std::shared_ptr< ppc::front::IFront > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + ppc::front::INodeDiscovery::Ptr result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__front__IFront_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IFront_getNodeDiscovery" "', argument " "1"" of type '" "ppc::front::IFront *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::front::IFront > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::front::IFront > * >(argp1); + arg1 = const_cast< ppc::front::IFront * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::front::IFront > * >(argp1); + arg1 = const_cast< ppc::front::IFront * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + result = (arg1)->getNodeDiscovery(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + { + std::shared_ptr< ppc::front::INodeDiscovery > *smartresult = result ? new std::shared_ptr< ppc::front::INodeDiscovery >(result) : 0; + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(smartresult), SWIGTYPE_p_std__shared_ptrT_ppc__front__INodeDiscovery_t, SWIG_POINTER_OWN); + } + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *IFront_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *obj; + if (!SWIG_Python_UnpackTuple(args, "swigregister", 1, 1, &obj)) return NULL; + SWIG_TypeNewClientData(SWIGTYPE_p_std__shared_ptrT_ppc__front__IFront_t, SWIG_NewClientData(obj)); + return SWIG_Py_Void(); +} + +SWIGINTERN PyObject *_wrap_delete_IFrontBuilder(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::front::IFrontBuilder *arg1 = (ppc::front::IFrontBuilder *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_ppc__front__IFrontBuilder, SWIG_POINTER_DISOWN | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_IFrontBuilder" "', argument " "1"" of type '" "ppc::front::IFrontBuilder *""'"); + } + arg1 = reinterpret_cast< ppc::front::IFrontBuilder * >(argp1); + { + try { + delete arg1; + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_IFrontBuilder_buildClient(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::front::IFrontBuilder *arg1 = (ppc::front::IFrontBuilder *) 0 ; + std::string arg2 ; + std::function< void () > arg3 ; + bool arg4 ; + void *argp1 = 0 ; + int res1 = 0 ; + void *argp3 ; + int res3 = 0 ; + bool val4 ; + int ecode4 = 0 ; + PyObject *swig_obj[4] ; + ppc::front::IFrontClient::Ptr result; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "IFrontBuilder_buildClient", 4, 4, swig_obj)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_ppc__front__IFrontBuilder, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IFrontBuilder_buildClient" "', argument " "1"" of type '" "ppc::front::IFrontBuilder const *""'"); + } + arg1 = reinterpret_cast< ppc::front::IFrontBuilder * >(argp1); + { + std::string *ptr = (std::string *)0; + int res = SWIG_AsPtr_std_string(swig_obj[1], &ptr); + if (!SWIG_IsOK(res) || !ptr) { + SWIG_exception_fail(SWIG_ArgError((ptr ? res : SWIG_TypeError)), "in method '" "IFrontBuilder_buildClient" "', argument " "2"" of type '" "std::string""'"); + } + arg2 = *ptr; + if (SWIG_IsNewObj(res)) delete ptr; + } + { + res3 = SWIG_ConvertPtr(swig_obj[2], &argp3, SWIGTYPE_p_std__functionT_void_fF_t, 0 | 0); + if (!SWIG_IsOK(res3)) { + SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "IFrontBuilder_buildClient" "', argument " "3"" of type '" "std::function< void () >""'"); + } + if (!argp3) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "IFrontBuilder_buildClient" "', argument " "3"" of type '" "std::function< void () >""'"); + } else { + std::function< void () > * temp = reinterpret_cast< std::function< void () > * >(argp3); + arg3 = *temp; + if (SWIG_IsNewObj(res3)) delete temp; + } + } + ecode4 = SWIG_AsVal_bool(swig_obj[3], &val4); + if (!SWIG_IsOK(ecode4)) { + SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "IFrontBuilder_buildClient" "', argument " "4"" of type '" "bool""'"); + } + arg4 = static_cast< bool >(val4); + { + try { + result = ((ppc::front::IFrontBuilder const *)arg1)->buildClient(arg2,arg3,arg4); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + { + std::shared_ptr< ppc::front::IFrontClient > *smartresult = result ? new std::shared_ptr< ppc::front::IFrontClient >(result) : 0; + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(smartresult), SWIGTYPE_p_std__shared_ptrT_ppc__front__IFrontClient_t, SWIG_POINTER_OWN); + } + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *IFrontBuilder_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *obj; + if (!SWIG_Python_UnpackTuple(args, "swigregister", 1, 1, &obj)) return NULL; + SWIG_TypeNewClientData(SWIGTYPE_p_ppc__front__IFrontBuilder, SWIG_NewClientData(obj)); + return SWIG_Py_Void(); +} + +SWIGINTERN PyObject *_wrap_delete_INodeDiscovery(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::front::INodeDiscovery *arg1 = (ppc::front::INodeDiscovery *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::front::INodeDiscovery > tempshared1 ; + std::shared_ptr< ppc::front::INodeDiscovery > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__front__INodeDiscovery_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_INodeDiscovery" "', argument " "1"" of type '" "ppc::front::INodeDiscovery *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::front::INodeDiscovery > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::front::INodeDiscovery > * >(argp1); + arg1 = const_cast< ppc::front::INodeDiscovery * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::front::INodeDiscovery > * >(argp1); + arg1 = const_cast< ppc::front::INodeDiscovery * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + (void)arg1; delete smartarg1; + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_INodeDiscovery_getAliveNodeList(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::front::INodeDiscovery *arg1 = (ppc::front::INodeDiscovery *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::front::INodeDiscovery const > tempshared1 ; + std::shared_ptr< ppc::front::INodeDiscovery const > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + std::vector< std::shared_ptr< ppc::protocol::INodeInfo >,std::allocator< std::shared_ptr< ppc::protocol::INodeInfo > > > result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__front__INodeDiscovery_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "INodeDiscovery_getAliveNodeList" "', argument " "1"" of type '" "ppc::front::INodeDiscovery const *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< const ppc::front::INodeDiscovery > * >(argp1); + delete reinterpret_cast< std::shared_ptr< const ppc::front::INodeDiscovery > * >(argp1); + arg1 = const_cast< ppc::front::INodeDiscovery * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< const ppc::front::INodeDiscovery > * >(argp1); + arg1 = const_cast< ppc::front::INodeDiscovery * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + result = ((ppc::front::INodeDiscovery const *)arg1)->getAliveNodeList(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = swig::from(static_cast< std::vector< std::shared_ptr< ppc::protocol::INodeInfo >,std::allocator< std::shared_ptr< ppc::protocol::INodeInfo > > > >(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *INodeDiscovery_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *obj; + if (!SWIG_Python_UnpackTuple(args, "swigregister", 1, 1, &obj)) return NULL; + SWIG_TypeNewClientData(SWIGTYPE_p_std__shared_ptrT_ppc__front__INodeDiscovery_t, SWIG_NewClientData(obj)); + return SWIG_Py_Void(); +} + +SWIGINTERN PyObject *_wrap_new_TransportBuilder(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::sdk::TransportBuilder *result = 0 ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "new_TransportBuilder", 0, 0, 0)) SWIG_fail; + { + try { + result = (ppc::sdk::TransportBuilder *)new ppc::sdk::TransportBuilder(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_ppc__sdk__TransportBuilder, SWIG_POINTER_NEW | 0 ); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_delete_TransportBuilder(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::sdk::TransportBuilder *arg1 = (ppc::sdk::TransportBuilder *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_ppc__sdk__TransportBuilder, SWIG_POINTER_DISOWN | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_TransportBuilder" "', argument " "1"" of type '" "ppc::sdk::TransportBuilder *""'"); + } + arg1 = reinterpret_cast< ppc::sdk::TransportBuilder * >(argp1); + { + try { + delete arg1; + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_TransportBuilder_buildProTransport(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::sdk::TransportBuilder *arg1 = (ppc::sdk::TransportBuilder *) 0 ; + ppc::front::FrontConfig::Ptr arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + void *argp2 ; + int res2 = 0 ; + PyObject *swig_obj[2] ; + ppc::sdk::Transport::Ptr result; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "TransportBuilder_buildProTransport", 2, 2, swig_obj)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_ppc__sdk__TransportBuilder, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "TransportBuilder_buildProTransport" "', argument " "1"" of type '" "ppc::sdk::TransportBuilder *""'"); + } + arg1 = reinterpret_cast< ppc::sdk::TransportBuilder * >(argp1); + { + int newmem = 0; + res2 = SWIG_ConvertPtrAndOwn(swig_obj[1], &argp2, SWIGTYPE_p_std__shared_ptrT_ppc__front__FrontConfig_t, 0 , &newmem); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "TransportBuilder_buildProTransport" "', argument " "2"" of type '" "ppc::front::FrontConfig::Ptr""'"); + } + if (argp2) arg2 = *(reinterpret_cast< ppc::front::FrontConfig::Ptr * >(argp2)); + if (newmem & SWIG_CAST_NEW_MEMORY) delete reinterpret_cast< ppc::front::FrontConfig::Ptr * >(argp2); + } + { + try { + result = (arg1)->buildProTransport(arg2); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + { + std::shared_ptr< ppc::sdk::Transport > *smartresult = result ? new std::shared_ptr< ppc::sdk::Transport >(result) : 0; + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(smartresult), SWIGTYPE_p_std__shared_ptrT_ppc__sdk__Transport_t, SWIG_POINTER_OWN); + } + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_TransportBuilder_buildConfig(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::sdk::TransportBuilder *arg1 = (ppc::sdk::TransportBuilder *) 0 ; + int arg2 ; + std::string arg3 ; + void *argp1 = 0 ; + int res1 = 0 ; + int val2 ; + int ecode2 = 0 ; + PyObject *swig_obj[3] ; + ppc::front::FrontConfig::Ptr result; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "TransportBuilder_buildConfig", 3, 3, swig_obj)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_ppc__sdk__TransportBuilder, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "TransportBuilder_buildConfig" "', argument " "1"" of type '" "ppc::sdk::TransportBuilder *""'"); + } + arg1 = reinterpret_cast< ppc::sdk::TransportBuilder * >(argp1); + ecode2 = SWIG_AsVal_int(swig_obj[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "TransportBuilder_buildConfig" "', argument " "2"" of type '" "int""'"); + } + arg2 = static_cast< int >(val2); + { + std::string *ptr = (std::string *)0; + int res = SWIG_AsPtr_std_string(swig_obj[2], &ptr); + if (!SWIG_IsOK(res) || !ptr) { + SWIG_exception_fail(SWIG_ArgError((ptr ? res : SWIG_TypeError)), "in method '" "TransportBuilder_buildConfig" "', argument " "3"" of type '" "std::string""'"); + } + arg3 = *ptr; + if (SWIG_IsNewObj(res)) delete ptr; + } + { + try { + result = (arg1)->buildConfig(arg2,arg3); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + { + std::shared_ptr< ppc::front::FrontConfig > *smartresult = result ? new std::shared_ptr< ppc::front::FrontConfig >(result) : 0; + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(smartresult), SWIGTYPE_p_std__shared_ptrT_ppc__front__FrontConfig_t, SWIG_POINTER_OWN); + } + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_TransportBuilder_frontConfigBuilder(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::sdk::TransportBuilder *arg1 = (ppc::sdk::TransportBuilder *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + ppc::front::FrontConfigBuilder::Ptr *result = 0 ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_ppc__sdk__TransportBuilder, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "TransportBuilder_frontConfigBuilder" "', argument " "1"" of type '" "ppc::sdk::TransportBuilder *""'"); + } + arg1 = reinterpret_cast< ppc::sdk::TransportBuilder * >(argp1); + { + try { + result = (ppc::front::FrontConfigBuilder::Ptr *) &(arg1)->frontConfigBuilder(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__shared_ptrT_ppc__front__FrontConfigBuilder_t, 0 | 0 ); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_TransportBuilder_initLog(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::sdk::TransportBuilder *arg1 = (ppc::sdk::TransportBuilder *) 0 ; + std::string *arg2 = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + int res2 = SWIG_OLDOBJ ; + PyObject *swig_obj[2] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "TransportBuilder_initLog", 2, 2, swig_obj)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_ppc__sdk__TransportBuilder, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "TransportBuilder_initLog" "', argument " "1"" of type '" "ppc::sdk::TransportBuilder *""'"); + } + arg1 = reinterpret_cast< ppc::sdk::TransportBuilder * >(argp1); + { + std::string *ptr = (std::string *)0; + res2 = SWIG_AsPtr_std_string(swig_obj[1], &ptr); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "TransportBuilder_initLog" "', argument " "2"" of type '" "std::string const &""'"); + } + if (!ptr) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "TransportBuilder_initLog" "', argument " "2"" of type '" "std::string const &""'"); + } + arg2 = ptr; + } + { + try { + (arg1)->initLog((std::string const &)*arg2); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + if (SWIG_IsNewObj(res2)) delete arg2; + return resultobj; +fail: + if (SWIG_IsNewObj(res2)) delete arg2; + return NULL; +} + + +SWIGINTERN PyObject *TransportBuilder_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *obj; + if (!SWIG_Python_UnpackTuple(args, "swigregister", 1, 1, &obj)) return NULL; + SWIG_TypeNewClientData(SWIGTYPE_p_ppc__sdk__TransportBuilder, SWIG_NewClientData(obj)); + return SWIG_Py_Void(); +} + +SWIGINTERN PyObject *TransportBuilder_swiginit(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + return SWIG_Python_InitShadowInstance(args); +} + +SWIGINTERN PyObject *_wrap_new_Transport(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::front::FrontConfig::Ptr arg1 ; + void *argp1 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + ppc::sdk::Transport *result = 0 ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__front__FrontConfig_t, 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "new_Transport" "', argument " "1"" of type '" "ppc::front::FrontConfig::Ptr""'"); + } + if (argp1) arg1 = *(reinterpret_cast< ppc::front::FrontConfig::Ptr * >(argp1)); + if (newmem & SWIG_CAST_NEW_MEMORY) delete reinterpret_cast< ppc::front::FrontConfig::Ptr * >(argp1); + } + { + try { + result = (ppc::sdk::Transport *)new ppc::sdk::Transport(arg1); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + { + std::shared_ptr< ppc::sdk::Transport > *smartresult = result ? new std::shared_ptr< ppc::sdk::Transport >(result SWIG_NO_NULL_DELETER_SWIG_POINTER_NEW) : 0; + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(smartresult), SWIGTYPE_p_std__shared_ptrT_ppc__sdk__Transport_t, SWIG_POINTER_NEW | SWIG_POINTER_OWN); + } + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_delete_Transport(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::sdk::Transport *arg1 = (ppc::sdk::Transport *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::sdk::Transport > tempshared1 ; + std::shared_ptr< ppc::sdk::Transport > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__sdk__Transport_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_Transport" "', argument " "1"" of type '" "ppc::sdk::Transport *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::sdk::Transport > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::sdk::Transport > * >(argp1); + arg1 = const_cast< ppc::sdk::Transport * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::sdk::Transport > * >(argp1); + arg1 = const_cast< ppc::sdk::Transport * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + (void)arg1; delete smartarg1; + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_Transport_start(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::sdk::Transport *arg1 = (ppc::sdk::Transport *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::sdk::Transport > tempshared1 ; + std::shared_ptr< ppc::sdk::Transport > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__sdk__Transport_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Transport_start" "', argument " "1"" of type '" "ppc::sdk::Transport *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::sdk::Transport > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::sdk::Transport > * >(argp1); + arg1 = const_cast< ppc::sdk::Transport * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::sdk::Transport > * >(argp1); + arg1 = const_cast< ppc::sdk::Transport * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + (arg1)->start(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_Transport_stop(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::sdk::Transport *arg1 = (ppc::sdk::Transport *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::sdk::Transport > tempshared1 ; + std::shared_ptr< ppc::sdk::Transport > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__sdk__Transport_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Transport_stop" "', argument " "1"" of type '" "ppc::sdk::Transport *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::sdk::Transport > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::sdk::Transport > * >(argp1); + arg1 = const_cast< ppc::sdk::Transport * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::sdk::Transport > * >(argp1); + arg1 = const_cast< ppc::sdk::Transport * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + (arg1)->stop(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_Transport_getFront(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::sdk::Transport *arg1 = (ppc::sdk::Transport *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::sdk::Transport const > tempshared1 ; + std::shared_ptr< ppc::sdk::Transport const > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + ppc::front::IFront::Ptr *result = 0 ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__sdk__Transport_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Transport_getFront" "', argument " "1"" of type '" "ppc::sdk::Transport const *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< const ppc::sdk::Transport > * >(argp1); + delete reinterpret_cast< std::shared_ptr< const ppc::sdk::Transport > * >(argp1); + arg1 = const_cast< ppc::sdk::Transport * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< const ppc::sdk::Transport > * >(argp1); + arg1 = const_cast< ppc::sdk::Transport * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + result = (ppc::front::IFront::Ptr *) &((ppc::sdk::Transport const *)arg1)->getFront(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + { + std::shared_ptr< ppc::front::IFront > *smartresult = *result ? new std::shared_ptr< ppc::front::IFront >(*result) : 0; + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(smartresult), SWIGTYPE_p_std__shared_ptrT_ppc__front__IFront_t, SWIG_POINTER_OWN); + } + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_Transport_gateway(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::sdk::Transport *arg1 = (ppc::sdk::Transport *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::sdk::Transport const > tempshared1 ; + std::shared_ptr< ppc::sdk::Transport const > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + ppc::gateway::IGateway::Ptr *result = 0 ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__sdk__Transport_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Transport_gateway" "', argument " "1"" of type '" "ppc::sdk::Transport const *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< const ppc::sdk::Transport > * >(argp1); + delete reinterpret_cast< std::shared_ptr< const ppc::sdk::Transport > * >(argp1); + arg1 = const_cast< ppc::sdk::Transport * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< const ppc::sdk::Transport > * >(argp1); + arg1 = const_cast< ppc::sdk::Transport * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + result = (ppc::gateway::IGateway::Ptr *) &((ppc::sdk::Transport const *)arg1)->gateway(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_ppc__gateway__IGateway__Ptr, 0 | 0 ); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_Transport_msgPayloadBuilder(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::sdk::Transport *arg1 = (ppc::sdk::Transport *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::sdk::Transport const > tempshared1 ; + std::shared_ptr< ppc::sdk::Transport const > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + ppc::protocol::MessagePayloadBuilder::Ptr *result = 0 ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__sdk__Transport_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Transport_msgPayloadBuilder" "', argument " "1"" of type '" "ppc::sdk::Transport const *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< const ppc::sdk::Transport > * >(argp1); + delete reinterpret_cast< std::shared_ptr< const ppc::sdk::Transport > * >(argp1); + arg1 = const_cast< ppc::sdk::Transport * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< const ppc::sdk::Transport > * >(argp1); + arg1 = const_cast< ppc::sdk::Transport * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + result = (ppc::protocol::MessagePayloadBuilder::Ptr *) &((ppc::sdk::Transport const *)arg1)->msgPayloadBuilder(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + { + std::shared_ptr< ppc::protocol::MessagePayloadBuilder > *smartresult = *result ? new std::shared_ptr< ppc::protocol::MessagePayloadBuilder >(*result) : 0; + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(smartresult), SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessagePayloadBuilder_t, SWIG_POINTER_OWN); + } + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_Transport_msgBuilder(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::sdk::Transport *arg1 = (ppc::sdk::Transport *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::sdk::Transport const > tempshared1 ; + std::shared_ptr< ppc::sdk::Transport const > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + ppc::protocol::MessageBuilder::Ptr *result = 0 ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__sdk__Transport_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Transport_msgBuilder" "', argument " "1"" of type '" "ppc::sdk::Transport const *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< const ppc::sdk::Transport > * >(argp1); + delete reinterpret_cast< std::shared_ptr< const ppc::sdk::Transport > * >(argp1); + arg1 = const_cast< ppc::sdk::Transport * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< const ppc::sdk::Transport > * >(argp1); + arg1 = const_cast< ppc::sdk::Transport * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + result = (ppc::protocol::MessageBuilder::Ptr *) &((ppc::sdk::Transport const *)arg1)->msgBuilder(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + { + std::shared_ptr< ppc::protocol::MessageBuilder > *smartresult = *result ? new std::shared_ptr< ppc::protocol::MessageBuilder >(*result) : 0; + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(smartresult), SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageBuilder_t, SWIG_POINTER_OWN); + } + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_Transport_msgHeaderBuilder(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::sdk::Transport *arg1 = (ppc::sdk::Transport *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::sdk::Transport const > tempshared1 ; + std::shared_ptr< ppc::sdk::Transport const > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + ppc::protocol::MessageHeaderBuilder::Ptr *result = 0 ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__sdk__Transport_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Transport_msgHeaderBuilder" "', argument " "1"" of type '" "ppc::sdk::Transport const *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< const ppc::sdk::Transport > * >(argp1); + delete reinterpret_cast< std::shared_ptr< const ppc::sdk::Transport > * >(argp1); + arg1 = const_cast< ppc::sdk::Transport * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< const ppc::sdk::Transport > * >(argp1); + arg1 = const_cast< ppc::sdk::Transport * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + result = (ppc::protocol::MessageHeaderBuilder::Ptr *) &((ppc::sdk::Transport const *)arg1)->msgHeaderBuilder(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + { + std::shared_ptr< ppc::protocol::MessageHeaderBuilder > *smartresult = *result ? new std::shared_ptr< ppc::protocol::MessageHeaderBuilder >(*result) : 0; + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(smartresult), SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageHeaderBuilder_t, SWIG_POINTER_OWN); + } + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_Transport_routeInfoBuilder(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::sdk::Transport *arg1 = (ppc::sdk::Transport *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::sdk::Transport const > tempshared1 ; + std::shared_ptr< ppc::sdk::Transport const > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + ppc::protocol::MessageOptionalHeaderBuilder::Ptr *result = 0 ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__sdk__Transport_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Transport_routeInfoBuilder" "', argument " "1"" of type '" "ppc::sdk::Transport const *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< const ppc::sdk::Transport > * >(argp1); + delete reinterpret_cast< std::shared_ptr< const ppc::sdk::Transport > * >(argp1); + arg1 = const_cast< ppc::sdk::Transport * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< const ppc::sdk::Transport > * >(argp1); + arg1 = const_cast< ppc::sdk::Transport * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + result = (ppc::protocol::MessageOptionalHeaderBuilder::Ptr *) &((ppc::sdk::Transport const *)arg1)->routeInfoBuilder(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + { + std::shared_ptr< ppc::protocol::MessageOptionalHeaderBuilder > *smartresult = *result ? new std::shared_ptr< ppc::protocol::MessageOptionalHeaderBuilder >(*result) : 0; + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(smartresult), SWIGTYPE_p_std__shared_ptrT_ppc__protocol__MessageOptionalHeaderBuilder_t, SWIG_POINTER_OWN); + } + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_Transport_getConfig(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::sdk::Transport *arg1 = (ppc::sdk::Transport *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::sdk::Transport const > tempshared1 ; + std::shared_ptr< ppc::sdk::Transport const > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + ppc::front::FrontConfig::Ptr *result = 0 ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__sdk__Transport_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Transport_getConfig" "', argument " "1"" of type '" "ppc::sdk::Transport const *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< const ppc::sdk::Transport > * >(argp1); + delete reinterpret_cast< std::shared_ptr< const ppc::sdk::Transport > * >(argp1); + arg1 = const_cast< ppc::sdk::Transport * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< const ppc::sdk::Transport > * >(argp1); + arg1 = const_cast< ppc::sdk::Transport * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + result = (ppc::front::FrontConfig::Ptr *) &((ppc::sdk::Transport const *)arg1)->getConfig(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + { + std::shared_ptr< ppc::front::FrontConfig > *smartresult = *result ? new std::shared_ptr< ppc::front::FrontConfig >(*result) : 0; + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(smartresult), SWIGTYPE_p_std__shared_ptrT_ppc__front__FrontConfig_t, SWIG_POINTER_OWN); + } + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *Transport_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *obj; + if (!SWIG_Python_UnpackTuple(args, "swigregister", 1, 1, &obj)) return NULL; + SWIG_TypeNewClientData(SWIGTYPE_p_std__shared_ptrT_ppc__sdk__Transport_t, SWIG_NewClientData(obj)); + return SWIG_Py_Void(); +} + +SWIGINTERN PyObject *Transport_swiginit(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + return SWIG_Python_InitShadowInstance(args); +} + +SWIGINTERN PyObject *_wrap_delete_INodeInfo(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::INodeInfo *arg1 = (ppc::protocol::INodeInfo *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::INodeInfo > tempshared1 ; + std::shared_ptr< ppc::protocol::INodeInfo > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__INodeInfo_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_INodeInfo" "', argument " "1"" of type '" "ppc::protocol::INodeInfo *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::protocol::INodeInfo > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::protocol::INodeInfo > * >(argp1); + arg1 = const_cast< ppc::protocol::INodeInfo * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::protocol::INodeInfo > * >(argp1); + arg1 = const_cast< ppc::protocol::INodeInfo * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + (void)arg1; delete smartarg1; + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_INodeInfo_endPoint(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::INodeInfo *arg1 = (ppc::protocol::INodeInfo *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::INodeInfo const > tempshared1 ; + std::shared_ptr< ppc::protocol::INodeInfo const > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + std::string *result = 0 ; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__INodeInfo_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "INodeInfo_endPoint" "', argument " "1"" of type '" "ppc::protocol::INodeInfo const *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< const ppc::protocol::INodeInfo > * >(argp1); + delete reinterpret_cast< std::shared_ptr< const ppc::protocol::INodeInfo > * >(argp1); + arg1 = const_cast< ppc::protocol::INodeInfo * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< const ppc::protocol::INodeInfo > * >(argp1); + arg1 = const_cast< ppc::protocol::INodeInfo * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + result = (std::string *) &((ppc::protocol::INodeInfo const *)arg1)->endPoint(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_From_std_string(static_cast< std::string >(*result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_INodeInfo_nodeID(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::INodeInfo *arg1 = (ppc::protocol::INodeInfo *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::INodeInfo const > tempshared1 ; + std::shared_ptr< ppc::protocol::INodeInfo const > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + bcos::bytesConstRef result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__INodeInfo_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "INodeInfo_nodeID" "', argument " "1"" of type '" "ppc::protocol::INodeInfo const *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< const ppc::protocol::INodeInfo > * >(argp1); + delete reinterpret_cast< std::shared_ptr< const ppc::protocol::INodeInfo > * >(argp1); + arg1 = const_cast< ppc::protocol::INodeInfo * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< const ppc::protocol::INodeInfo > * >(argp1); + arg1 = const_cast< ppc::protocol::INodeInfo * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + result = ((ppc::protocol::INodeInfo const *)arg1)->nodeID(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_NewPointerObj((new bcos::bytesConstRef(result)), SWIGTYPE_p_bcos__bytesConstRef, SWIG_POINTER_OWN | 0 ); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_INodeInfo_setNodeID(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::INodeInfo *arg1 = (ppc::protocol::INodeInfo *) 0 ; + bcos::bytesConstRef arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::INodeInfo > tempshared1 ; + std::shared_ptr< ppc::protocol::INodeInfo > *smartarg1 = 0 ; + void *argp2 ; + int res2 = 0 ; + PyObject *swig_obj[2] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "INodeInfo_setNodeID", 2, 2, swig_obj)) SWIG_fail; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__INodeInfo_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "INodeInfo_setNodeID" "', argument " "1"" of type '" "ppc::protocol::INodeInfo *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::protocol::INodeInfo > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::protocol::INodeInfo > * >(argp1); + arg1 = const_cast< ppc::protocol::INodeInfo * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::protocol::INodeInfo > * >(argp1); + arg1 = const_cast< ppc::protocol::INodeInfo * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + res2 = SWIG_ConvertPtr(swig_obj[1], &argp2, SWIGTYPE_p_bcos__bytesConstRef, 0 | 0); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "INodeInfo_setNodeID" "', argument " "2"" of type '" "bcos::bytesConstRef""'"); + } + if (!argp2) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "INodeInfo_setNodeID" "', argument " "2"" of type '" "bcos::bytesConstRef""'"); + } else { + bcos::bytesConstRef * temp = reinterpret_cast< bcos::bytesConstRef * >(argp2); + arg2 = *temp; + if (SWIG_IsNewObj(res2)) delete temp; + } + } + { + try { + (arg1)->setNodeID(arg2); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_INodeInfo_setEndPoint(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::INodeInfo *arg1 = (ppc::protocol::INodeInfo *) 0 ; + std::string *arg2 = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::INodeInfo > tempshared1 ; + std::shared_ptr< ppc::protocol::INodeInfo > *smartarg1 = 0 ; + int res2 = SWIG_OLDOBJ ; + PyObject *swig_obj[2] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "INodeInfo_setEndPoint", 2, 2, swig_obj)) SWIG_fail; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__INodeInfo_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "INodeInfo_setEndPoint" "', argument " "1"" of type '" "ppc::protocol::INodeInfo *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::protocol::INodeInfo > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::protocol::INodeInfo > * >(argp1); + arg1 = const_cast< ppc::protocol::INodeInfo * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::protocol::INodeInfo > * >(argp1); + arg1 = const_cast< ppc::protocol::INodeInfo * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + std::string *ptr = (std::string *)0; + res2 = SWIG_AsPtr_std_string(swig_obj[1], &ptr); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "INodeInfo_setEndPoint" "', argument " "2"" of type '" "std::string const &""'"); + } + if (!ptr) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "INodeInfo_setEndPoint" "', argument " "2"" of type '" "std::string const &""'"); + } + arg2 = ptr; + } + { + try { + (arg1)->setEndPoint((std::string const &)*arg2); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + if (SWIG_IsNewObj(res2)) delete arg2; + return resultobj; +fail: + if (SWIG_IsNewObj(res2)) delete arg2; + return NULL; +} + + +SWIGINTERN PyObject *_wrap_INodeInfo_addComponent(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::INodeInfo *arg1 = (ppc::protocol::INodeInfo *) 0 ; + std::string *arg2 = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::INodeInfo > tempshared1 ; + std::shared_ptr< ppc::protocol::INodeInfo > *smartarg1 = 0 ; + int res2 = SWIG_OLDOBJ ; + PyObject *swig_obj[2] ; + bool result; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "INodeInfo_addComponent", 2, 2, swig_obj)) SWIG_fail; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__INodeInfo_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "INodeInfo_addComponent" "', argument " "1"" of type '" "ppc::protocol::INodeInfo *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::protocol::INodeInfo > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::protocol::INodeInfo > * >(argp1); + arg1 = const_cast< ppc::protocol::INodeInfo * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::protocol::INodeInfo > * >(argp1); + arg1 = const_cast< ppc::protocol::INodeInfo * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + std::string *ptr = (std::string *)0; + res2 = SWIG_AsPtr_std_string(swig_obj[1], &ptr); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "INodeInfo_addComponent" "', argument " "2"" of type '" "std::string const &""'"); + } + if (!ptr) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "INodeInfo_addComponent" "', argument " "2"" of type '" "std::string const &""'"); + } + arg2 = ptr; + } + { + try { + result = (bool)(arg1)->addComponent((std::string const &)*arg2); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_From_bool(static_cast< bool >(result)); + if (SWIG_IsNewObj(res2)) delete arg2; + return resultobj; +fail: + if (SWIG_IsNewObj(res2)) delete arg2; + return NULL; +} + + +SWIGINTERN PyObject *_wrap_INodeInfo_eraseComponent(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::INodeInfo *arg1 = (ppc::protocol::INodeInfo *) 0 ; + std::string *arg2 = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::INodeInfo > tempshared1 ; + std::shared_ptr< ppc::protocol::INodeInfo > *smartarg1 = 0 ; + int res2 = SWIG_OLDOBJ ; + PyObject *swig_obj[2] ; + bool result; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "INodeInfo_eraseComponent", 2, 2, swig_obj)) SWIG_fail; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__INodeInfo_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "INodeInfo_eraseComponent" "', argument " "1"" of type '" "ppc::protocol::INodeInfo *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::protocol::INodeInfo > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::protocol::INodeInfo > * >(argp1); + arg1 = const_cast< ppc::protocol::INodeInfo * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::protocol::INodeInfo > * >(argp1); + arg1 = const_cast< ppc::protocol::INodeInfo * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + std::string *ptr = (std::string *)0; + res2 = SWIG_AsPtr_std_string(swig_obj[1], &ptr); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "INodeInfo_eraseComponent" "', argument " "2"" of type '" "std::string const &""'"); + } + if (!ptr) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "INodeInfo_eraseComponent" "', argument " "2"" of type '" "std::string const &""'"); + } + arg2 = ptr; + } + { + try { + result = (bool)(arg1)->eraseComponent((std::string const &)*arg2); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_From_bool(static_cast< bool >(result)); + if (SWIG_IsNewObj(res2)) delete arg2; + return resultobj; +fail: + if (SWIG_IsNewObj(res2)) delete arg2; + return NULL; +} + + +SWIGINTERN PyObject *_wrap_INodeInfo_componentExist(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::INodeInfo *arg1 = (ppc::protocol::INodeInfo *) 0 ; + std::string *arg2 = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::INodeInfo const > tempshared1 ; + std::shared_ptr< ppc::protocol::INodeInfo const > *smartarg1 = 0 ; + int res2 = SWIG_OLDOBJ ; + PyObject *swig_obj[2] ; + bool result; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "INodeInfo_componentExist", 2, 2, swig_obj)) SWIG_fail; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__INodeInfo_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "INodeInfo_componentExist" "', argument " "1"" of type '" "ppc::protocol::INodeInfo const *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< const ppc::protocol::INodeInfo > * >(argp1); + delete reinterpret_cast< std::shared_ptr< const ppc::protocol::INodeInfo > * >(argp1); + arg1 = const_cast< ppc::protocol::INodeInfo * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< const ppc::protocol::INodeInfo > * >(argp1); + arg1 = const_cast< ppc::protocol::INodeInfo * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + std::string *ptr = (std::string *)0; + res2 = SWIG_AsPtr_std_string(swig_obj[1], &ptr); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "INodeInfo_componentExist" "', argument " "2"" of type '" "std::string const &""'"); + } + if (!ptr) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "INodeInfo_componentExist" "', argument " "2"" of type '" "std::string const &""'"); + } + arg2 = ptr; + } + { + try { + result = (bool)((ppc::protocol::INodeInfo const *)arg1)->componentExist((std::string const &)*arg2); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_From_bool(static_cast< bool >(result)); + if (SWIG_IsNewObj(res2)) delete arg2; + return resultobj; +fail: + if (SWIG_IsNewObj(res2)) delete arg2; + return NULL; +} + + +SWIGINTERN PyObject *_wrap_INodeInfo_copiedComponents(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::INodeInfo *arg1 = (ppc::protocol::INodeInfo *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::INodeInfo const > tempshared1 ; + std::shared_ptr< ppc::protocol::INodeInfo const > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + std::vector< std::string,std::allocator< std::string > > result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__INodeInfo_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "INodeInfo_copiedComponents" "', argument " "1"" of type '" "ppc::protocol::INodeInfo const *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< const ppc::protocol::INodeInfo > * >(argp1); + delete reinterpret_cast< std::shared_ptr< const ppc::protocol::INodeInfo > * >(argp1); + arg1 = const_cast< ppc::protocol::INodeInfo * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< const ppc::protocol::INodeInfo > * >(argp1); + arg1 = const_cast< ppc::protocol::INodeInfo * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + result = ((ppc::protocol::INodeInfo const *)arg1)->copiedComponents(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = swig::from(static_cast< std::vector< std::string,std::allocator< std::string > > >(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_INodeInfo_meta(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::INodeInfo *arg1 = (ppc::protocol::INodeInfo *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::INodeInfo const > tempshared1 ; + std::shared_ptr< ppc::protocol::INodeInfo const > *smartarg1 = 0 ; + PyObject *swig_obj[1] ; + std::string result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__INodeInfo_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "INodeInfo_meta" "', argument " "1"" of type '" "ppc::protocol::INodeInfo const *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< const ppc::protocol::INodeInfo > * >(argp1); + delete reinterpret_cast< std::shared_ptr< const ppc::protocol::INodeInfo > * >(argp1); + arg1 = const_cast< ppc::protocol::INodeInfo * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< const ppc::protocol::INodeInfo > * >(argp1); + arg1 = const_cast< ppc::protocol::INodeInfo * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + try { + result = ((ppc::protocol::INodeInfo const *)arg1)->meta(); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_From_std_string(static_cast< std::string >(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_INodeInfo_setMeta(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::INodeInfo *arg1 = (ppc::protocol::INodeInfo *) 0 ; + std::string *arg2 = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + std::shared_ptr< ppc::protocol::INodeInfo > tempshared1 ; + std::shared_ptr< ppc::protocol::INodeInfo > *smartarg1 = 0 ; + int res2 = SWIG_OLDOBJ ; + PyObject *swig_obj[2] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "INodeInfo_setMeta", 2, 2, swig_obj)) SWIG_fail; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__INodeInfo_t, 0 | 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "INodeInfo_setMeta" "', argument " "1"" of type '" "ppc::protocol::INodeInfo *""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + tempshared1 = *reinterpret_cast< std::shared_ptr< ppc::protocol::INodeInfo > * >(argp1); + delete reinterpret_cast< std::shared_ptr< ppc::protocol::INodeInfo > * >(argp1); + arg1 = const_cast< ppc::protocol::INodeInfo * >(tempshared1.get()); + } else { + smartarg1 = reinterpret_cast< std::shared_ptr< ppc::protocol::INodeInfo > * >(argp1); + arg1 = const_cast< ppc::protocol::INodeInfo * >((smartarg1 ? smartarg1->get() : 0)); + } + } + { + std::string *ptr = (std::string *)0; + res2 = SWIG_AsPtr_std_string(swig_obj[1], &ptr); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "INodeInfo_setMeta" "', argument " "2"" of type '" "std::string const &""'"); + } + if (!ptr) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "INodeInfo_setMeta" "', argument " "2"" of type '" "std::string const &""'"); + } + arg2 = ptr; + } + { + try { + (arg1)->setMeta((std::string const &)*arg2); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_Py_Void(); + if (SWIG_IsNewObj(res2)) delete arg2; + return resultobj; +fail: + if (SWIG_IsNewObj(res2)) delete arg2; + return NULL; +} + + +SWIGINTERN PyObject *INodeInfo_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *obj; + if (!SWIG_Python_UnpackTuple(args, "swigregister", 1, 1, &obj)) return NULL; + SWIG_TypeNewClientData(SWIGTYPE_p_std__shared_ptrT_ppc__protocol__INodeInfo_t, SWIG_NewClientData(obj)); + return SWIG_Py_Void(); +} + +SWIGINTERN PyObject *_wrap_printNodeInfo(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + ppc::protocol::INodeInfo::Ptr *arg1 = 0 ; + void *argp1 ; + int res1 = 0 ; + ppc::protocol::INodeInfo::Ptr tempshared1 ; + PyObject *swig_obj[1] ; + std::string result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + { + int newmem = 0; + res1 = SWIG_ConvertPtrAndOwn(swig_obj[0], &argp1, SWIGTYPE_p_std__shared_ptrT_ppc__protocol__INodeInfo_t, 0 , &newmem); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "printNodeInfo" "', argument " "1"" of type '" "ppc::protocol::INodeInfo::Ptr const &""'"); + } + if (newmem & SWIG_CAST_NEW_MEMORY) { + if (argp1) tempshared1 = *reinterpret_cast< ppc::protocol::INodeInfo::Ptr * >(argp1); + delete reinterpret_cast< ppc::protocol::INodeInfo::Ptr * >(argp1); + arg1 = &tempshared1; + } else { + arg1 = (argp1) ? reinterpret_cast< ppc::protocol::INodeInfo::Ptr * >(argp1) : &tempshared1; + } + } + { + try { + result = ppc::protocol::printNodeInfo((std::shared_ptr< ppc::protocol::INodeInfo > const &)*arg1); + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } + } + resultobj = SWIG_From_std_string(static_cast< std::string >(result)); + return resultobj; +fail: + return NULL; +} + + +static PyMethodDef SwigMethods[] = { + { "delete_SwigPyIterator", _wrap_delete_SwigPyIterator, METH_O, NULL}, + { "SwigPyIterator_value", _wrap_SwigPyIterator_value, METH_O, NULL}, + { "SwigPyIterator_incr", _wrap_SwigPyIterator_incr, METH_VARARGS, NULL}, + { "SwigPyIterator_decr", _wrap_SwigPyIterator_decr, METH_VARARGS, NULL}, + { "SwigPyIterator_distance", _wrap_SwigPyIterator_distance, METH_VARARGS, NULL}, + { "SwigPyIterator_equal", _wrap_SwigPyIterator_equal, METH_VARARGS, NULL}, + { "SwigPyIterator_copy", _wrap_SwigPyIterator_copy, METH_O, NULL}, + { "SwigPyIterator_next", _wrap_SwigPyIterator_next, METH_O, NULL}, + { "SwigPyIterator___next__", _wrap_SwigPyIterator___next__, METH_O, NULL}, + { "SwigPyIterator_previous", _wrap_SwigPyIterator_previous, METH_O, NULL}, + { "SwigPyIterator_advance", _wrap_SwigPyIterator_advance, METH_VARARGS, NULL}, + { "SwigPyIterator___eq__", _wrap_SwigPyIterator___eq__, METH_VARARGS, NULL}, + { "SwigPyIterator___ne__", _wrap_SwigPyIterator___ne__, METH_VARARGS, NULL}, + { "SwigPyIterator___iadd__", _wrap_SwigPyIterator___iadd__, METH_VARARGS, NULL}, + { "SwigPyIterator___isub__", _wrap_SwigPyIterator___isub__, METH_VARARGS, NULL}, + { "SwigPyIterator___add__", _wrap_SwigPyIterator___add__, METH_VARARGS, NULL}, + { "SwigPyIterator___sub__", _wrap_SwigPyIterator___sub__, METH_VARARGS, NULL}, + { "SwigPyIterator_swigregister", SwigPyIterator_swigregister, METH_O, NULL}, + { "new_SharedBcosError", _wrap_new_SharedBcosError, METH_NOARGS, NULL}, + { "delete_SharedBcosError", _wrap_delete_SharedBcosError, METH_O, NULL}, + { "SharedBcosError_swigregister", SharedBcosError_swigregister, METH_O, NULL}, + { "SharedBcosError_swiginit", SharedBcosError_swiginit, METH_VARARGS, NULL}, + { "new_SharedFrontConfig", _wrap_new_SharedFrontConfig, METH_NOARGS, NULL}, + { "delete_SharedFrontConfig", _wrap_delete_SharedFrontConfig, METH_O, NULL}, + { "SharedFrontConfig_swigregister", SharedFrontConfig_swigregister, METH_O, NULL}, + { "SharedFrontConfig_swiginit", SharedFrontConfig_swiginit, METH_VARARGS, NULL}, + { "new_SharedGrpcConfig", _wrap_new_SharedGrpcConfig, METH_NOARGS, NULL}, + { "delete_SharedGrpcConfig", _wrap_delete_SharedGrpcConfig, METH_O, NULL}, + { "SharedGrpcConfig_swigregister", SharedGrpcConfig_swigregister, METH_O, NULL}, + { "SharedGrpcConfig_swiginit", SharedGrpcConfig_swiginit, METH_VARARGS, NULL}, + { "new_SharedFront", _wrap_new_SharedFront, METH_NOARGS, NULL}, + { "delete_SharedFront", _wrap_delete_SharedFront, METH_O, NULL}, + { "SharedFront_swigregister", SharedFront_swigregister, METH_O, NULL}, + { "SharedFront_swiginit", SharedFront_swiginit, METH_VARARGS, NULL}, + { "new_SharedNodeDiscovery", _wrap_new_SharedNodeDiscovery, METH_NOARGS, NULL}, + { "delete_SharedNodeDiscovery", _wrap_delete_SharedNodeDiscovery, METH_O, NULL}, + { "SharedNodeDiscovery_swigregister", SharedNodeDiscovery_swigregister, METH_O, NULL}, + { "SharedNodeDiscovery_swiginit", SharedNodeDiscovery_swiginit, METH_VARARGS, NULL}, + { "new_SharedNodeInfo", _wrap_new_SharedNodeInfo, METH_NOARGS, NULL}, + { "delete_SharedNodeInfo", _wrap_delete_SharedNodeInfo, METH_O, NULL}, + { "SharedNodeInfo_swigregister", SharedNodeInfo_swigregister, METH_O, NULL}, + { "SharedNodeInfo_swiginit", SharedNodeInfo_swiginit, METH_VARARGS, NULL}, + { "new_SharedFrontClient", _wrap_new_SharedFrontClient, METH_NOARGS, NULL}, + { "delete_SharedFrontClient", _wrap_delete_SharedFrontClient, METH_O, NULL}, + { "SharedFrontClient_swigregister", SharedFrontClient_swigregister, METH_O, NULL}, + { "SharedFrontClient_swiginit", SharedFrontClient_swiginit, METH_VARARGS, NULL}, + { "new_SharedErrorCallback", _wrap_new_SharedErrorCallback, METH_NOARGS, NULL}, + { "delete_SharedErrorCallback", _wrap_delete_SharedErrorCallback, METH_O, NULL}, + { "SharedErrorCallback_swigregister", SharedErrorCallback_swigregister, METH_O, NULL}, + { "SharedErrorCallback_swiginit", SharedErrorCallback_swiginit, METH_VARARGS, NULL}, + { "new_SharedMessageDispatcherHandler", _wrap_new_SharedMessageDispatcherHandler, METH_NOARGS, NULL}, + { "delete_SharedMessageDispatcherHandler", _wrap_delete_SharedMessageDispatcherHandler, METH_O, NULL}, + { "SharedMessageDispatcherHandler_swigregister", SharedMessageDispatcherHandler_swigregister, METH_O, NULL}, + { "SharedMessageDispatcherHandler_swiginit", SharedMessageDispatcherHandler_swiginit, METH_VARARGS, NULL}, + { "new_SharedIMessageHandler", _wrap_new_SharedIMessageHandler, METH_NOARGS, NULL}, + { "delete_SharedIMessageHandler", _wrap_delete_SharedIMessageHandler, METH_O, NULL}, + { "SharedIMessageHandler_swigregister", SharedIMessageHandler_swigregister, METH_O, NULL}, + { "SharedIMessageHandler_swiginit", SharedIMessageHandler_swiginit, METH_VARARGS, NULL}, + { "new_SharedGetPeersInfoHandler", _wrap_new_SharedGetPeersInfoHandler, METH_NOARGS, NULL}, + { "delete_SharedGetPeersInfoHandler", _wrap_delete_SharedGetPeersInfoHandler, METH_O, NULL}, + { "SharedGetPeersInfoHandler_swigregister", SharedGetPeersInfoHandler_swigregister, METH_O, NULL}, + { "SharedGetPeersInfoHandler_swiginit", SharedGetPeersInfoHandler_swiginit, METH_VARARGS, NULL}, + { "new_SharedGateway", _wrap_new_SharedGateway, METH_NOARGS, NULL}, + { "delete_SharedGateway", _wrap_delete_SharedGateway, METH_O, NULL}, + { "SharedGateway_swigregister", SharedGateway_swigregister, METH_O, NULL}, + { "SharedGateway_swiginit", SharedGateway_swiginit, METH_VARARGS, NULL}, + { "new_SharedMessage", _wrap_new_SharedMessage, METH_NOARGS, NULL}, + { "delete_SharedMessage", _wrap_delete_SharedMessage, METH_O, NULL}, + { "SharedMessage_swigregister", SharedMessage_swigregister, METH_O, NULL}, + { "SharedMessage_swiginit", SharedMessage_swiginit, METH_VARARGS, NULL}, + { "new_SharedMessageHeader", _wrap_new_SharedMessageHeader, METH_NOARGS, NULL}, + { "delete_SharedMessageHeader", _wrap_delete_SharedMessageHeader, METH_O, NULL}, + { "SharedMessageHeader_swigregister", SharedMessageHeader_swigregister, METH_O, NULL}, + { "SharedMessageHeader_swiginit", SharedMessageHeader_swiginit, METH_VARARGS, NULL}, + { "new_SharedMessagePayload", _wrap_new_SharedMessagePayload, METH_NOARGS, NULL}, + { "delete_SharedMessagePayload", _wrap_delete_SharedMessagePayload, METH_O, NULL}, + { "SharedMessagePayload_swigregister", SharedMessagePayload_swigregister, METH_O, NULL}, + { "SharedMessagePayload_swiginit", SharedMessagePayload_swiginit, METH_VARARGS, NULL}, + { "new_SharedRouteInfo", _wrap_new_SharedRouteInfo, METH_NOARGS, NULL}, + { "delete_SharedRouteInfo", _wrap_delete_SharedRouteInfo, METH_O, NULL}, + { "SharedRouteInfo_swigregister", SharedRouteInfo_swigregister, METH_O, NULL}, + { "SharedRouteInfo_swiginit", SharedRouteInfo_swiginit, METH_VARARGS, NULL}, + { "new_SharedMessageBuilder", _wrap_new_SharedMessageBuilder, METH_NOARGS, NULL}, + { "delete_SharedMessageBuilder", _wrap_delete_SharedMessageBuilder, METH_O, NULL}, + { "SharedMessageBuilder_swigregister", SharedMessageBuilder_swigregister, METH_O, NULL}, + { "SharedMessageBuilder_swiginit", SharedMessageBuilder_swiginit, METH_VARARGS, NULL}, + { "new_SharedMessageHeaderBuilder", _wrap_new_SharedMessageHeaderBuilder, METH_NOARGS, NULL}, + { "delete_SharedMessageHeaderBuilder", _wrap_delete_SharedMessageHeaderBuilder, METH_O, NULL}, + { "SharedMessageHeaderBuilder_swigregister", SharedMessageHeaderBuilder_swigregister, METH_O, NULL}, + { "SharedMessageHeaderBuilder_swiginit", SharedMessageHeaderBuilder_swiginit, METH_VARARGS, NULL}, + { "new_SharedMessagePayloadBuilder", _wrap_new_SharedMessagePayloadBuilder, METH_NOARGS, NULL}, + { "delete_SharedMessagePayloadBuilder", _wrap_delete_SharedMessagePayloadBuilder, METH_O, NULL}, + { "SharedMessagePayloadBuilder_swigregister", SharedMessagePayloadBuilder_swigregister, METH_O, NULL}, + { "SharedMessagePayloadBuilder_swiginit", SharedMessagePayloadBuilder_swiginit, METH_VARARGS, NULL}, + { "new_SharedRouteInfoBuilder", _wrap_new_SharedRouteInfoBuilder, METH_NOARGS, NULL}, + { "delete_SharedRouteInfoBuilder", _wrap_delete_SharedRouteInfoBuilder, METH_O, NULL}, + { "SharedRouteInfoBuilder_swigregister", SharedRouteInfoBuilder_swigregister, METH_O, NULL}, + { "SharedRouteInfoBuilder_swiginit", SharedRouteInfoBuilder_swiginit, METH_VARARGS, NULL}, + { "ubytes_iterator", _wrap_ubytes_iterator, METH_O, NULL}, + { "ubytes___nonzero__", _wrap_ubytes___nonzero__, METH_O, NULL}, + { "ubytes___bool__", _wrap_ubytes___bool__, METH_O, NULL}, + { "ubytes___len__", _wrap_ubytes___len__, METH_O, NULL}, + { "ubytes___getslice__", _wrap_ubytes___getslice__, METH_VARARGS, NULL}, + { "ubytes___setslice__", _wrap_ubytes___setslice__, METH_VARARGS, NULL}, + { "ubytes___delslice__", _wrap_ubytes___delslice__, METH_VARARGS, NULL}, + { "ubytes___delitem__", _wrap_ubytes___delitem__, METH_VARARGS, NULL}, + { "ubytes___getitem__", _wrap_ubytes___getitem__, METH_VARARGS, NULL}, + { "ubytes___setitem__", _wrap_ubytes___setitem__, METH_VARARGS, NULL}, + { "ubytes_pop", _wrap_ubytes_pop, METH_O, NULL}, + { "ubytes_append", _wrap_ubytes_append, METH_VARARGS, NULL}, + { "ubytes_empty", _wrap_ubytes_empty, METH_O, NULL}, + { "ubytes_size", _wrap_ubytes_size, METH_O, NULL}, + { "ubytes_swap", _wrap_ubytes_swap, METH_VARARGS, NULL}, + { "ubytes_begin", _wrap_ubytes_begin, METH_O, NULL}, + { "ubytes_end", _wrap_ubytes_end, METH_O, NULL}, + { "ubytes_rbegin", _wrap_ubytes_rbegin, METH_O, NULL}, + { "ubytes_rend", _wrap_ubytes_rend, METH_O, NULL}, + { "ubytes_clear", _wrap_ubytes_clear, METH_O, NULL}, + { "ubytes_get_allocator", _wrap_ubytes_get_allocator, METH_O, NULL}, + { "ubytes_pop_back", _wrap_ubytes_pop_back, METH_O, NULL}, + { "ubytes_erase", _wrap_ubytes_erase, METH_VARARGS, NULL}, + { "new_ubytes", _wrap_new_ubytes, METH_VARARGS, NULL}, + { "ubytes_push_back", _wrap_ubytes_push_back, METH_VARARGS, NULL}, + { "ubytes_front", _wrap_ubytes_front, METH_O, NULL}, + { "ubytes_back", _wrap_ubytes_back, METH_O, NULL}, + { "ubytes_assign", _wrap_ubytes_assign, METH_VARARGS, NULL}, + { "ubytes_resize", _wrap_ubytes_resize, METH_VARARGS, NULL}, + { "ubytes_insert", _wrap_ubytes_insert, METH_VARARGS, NULL}, + { "ubytes_reserve", _wrap_ubytes_reserve, METH_VARARGS, NULL}, + { "ubytes_capacity", _wrap_ubytes_capacity, METH_O, NULL}, + { "delete_ubytes", _wrap_delete_ubytes, METH_O, NULL}, + { "ubytes_swigregister", ubytes_swigregister, METH_O, NULL}, + { "ubytes_swiginit", ubytes_swiginit, METH_VARARGS, NULL}, + { "ibytes_iterator", _wrap_ibytes_iterator, METH_O, NULL}, + { "ibytes___nonzero__", _wrap_ibytes___nonzero__, METH_O, NULL}, + { "ibytes___bool__", _wrap_ibytes___bool__, METH_O, NULL}, + { "ibytes___len__", _wrap_ibytes___len__, METH_O, NULL}, + { "ibytes___getslice__", _wrap_ibytes___getslice__, METH_VARARGS, NULL}, + { "ibytes___setslice__", _wrap_ibytes___setslice__, METH_VARARGS, NULL}, + { "ibytes___delslice__", _wrap_ibytes___delslice__, METH_VARARGS, NULL}, + { "ibytes___delitem__", _wrap_ibytes___delitem__, METH_VARARGS, NULL}, + { "ibytes___getitem__", _wrap_ibytes___getitem__, METH_VARARGS, NULL}, + { "ibytes___setitem__", _wrap_ibytes___setitem__, METH_VARARGS, NULL}, + { "ibytes_pop", _wrap_ibytes_pop, METH_O, NULL}, + { "ibytes_append", _wrap_ibytes_append, METH_VARARGS, NULL}, + { "ibytes_empty", _wrap_ibytes_empty, METH_O, NULL}, + { "ibytes_size", _wrap_ibytes_size, METH_O, NULL}, + { "ibytes_swap", _wrap_ibytes_swap, METH_VARARGS, NULL}, + { "ibytes_begin", _wrap_ibytes_begin, METH_O, NULL}, + { "ibytes_end", _wrap_ibytes_end, METH_O, NULL}, + { "ibytes_rbegin", _wrap_ibytes_rbegin, METH_O, NULL}, + { "ibytes_rend", _wrap_ibytes_rend, METH_O, NULL}, + { "ibytes_clear", _wrap_ibytes_clear, METH_O, NULL}, + { "ibytes_get_allocator", _wrap_ibytes_get_allocator, METH_O, NULL}, + { "ibytes_pop_back", _wrap_ibytes_pop_back, METH_O, NULL}, + { "ibytes_erase", _wrap_ibytes_erase, METH_VARARGS, NULL}, + { "new_ibytes", _wrap_new_ibytes, METH_VARARGS, NULL}, + { "ibytes_push_back", _wrap_ibytes_push_back, METH_VARARGS, NULL}, + { "ibytes_front", _wrap_ibytes_front, METH_O, NULL}, + { "ibytes_back", _wrap_ibytes_back, METH_O, NULL}, + { "ibytes_assign", _wrap_ibytes_assign, METH_VARARGS, NULL}, + { "ibytes_resize", _wrap_ibytes_resize, METH_VARARGS, NULL}, + { "ibytes_insert", _wrap_ibytes_insert, METH_VARARGS, NULL}, + { "ibytes_reserve", _wrap_ibytes_reserve, METH_VARARGS, NULL}, + { "ibytes_capacity", _wrap_ibytes_capacity, METH_O, NULL}, + { "delete_ibytes", _wrap_delete_ibytes, METH_O, NULL}, + { "ibytes_swigregister", ibytes_swigregister, METH_O, NULL}, + { "ibytes_swiginit", ibytes_swiginit, METH_VARARGS, NULL}, + { "StringVec_iterator", _wrap_StringVec_iterator, METH_O, NULL}, + { "StringVec___nonzero__", _wrap_StringVec___nonzero__, METH_O, NULL}, + { "StringVec___bool__", _wrap_StringVec___bool__, METH_O, NULL}, + { "StringVec___len__", _wrap_StringVec___len__, METH_O, NULL}, + { "StringVec___getslice__", _wrap_StringVec___getslice__, METH_VARARGS, NULL}, + { "StringVec___setslice__", _wrap_StringVec___setslice__, METH_VARARGS, NULL}, + { "StringVec___delslice__", _wrap_StringVec___delslice__, METH_VARARGS, NULL}, + { "StringVec___delitem__", _wrap_StringVec___delitem__, METH_VARARGS, NULL}, + { "StringVec___getitem__", _wrap_StringVec___getitem__, METH_VARARGS, NULL}, + { "StringVec___setitem__", _wrap_StringVec___setitem__, METH_VARARGS, NULL}, + { "StringVec_pop", _wrap_StringVec_pop, METH_O, NULL}, + { "StringVec_append", _wrap_StringVec_append, METH_VARARGS, NULL}, + { "StringVec_empty", _wrap_StringVec_empty, METH_O, NULL}, + { "StringVec_size", _wrap_StringVec_size, METH_O, NULL}, + { "StringVec_swap", _wrap_StringVec_swap, METH_VARARGS, NULL}, + { "StringVec_begin", _wrap_StringVec_begin, METH_O, NULL}, + { "StringVec_end", _wrap_StringVec_end, METH_O, NULL}, + { "StringVec_rbegin", _wrap_StringVec_rbegin, METH_O, NULL}, + { "StringVec_rend", _wrap_StringVec_rend, METH_O, NULL}, + { "StringVec_clear", _wrap_StringVec_clear, METH_O, NULL}, + { "StringVec_get_allocator", _wrap_StringVec_get_allocator, METH_O, NULL}, + { "StringVec_pop_back", _wrap_StringVec_pop_back, METH_O, NULL}, + { "StringVec_erase", _wrap_StringVec_erase, METH_VARARGS, NULL}, + { "new_StringVec", _wrap_new_StringVec, METH_VARARGS, NULL}, + { "StringVec_push_back", _wrap_StringVec_push_back, METH_VARARGS, NULL}, + { "StringVec_front", _wrap_StringVec_front, METH_O, NULL}, + { "StringVec_back", _wrap_StringVec_back, METH_O, NULL}, + { "StringVec_assign", _wrap_StringVec_assign, METH_VARARGS, NULL}, + { "StringVec_resize", _wrap_StringVec_resize, METH_VARARGS, NULL}, + { "StringVec_insert", _wrap_StringVec_insert, METH_VARARGS, NULL}, + { "StringVec_reserve", _wrap_StringVec_reserve, METH_VARARGS, NULL}, + { "StringVec_capacity", _wrap_StringVec_capacity, METH_O, NULL}, + { "delete_StringVec", _wrap_delete_StringVec, METH_O, NULL}, + { "StringVec_swigregister", StringVec_swigregister, METH_O, NULL}, + { "StringVec_swiginit", StringVec_swiginit, METH_VARARGS, NULL}, + { "NodeInfoVec_iterator", _wrap_NodeInfoVec_iterator, METH_O, NULL}, + { "NodeInfoVec___nonzero__", _wrap_NodeInfoVec___nonzero__, METH_O, NULL}, + { "NodeInfoVec___bool__", _wrap_NodeInfoVec___bool__, METH_O, NULL}, + { "NodeInfoVec___len__", _wrap_NodeInfoVec___len__, METH_O, NULL}, + { "NodeInfoVec___getslice__", _wrap_NodeInfoVec___getslice__, METH_VARARGS, NULL}, + { "NodeInfoVec___setslice__", _wrap_NodeInfoVec___setslice__, METH_VARARGS, NULL}, + { "NodeInfoVec___delslice__", _wrap_NodeInfoVec___delslice__, METH_VARARGS, NULL}, + { "NodeInfoVec___delitem__", _wrap_NodeInfoVec___delitem__, METH_VARARGS, NULL}, + { "NodeInfoVec___getitem__", _wrap_NodeInfoVec___getitem__, METH_VARARGS, NULL}, + { "NodeInfoVec___setitem__", _wrap_NodeInfoVec___setitem__, METH_VARARGS, NULL}, + { "NodeInfoVec_pop", _wrap_NodeInfoVec_pop, METH_O, NULL}, + { "NodeInfoVec_append", _wrap_NodeInfoVec_append, METH_VARARGS, NULL}, + { "NodeInfoVec_empty", _wrap_NodeInfoVec_empty, METH_O, NULL}, + { "NodeInfoVec_size", _wrap_NodeInfoVec_size, METH_O, NULL}, + { "NodeInfoVec_swap", _wrap_NodeInfoVec_swap, METH_VARARGS, NULL}, + { "NodeInfoVec_begin", _wrap_NodeInfoVec_begin, METH_O, NULL}, + { "NodeInfoVec_end", _wrap_NodeInfoVec_end, METH_O, NULL}, + { "NodeInfoVec_rbegin", _wrap_NodeInfoVec_rbegin, METH_O, NULL}, + { "NodeInfoVec_rend", _wrap_NodeInfoVec_rend, METH_O, NULL}, + { "NodeInfoVec_clear", _wrap_NodeInfoVec_clear, METH_O, NULL}, + { "NodeInfoVec_get_allocator", _wrap_NodeInfoVec_get_allocator, METH_O, NULL}, + { "NodeInfoVec_pop_back", _wrap_NodeInfoVec_pop_back, METH_O, NULL}, + { "NodeInfoVec_erase", _wrap_NodeInfoVec_erase, METH_VARARGS, NULL}, + { "new_NodeInfoVec", _wrap_new_NodeInfoVec, METH_VARARGS, NULL}, + { "NodeInfoVec_push_back", _wrap_NodeInfoVec_push_back, METH_VARARGS, NULL}, + { "NodeInfoVec_front", _wrap_NodeInfoVec_front, METH_O, NULL}, + { "NodeInfoVec_back", _wrap_NodeInfoVec_back, METH_O, NULL}, + { "NodeInfoVec_assign", _wrap_NodeInfoVec_assign, METH_VARARGS, NULL}, + { "NodeInfoVec_resize", _wrap_NodeInfoVec_resize, METH_VARARGS, NULL}, + { "NodeInfoVec_insert", _wrap_NodeInfoVec_insert, METH_VARARGS, NULL}, + { "NodeInfoVec_reserve", _wrap_NodeInfoVec_reserve, METH_VARARGS, NULL}, + { "NodeInfoVec_capacity", _wrap_NodeInfoVec_capacity, METH_O, NULL}, + { "delete_NodeInfoVec", _wrap_delete_NodeInfoVec, METH_O, NULL}, + { "NodeInfoVec_swigregister", NodeInfoVec_swigregister, METH_O, NULL}, + { "NodeInfoVec_swiginit", NodeInfoVec_swiginit, METH_VARARGS, NULL}, + { "Error_buildError", _wrap_Error_buildError, METH_VARARGS, NULL}, + { "new_Error", _wrap_new_Error, METH_VARARGS, NULL}, + { "delete_Error", _wrap_delete_Error, METH_O, NULL}, + { "Error_errorCode", _wrap_Error_errorCode, METH_O, NULL}, + { "Error_errorMessage", _wrap_Error_errorMessage, METH_O, NULL}, + { "Error_setErrorCode", _wrap_Error_setErrorCode, METH_VARARGS, NULL}, + { "Error_setErrorMessage", _wrap_Error_setErrorMessage, METH_VARARGS, NULL}, + { "Error_swigregister", Error_swigregister, METH_O, NULL}, + { "Error_swiginit", Error_swiginit, METH_VARARGS, NULL}, + { "InputBuffer_data_set", _wrap_InputBuffer_data_set, METH_VARARGS, NULL}, + { "InputBuffer_data_get", _wrap_InputBuffer_data_get, METH_O, NULL}, + { "InputBuffer_len_set", _wrap_InputBuffer_len_set, METH_VARARGS, NULL}, + { "InputBuffer_len_get", _wrap_InputBuffer_len_get, METH_O, NULL}, + { "new_InputBuffer", _wrap_new_InputBuffer, METH_NOARGS, NULL}, + { "delete_InputBuffer", _wrap_delete_InputBuffer, METH_O, NULL}, + { "InputBuffer_swigregister", InputBuffer_swigregister, METH_O, NULL}, + { "InputBuffer_swiginit", InputBuffer_swiginit, METH_VARARGS, NULL}, + { "OutputBuffer_data_set", _wrap_OutputBuffer_data_set, METH_VARARGS, NULL}, + { "OutputBuffer_data_get", _wrap_OutputBuffer_data_get, METH_O, NULL}, + { "OutputBuffer_len_set", _wrap_OutputBuffer_len_set, METH_VARARGS, NULL}, + { "OutputBuffer_len_get", _wrap_OutputBuffer_len_get, METH_O, NULL}, + { "new_OutputBuffer", _wrap_new_OutputBuffer, METH_NOARGS, NULL}, + { "delete_OutputBuffer", _wrap_delete_OutputBuffer, METH_O, NULL}, + { "OutputBuffer_swigregister", OutputBuffer_swigregister, METH_O, NULL}, + { "OutputBuffer_swiginit", OutputBuffer_swiginit, METH_VARARGS, NULL}, + { "delete_FrontConfig", _wrap_delete_FrontConfig, METH_O, NULL}, + { "FrontConfig_threadPoolSize", _wrap_FrontConfig_threadPoolSize, METH_O, NULL}, + { "FrontConfig_setThreadPoolSize", _wrap_FrontConfig_setThreadPoolSize, METH_VARARGS, NULL}, + { "FrontConfig_nodeID", _wrap_FrontConfig_nodeID, METH_O, NULL}, + { "FrontConfig_setNodeID", _wrap_FrontConfig_setNodeID, METH_VARARGS, NULL}, + { "FrontConfig_selfEndPoint", _wrap_FrontConfig_selfEndPoint, METH_O, NULL}, + { "FrontConfig_mutableSelfEndPoint", _wrap_FrontConfig_mutableSelfEndPoint, METH_O, NULL}, + { "FrontConfig_setSelfEndPoint", _wrap_FrontConfig_setSelfEndPoint, METH_VARARGS, NULL}, + { "FrontConfig_setGatewayGrpcTarget", _wrap_FrontConfig_setGatewayGrpcTarget, METH_VARARGS, NULL}, + { "FrontConfig_gatewayGrpcTarget", _wrap_FrontConfig_gatewayGrpcTarget, METH_O, NULL}, + { "FrontConfig_setGrpcConfig", _wrap_FrontConfig_setGrpcConfig, METH_VARARGS, NULL}, + { "FrontConfig_grpcConfig", _wrap_FrontConfig_grpcConfig, METH_O, NULL}, + { "FrontConfig_generateNodeInfo", _wrap_FrontConfig_generateNodeInfo, METH_O, NULL}, + { "FrontConfig_getComponents", _wrap_FrontConfig_getComponents, METH_O, NULL}, + { "FrontConfig_setComponents", _wrap_FrontConfig_setComponents, METH_VARARGS, NULL}, + { "FrontConfig_addComponent", _wrap_FrontConfig_addComponent, METH_VARARGS, NULL}, + { "FrontConfig_mutableComponents", _wrap_FrontConfig_mutableComponents, METH_O, NULL}, + { "FrontConfig_meta", _wrap_FrontConfig_meta, METH_O, NULL}, + { "FrontConfig_setMeta", _wrap_FrontConfig_setMeta, METH_VARARGS, NULL}, + { "FrontConfig_swigregister", FrontConfig_swigregister, METH_O, NULL}, + { "delete_FrontConfigBuilder", _wrap_delete_FrontConfigBuilder, METH_O, NULL}, + { "FrontConfigBuilder_build", _wrap_FrontConfigBuilder_build, METH_VARARGS, NULL}, + { "FrontConfigBuilder_swigregister", FrontConfigBuilder_swigregister, METH_O, NULL}, + { "printFrontDesc", _wrap_printFrontDesc, METH_O, NULL}, + { "new_EndPoint", _wrap_new_EndPoint, METH_VARARGS, NULL}, + { "delete_EndPoint", _wrap_delete_EndPoint, METH_O, NULL}, + { "EndPoint_host", _wrap_EndPoint_host, METH_O, NULL}, + { "EndPoint_port", _wrap_EndPoint_port, METH_O, NULL}, + { "EndPoint_setHost", _wrap_EndPoint_setHost, METH_VARARGS, NULL}, + { "EndPoint_setPort", _wrap_EndPoint_setPort, METH_VARARGS, NULL}, + { "EndPoint_setListenIp", _wrap_EndPoint_setListenIp, METH_VARARGS, NULL}, + { "EndPoint_entryPoint", _wrap_EndPoint_entryPoint, METH_O, NULL}, + { "EndPoint_listenEndPoint", _wrap_EndPoint_listenEndPoint, METH_O, NULL}, + { "EndPoint_listenIp", _wrap_EndPoint_listenIp, METH_O, NULL}, + { "EndPoint_swigregister", EndPoint_swigregister, METH_O, NULL}, + { "EndPoint_swiginit", EndPoint_swiginit, METH_VARARGS, NULL}, + { "new_GrpcConfig", _wrap_new_GrpcConfig, METH_NOARGS, NULL}, + { "GrpcConfig_loadBalancePolicy", _wrap_GrpcConfig_loadBalancePolicy, METH_O, NULL}, + { "GrpcConfig_setLoadBalancePolicy", _wrap_GrpcConfig_setLoadBalancePolicy, METH_VARARGS, NULL}, + { "GrpcConfig_enableHealthCheck", _wrap_GrpcConfig_enableHealthCheck, METH_O, NULL}, + { "GrpcConfig_setEnableHealthCheck", _wrap_GrpcConfig_setEnableHealthCheck, METH_VARARGS, NULL}, + { "GrpcConfig_setEnableDnslookup", _wrap_GrpcConfig_setEnableDnslookup, METH_VARARGS, NULL}, + { "GrpcConfig_enableDnslookup", _wrap_GrpcConfig_enableDnslookup, METH_O, NULL}, + { "GrpcConfig_maxSendMessageSize", _wrap_GrpcConfig_maxSendMessageSize, METH_O, NULL}, + { "GrpcConfig_maxReceivedMessageSize", _wrap_GrpcConfig_maxReceivedMessageSize, METH_O, NULL}, + { "GrpcConfig_setMaxSendMessageSize", _wrap_GrpcConfig_setMaxSendMessageSize, METH_VARARGS, NULL}, + { "GrpcConfig_setMaxReceivedMessageSize", _wrap_GrpcConfig_setMaxReceivedMessageSize, METH_VARARGS, NULL}, + { "GrpcConfig_compressAlgorithm", _wrap_GrpcConfig_compressAlgorithm, METH_O, NULL}, + { "GrpcConfig_setCompressAlgorithm", _wrap_GrpcConfig_setCompressAlgorithm, METH_VARARGS, NULL}, + { "GrpcConfig_maxMsgSize", _wrap_GrpcConfig_maxMsgSize, METH_O, NULL}, + { "GrpcConfig_setMaxMsgSize", _wrap_GrpcConfig_setMaxMsgSize, METH_VARARGS, NULL}, + { "GrpcConfig_swigregister", GrpcConfig_swigregister, METH_O, NULL}, + { "GrpcConfig_swiginit", GrpcConfig_swiginit, METH_VARARGS, NULL}, + { "new_GrpcServerConfig", _wrap_new_GrpcServerConfig, METH_VARARGS, NULL}, + { "GrpcServerConfig_listenEndPoint", _wrap_GrpcServerConfig_listenEndPoint, METH_O, NULL}, + { "GrpcServerConfig_setEndPoint", _wrap_GrpcServerConfig_setEndPoint, METH_VARARGS, NULL}, + { "GrpcServerConfig_setEnableHealthCheck", _wrap_GrpcServerConfig_setEnableHealthCheck, METH_VARARGS, NULL}, + { "GrpcServerConfig_endPoint", _wrap_GrpcServerConfig_endPoint, METH_O, NULL}, + { "GrpcServerConfig_mutableEndPoint", _wrap_GrpcServerConfig_mutableEndPoint, METH_O, NULL}, + { "GrpcServerConfig_enableHealthCheck", _wrap_GrpcServerConfig_enableHealthCheck, METH_O, NULL}, + { "GrpcServerConfig_grpcConfig", _wrap_GrpcServerConfig_grpcConfig, METH_O, NULL}, + { "GrpcServerConfig_swigregister", GrpcServerConfig_swigregister, METH_O, NULL}, + { "GrpcServerConfig_swiginit", GrpcServerConfig_swiginit, METH_VARARGS, NULL}, + { "printGrpcConfig", _wrap_printGrpcConfig, METH_O, NULL}, + { "delete_MessageOptionalHeader", _wrap_delete_MessageOptionalHeader, METH_O, NULL}, + { "MessageOptionalHeader_encode", _wrap_MessageOptionalHeader_encode, METH_VARARGS, NULL}, + { "MessageOptionalHeader_decode", _wrap_MessageOptionalHeader_decode, METH_VARARGS, NULL}, + { "MessageOptionalHeader_componentType", _wrap_MessageOptionalHeader_componentType, METH_O, NULL}, + { "MessageOptionalHeader_setComponentType", _wrap_MessageOptionalHeader_setComponentType, METH_VARARGS, NULL}, + { "MessageOptionalHeader_srcNodeBuffer", _wrap_MessageOptionalHeader_srcNodeBuffer, METH_O, " for swig-wrapper(pass the binary data)"}, + { "MessageOptionalHeader_setSrcNodeBuffer", _wrap_MessageOptionalHeader_setSrcNodeBuffer, METH_VARARGS, NULL}, + { "MessageOptionalHeader_dstNodeBuffer", _wrap_MessageOptionalHeader_dstNodeBuffer, METH_O, NULL}, + { "MessageOptionalHeader_setDstNodeBuffer", _wrap_MessageOptionalHeader_setDstNodeBuffer, METH_VARARGS, NULL}, + { "MessageOptionalHeader_dstInst", _wrap_MessageOptionalHeader_dstInst, METH_O, NULL}, + { "MessageOptionalHeader_setDstInst", _wrap_MessageOptionalHeader_setDstInst, METH_VARARGS, NULL}, + { "MessageOptionalHeader_topic", _wrap_MessageOptionalHeader_topic, METH_O, NULL}, + { "MessageOptionalHeader_setTopic", _wrap_MessageOptionalHeader_setTopic, METH_VARARGS, NULL}, + { "MessageOptionalHeader_srcInst", _wrap_MessageOptionalHeader_srcInst, METH_O, NULL}, + { "MessageOptionalHeader_setSrcInst", _wrap_MessageOptionalHeader_setSrcInst, METH_VARARGS, NULL}, + { "MessageOptionalHeader_swigregister", MessageOptionalHeader_swigregister, METH_O, NULL}, + { "delete_MessageHeader", _wrap_delete_MessageHeader, METH_O, NULL}, + { "MessageHeader_encode", _wrap_MessageHeader_encode, METH_VARARGS, NULL}, + { "MessageHeader_decode", _wrap_MessageHeader_decode, METH_VARARGS, NULL}, + { "MessageHeader_version", _wrap_MessageHeader_version, METH_O, NULL}, + { "MessageHeader_setVersion", _wrap_MessageHeader_setVersion, METH_VARARGS, NULL}, + { "MessageHeader_traceID", _wrap_MessageHeader_traceID, METH_O, NULL}, + { "MessageHeader_setTraceID", _wrap_MessageHeader_setTraceID, METH_VARARGS, NULL}, + { "MessageHeader_srcGwNode", _wrap_MessageHeader_srcGwNode, METH_O, NULL}, + { "MessageHeader_setSrcGwNode", _wrap_MessageHeader_setSrcGwNode, METH_VARARGS, NULL}, + { "MessageHeader_dstGwNode", _wrap_MessageHeader_dstGwNode, METH_O, NULL}, + { "MessageHeader_setDstGwNode", _wrap_MessageHeader_setDstGwNode, METH_VARARGS, NULL}, + { "MessageHeader_packetType", _wrap_MessageHeader_packetType, METH_O, NULL}, + { "MessageHeader_setPacketType", _wrap_MessageHeader_setPacketType, METH_VARARGS, NULL}, + { "MessageHeader_ttl", _wrap_MessageHeader_ttl, METH_O, NULL}, + { "MessageHeader_setTTL", _wrap_MessageHeader_setTTL, METH_VARARGS, NULL}, + { "MessageHeader_ext", _wrap_MessageHeader_ext, METH_O, NULL}, + { "MessageHeader_setExt", _wrap_MessageHeader_setExt, METH_VARARGS, NULL}, + { "MessageHeader_optionalField", _wrap_MessageHeader_optionalField, METH_O, NULL}, + { "MessageHeader_setOptionalField", _wrap_MessageHeader_setOptionalField, METH_VARARGS, NULL}, + { "MessageHeader_length", _wrap_MessageHeader_length, METH_O, NULL}, + { "MessageHeader_isRespPacket", _wrap_MessageHeader_isRespPacket, METH_O, NULL}, + { "MessageHeader_setRespPacket", _wrap_MessageHeader_setRespPacket, METH_O, NULL}, + { "MessageHeader_srcP2PNodeIDView", _wrap_MessageHeader_srcP2PNodeIDView, METH_O, NULL}, + { "MessageHeader_dstP2PNodeIDView", _wrap_MessageHeader_dstP2PNodeIDView, METH_O, NULL}, + { "MessageHeader_routeType", _wrap_MessageHeader_routeType, METH_O, NULL}, + { "MessageHeader_setRouteType", _wrap_MessageHeader_setRouteType, METH_VARARGS, NULL}, + { "MessageHeader_hasOptionalField", _wrap_MessageHeader_hasOptionalField, METH_O, NULL}, + { "MessageHeader_swigregister", MessageHeader_swigregister, METH_O, NULL}, + { "delete_Message", _wrap_delete_Message, METH_O, NULL}, + { "Message_header", _wrap_Message_header, METH_O, NULL}, + { "Message_setHeader", _wrap_Message_setHeader, METH_VARARGS, NULL}, + { "Message_version", _wrap_Message_version, METH_O, " the overloaed implementation ==="}, + { "Message_setVersion", _wrap_Message_setVersion, METH_VARARGS, NULL}, + { "Message_packetType", _wrap_Message_packetType, METH_O, NULL}, + { "Message_setPacketType", _wrap_Message_setPacketType, METH_VARARGS, NULL}, + { "Message_seq", _wrap_Message_seq, METH_O, NULL}, + { "Message_setSeq", _wrap_Message_setSeq, METH_VARARGS, NULL}, + { "Message_ext", _wrap_Message_ext, METH_O, NULL}, + { "Message_setExt", _wrap_Message_setExt, METH_VARARGS, NULL}, + { "Message_isRespPacket", _wrap_Message_isRespPacket, METH_O, NULL}, + { "Message_setRespPacket", _wrap_Message_setRespPacket, METH_O, NULL}, + { "Message_setPayload", _wrap_Message_setPayload, METH_VARARGS, NULL}, + { "Message_payloadBuffer", _wrap_Message_payloadBuffer, METH_O, NULL}, + { "Message_frontMessage", _wrap_Message_frontMessage, METH_O, NULL}, + { "Message_encode", _wrap_Message_encode, METH_VARARGS, NULL}, + { "Message_decode", _wrap_Message_decode, METH_VARARGS, NULL}, + { "Message_length", _wrap_Message_length, METH_O, NULL}, + { "Message_payload", _wrap_Message_payload, METH_O, NULL}, + { "Message_releasePayload", _wrap_Message_releasePayload, METH_O, NULL}, + { "Message_swigregister", Message_swigregister, METH_O, NULL}, + { "delete_MessageHeaderBuilder", _wrap_delete_MessageHeaderBuilder, METH_O, NULL}, + { "MessageHeaderBuilder_build", _wrap_MessageHeaderBuilder_build, METH_VARARGS, NULL}, + { "MessageHeaderBuilder_swigregister", MessageHeaderBuilder_swigregister, METH_O, NULL}, + { "delete_MessageBuilder", _wrap_delete_MessageBuilder, METH_O, NULL}, + { "MessageBuilder_build", _wrap_MessageBuilder_build, METH_VARARGS, NULL}, + { "MessageBuilder_swigregister", MessageBuilder_swigregister, METH_O, NULL}, + { "delete_MessageOptionalHeaderBuilder", _wrap_delete_MessageOptionalHeaderBuilder, METH_O, NULL}, + { "MessageOptionalHeaderBuilder_build", _wrap_MessageOptionalHeaderBuilder_build, METH_VARARGS, NULL}, + { "MessageOptionalHeaderBuilder_swigregister", MessageOptionalHeaderBuilder_swigregister, METH_O, NULL}, + { "printOptionalField", _wrap_printOptionalField, METH_O, NULL}, + { "printMessage", _wrap_printMessage, METH_O, NULL}, + { "delete_MessagePayload", _wrap_delete_MessagePayload, METH_O, NULL}, + { "MessagePayload_encode", _wrap_MessagePayload_encode, METH_VARARGS, NULL}, + { "MessagePayload_decode", _wrap_MessagePayload_decode, METH_VARARGS, NULL}, + { "MessagePayload_version", _wrap_MessagePayload_version, METH_O, NULL}, + { "MessagePayload_setVersion", _wrap_MessagePayload_setVersion, METH_VARARGS, NULL}, + { "MessagePayload_dataBuffer", _wrap_MessagePayload_dataBuffer, METH_O, NULL}, + { "MessagePayload_seq", _wrap_MessagePayload_seq, METH_O, NULL}, + { "MessagePayload_setSeq", _wrap_MessagePayload_setSeq, METH_VARARGS, NULL}, + { "MessagePayload_length", _wrap_MessagePayload_length, METH_O, NULL}, + { "MessagePayload_traceID", _wrap_MessagePayload_traceID, METH_O, NULL}, + { "MessagePayload_setTraceID", _wrap_MessagePayload_setTraceID, METH_VARARGS, NULL}, + { "MessagePayload_ext", _wrap_MessagePayload_ext, METH_O, NULL}, + { "MessagePayload_setExt", _wrap_MessagePayload_setExt, METH_VARARGS, NULL}, + { "MessagePayload_setRespPacket", _wrap_MessagePayload_setRespPacket, METH_O, NULL}, + { "MessagePayload_isRespPacket", _wrap_MessagePayload_isRespPacket, METH_O, NULL}, + { "MessagePayload_releasePayload", _wrap_MessagePayload_releasePayload, METH_O, NULL}, + { "MessagePayload_swigregister", MessagePayload_swigregister, METH_O, NULL}, + { "delete_MessagePayloadBuilder", _wrap_delete_MessagePayloadBuilder, METH_O, NULL}, + { "MessagePayloadBuilder_build", _wrap_MessagePayloadBuilder_build, METH_VARARGS, NULL}, + { "MessagePayloadBuilder_swigregister", MessagePayloadBuilder_swigregister, METH_O, NULL}, + { "delete_IFrontClient", _wrap_delete_IFrontClient, METH_O, NULL}, + { "IFrontClient_onReceiveMessage", _wrap_IFrontClient_onReceiveMessage, METH_VARARGS, "\n" + ": receive message from gateway, call by gateway\n" + ":param _message:: received ppc message\n" + ":rtype: void\n" + ":return: void\n" + ""}, + { "IFrontClient_swigregister", IFrontClient_swigregister, METH_O, NULL}, + { "new_ErrorCallback", _wrap_new_ErrorCallback, METH_O, NULL}, + { "delete_ErrorCallback", _wrap_delete_ErrorCallback, METH_O, NULL}, + { "ErrorCallback_onError", _wrap_ErrorCallback_onError, METH_VARARGS, NULL}, + { "disown_ErrorCallback", _wrap_disown_ErrorCallback, METH_O, NULL}, + { "ErrorCallback_swigregister", ErrorCallback_swigregister, METH_O, NULL}, + { "ErrorCallback_swiginit", ErrorCallback_swiginit, METH_VARARGS, NULL}, + { "new_MessageDispatcherHandler", _wrap_new_MessageDispatcherHandler, METH_O, NULL}, + { "delete_MessageDispatcherHandler", _wrap_delete_MessageDispatcherHandler, METH_O, NULL}, + { "MessageDispatcherHandler_onMessage", _wrap_MessageDispatcherHandler_onMessage, METH_VARARGS, NULL}, + { "disown_MessageDispatcherHandler", _wrap_disown_MessageDispatcherHandler, METH_O, NULL}, + { "MessageDispatcherHandler_swigregister", MessageDispatcherHandler_swigregister, METH_O, NULL}, + { "MessageDispatcherHandler_swiginit", MessageDispatcherHandler_swiginit, METH_VARARGS, NULL}, + { "new_SendResponseHandler", _wrap_new_SendResponseHandler, METH_O, NULL}, + { "delete_SendResponseHandler", _wrap_delete_SendResponseHandler, METH_O, NULL}, + { "SendResponseHandler_sendResponse", _wrap_SendResponseHandler_sendResponse, METH_VARARGS, NULL}, + { "SendResponseHandler_swigregister", SendResponseHandler_swigregister, METH_O, NULL}, + { "SendResponseHandler_swiginit", SendResponseHandler_swiginit, METH_VARARGS, NULL}, + { "new_IMessageHandler", _wrap_new_IMessageHandler, METH_O, NULL}, + { "delete_IMessageHandler", _wrap_delete_IMessageHandler, METH_O, NULL}, + { "IMessageHandler_onMessage", _wrap_IMessageHandler_onMessage, METH_VARARGS, NULL}, + { "disown_IMessageHandler", _wrap_disown_IMessageHandler, METH_O, NULL}, + { "IMessageHandler_swigregister", IMessageHandler_swigregister, METH_O, NULL}, + { "IMessageHandler_swiginit", IMessageHandler_swiginit, METH_VARARGS, NULL}, + { "new_GetPeersInfoHandler", _wrap_new_GetPeersInfoHandler, METH_O, NULL}, + { "delete_GetPeersInfoHandler", _wrap_delete_GetPeersInfoHandler, METH_O, NULL}, + { "GetPeersInfoHandler_onPeersInfo", _wrap_GetPeersInfoHandler_onPeersInfo, METH_VARARGS, NULL}, + { "disown_GetPeersInfoHandler", _wrap_disown_GetPeersInfoHandler, METH_O, NULL}, + { "GetPeersInfoHandler_swigregister", GetPeersInfoHandler_swigregister, METH_O, NULL}, + { "GetPeersInfoHandler_swiginit", GetPeersInfoHandler_swiginit, METH_VARARGS, NULL}, + { "delete_IFront", _wrap_delete_IFront, METH_O, NULL}, + { "IFront_start", _wrap_IFront_start, METH_O, "\n" + "start the IFront\n" + "\n" + ":param front: the IFront to start\n" + ""}, + { "IFront_stop", _wrap_IFront_stop, METH_O, "\n" + "stop the IFront\n" + "\n" + ":param front: the IFront to stop\n" + ""}, + { "IFront_register_topic_handler", _wrap_IFront_register_topic_handler, METH_VARARGS, NULL}, + { "IFront_register_msg_handler", _wrap_IFront_register_msg_handler, METH_VARARGS, NULL}, + { "IFront_async_send_message", _wrap_IFront_async_send_message, METH_VARARGS, NULL}, + { "IFront_async_send_response", _wrap_IFront_async_send_response, METH_VARARGS, NULL}, + { "IFront_push_msg", _wrap_IFront_push_msg, METH_VARARGS, NULL}, + { "IFront_pop", _wrap_IFront_pop, METH_VARARGS, NULL}, + { "IFront_peek", _wrap_IFront_peek, METH_VARARGS, NULL}, + { "IFront_asyncGetPeers", _wrap_IFront_asyncGetPeers, METH_VARARGS, NULL}, + { "IFront_nodeInfo", _wrap_IFront_nodeInfo, METH_O, NULL}, + { "IFront_registerTopic", _wrap_IFront_registerTopic, METH_VARARGS, "\n" + "register the topic\n" + "\n" + ":type topic: string\n" + ":param topic: the topic to register\n" + ""}, + { "IFront_unRegisterTopic", _wrap_IFront_unRegisterTopic, METH_VARARGS, "\n" + "unRegister the topic\n" + "\n" + ":type topic: string\n" + ":param topic: the topic to unregister\n" + ""}, + { "IFront_registerComponent", _wrap_IFront_registerComponent, METH_VARARGS, NULL}, + { "IFront_unRegisterComponent", _wrap_IFront_unRegisterComponent, METH_VARARGS, NULL}, + { "IFront_updateMetaInfo", _wrap_IFront_updateMetaInfo, METH_VARARGS, NULL}, + { "IFront_selectNodesByRoutePolicy", _wrap_IFront_selectNodesByRoutePolicy, METH_VARARGS, NULL}, + { "IFront_getNodeDiscovery", _wrap_IFront_getNodeDiscovery, METH_O, NULL}, + { "IFront_swigregister", IFront_swigregister, METH_O, NULL}, + { "delete_IFrontBuilder", _wrap_delete_IFrontBuilder, METH_O, NULL}, + { "IFrontBuilder_buildClient", _wrap_IFrontBuilder_buildClient, METH_VARARGS, NULL}, + { "IFrontBuilder_swigregister", IFrontBuilder_swigregister, METH_O, NULL}, + { "delete_INodeDiscovery", _wrap_delete_INodeDiscovery, METH_O, NULL}, + { "INodeDiscovery_getAliveNodeList", _wrap_INodeDiscovery_getAliveNodeList, METH_O, NULL}, + { "INodeDiscovery_swigregister", INodeDiscovery_swigregister, METH_O, NULL}, + { "new_TransportBuilder", _wrap_new_TransportBuilder, METH_NOARGS, NULL}, + { "delete_TransportBuilder", _wrap_delete_TransportBuilder, METH_O, NULL}, + { "TransportBuilder_buildProTransport", _wrap_TransportBuilder_buildProTransport, METH_VARARGS, NULL}, + { "TransportBuilder_buildConfig", _wrap_TransportBuilder_buildConfig, METH_VARARGS, NULL}, + { "TransportBuilder_frontConfigBuilder", _wrap_TransportBuilder_frontConfigBuilder, METH_O, NULL}, + { "TransportBuilder_initLog", _wrap_TransportBuilder_initLog, METH_VARARGS, NULL}, + { "TransportBuilder_swigregister", TransportBuilder_swigregister, METH_O, NULL}, + { "TransportBuilder_swiginit", TransportBuilder_swiginit, METH_VARARGS, NULL}, + { "new_Transport", _wrap_new_Transport, METH_O, NULL}, + { "delete_Transport", _wrap_delete_Transport, METH_O, NULL}, + { "Transport_start", _wrap_Transport_start, METH_O, NULL}, + { "Transport_stop", _wrap_Transport_stop, METH_O, NULL}, + { "Transport_getFront", _wrap_Transport_getFront, METH_O, NULL}, + { "Transport_gateway", _wrap_Transport_gateway, METH_O, NULL}, + { "Transport_msgPayloadBuilder", _wrap_Transport_msgPayloadBuilder, METH_O, NULL}, + { "Transport_msgBuilder", _wrap_Transport_msgBuilder, METH_O, NULL}, + { "Transport_msgHeaderBuilder", _wrap_Transport_msgHeaderBuilder, METH_O, NULL}, + { "Transport_routeInfoBuilder", _wrap_Transport_routeInfoBuilder, METH_O, NULL}, + { "Transport_getConfig", _wrap_Transport_getConfig, METH_O, NULL}, + { "Transport_swigregister", Transport_swigregister, METH_O, NULL}, + { "Transport_swiginit", Transport_swiginit, METH_VARARGS, NULL}, + { "delete_INodeInfo", _wrap_delete_INodeInfo, METH_O, NULL}, + { "INodeInfo_endPoint", _wrap_INodeInfo_endPoint, METH_O, NULL}, + { "INodeInfo_nodeID", _wrap_INodeInfo_nodeID, METH_O, NULL}, + { "INodeInfo_setNodeID", _wrap_INodeInfo_setNodeID, METH_VARARGS, NULL}, + { "INodeInfo_setEndPoint", _wrap_INodeInfo_setEndPoint, METH_VARARGS, NULL}, + { "INodeInfo_addComponent", _wrap_INodeInfo_addComponent, METH_VARARGS, NULL}, + { "INodeInfo_eraseComponent", _wrap_INodeInfo_eraseComponent, METH_VARARGS, NULL}, + { "INodeInfo_componentExist", _wrap_INodeInfo_componentExist, METH_VARARGS, NULL}, + { "INodeInfo_copiedComponents", _wrap_INodeInfo_copiedComponents, METH_O, NULL}, + { "INodeInfo_meta", _wrap_INodeInfo_meta, METH_O, NULL}, + { "INodeInfo_setMeta", _wrap_INodeInfo_setMeta, METH_VARARGS, NULL}, + { "INodeInfo_swigregister", INodeInfo_swigregister, METH_O, NULL}, + { "printNodeInfo", _wrap_printNodeInfo, METH_O, NULL}, + { NULL, NULL, 0, NULL } +}; + + +/* -------- TYPE CONVERSION AND EQUIVALENCE RULES (BEGIN) -------- */ + +static void *_p_ppc__front__IFrontTo_p_ppc__front__IFrontClient(void *x, int *SWIGUNUSEDPARM(newmemory)) { + return (void *)((ppc::front::IFrontClient *) ((ppc::front::IFront *) x)); +} +static void *_p_std__shared_ptrT_ppc__front__IFront_tTo_p_std__shared_ptrT_ppc__front__IFrontClient_t(void *x, int *newmemory) { + *newmemory = SWIG_CAST_NEW_MEMORY; + return (void *) new std::shared_ptr< ppc::front::IFrontClient >(*(std::shared_ptr< ppc::front::IFront > *)x); +} +static swig_type_info _swigt__p_ConstPtr = {"_p_ConstPtr", "ConstPtr *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_InputBuffer = {"_p_InputBuffer", "InputBuffer *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_OutputBuffer = {"_p_OutputBuffer", "OutputBuffer *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_PrevStdError = {"_p_PrevStdError", "PrevStdError *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_Ptr = {"_p_Ptr", "Ptr *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_UniqueConstPtr = {"_p_UniqueConstPtr", "UniqueConstPtr *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_UniquePtr = {"_p_UniquePtr", "UniquePtr *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_allocator_type = {"_p_allocator_type", "allocator_type *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_bcos__Error = {"_p_bcos__Error", "bcos::Error *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_bcos__bytesConstRef = {"_p_bcos__bytesConstRef", "bcos::bytesConstRef *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_char = {"_p_char", "char *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_difference_type = {"_p_difference_type", "difference_type *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_int = {"_p_int", "int32_t *|int_fast16_t *|int_fast32_t *|int_least32_t *|intptr_t *|int *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_long_long = {"_p_long_long", "int64_t *|int_fast64_t *|int_least64_t *|intmax_t *|long long *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_p_PyObject = {"_p_p_PyObject", "PyObject **", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_ppc__front__ErrorCallback = {"_p_ppc__front__ErrorCallback", "ppc::front::ErrorCallback *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_ppc__front__FrontConfig = {"_p_ppc__front__FrontConfig", "ppc::front::FrontConfig *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_ppc__front__FrontConfigBuilder = {"_p_ppc__front__FrontConfigBuilder", "ppc::front::FrontConfigBuilder *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_ppc__front__GetPeersInfoHandler = {"_p_ppc__front__GetPeersInfoHandler", "ppc::front::GetPeersInfoHandler *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_ppc__front__IFront = {"_p_ppc__front__IFront", "ppc::front::IFront *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_ppc__front__IFrontBuilder = {"_p_ppc__front__IFrontBuilder", "ppc::front::IFrontBuilder *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_ppc__front__IFrontClient = {"_p_ppc__front__IFrontClient", "ppc::front::IFrontClient *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_ppc__front__IMessageHandler = {"_p_ppc__front__IMessageHandler", "ppc::front::IMessageHandler *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_ppc__front__INodeDiscovery = {"_p_ppc__front__INodeDiscovery", "ppc::front::INodeDiscovery *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_ppc__front__MessageDispatcherHandler = {"_p_ppc__front__MessageDispatcherHandler", "ppc::front::MessageDispatcherHandler *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_ppc__front__SendResponseHandler = {"_p_ppc__front__SendResponseHandler", "ppc::front::SendResponseHandler *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_ppc__gateway__IGateway__Ptr = {"_p_ppc__gateway__IGateway__Ptr", "ppc::gateway::IGateway::Ptr *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_ppc__protocol__EndPoint = {"_p_ppc__protocol__EndPoint", "ppc::protocol::EndPoint *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_ppc__protocol__GrpcConfig = {"_p_ppc__protocol__GrpcConfig", "ppc::protocol::GrpcConfig *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_ppc__protocol__GrpcServerConfig = {"_p_ppc__protocol__GrpcServerConfig", "ppc::protocol::GrpcServerConfig *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_ppc__protocol__INodeInfo = {"_p_ppc__protocol__INodeInfo", "ppc::protocol::INodeInfo *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_ppc__protocol__Message = {"_p_ppc__protocol__Message", "ppc::protocol::Message *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_ppc__protocol__MessageBuilder = {"_p_ppc__protocol__MessageBuilder", "ppc::protocol::MessageBuilder *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_ppc__protocol__MessageHeader = {"_p_ppc__protocol__MessageHeader", "ppc::protocol::MessageHeader *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_ppc__protocol__MessageHeaderBuilder = {"_p_ppc__protocol__MessageHeaderBuilder", "ppc::protocol::MessageHeaderBuilder *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_ppc__protocol__MessageOptionalHeader = {"_p_ppc__protocol__MessageOptionalHeader", "ppc::protocol::MessageOptionalHeader *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_ppc__protocol__MessageOptionalHeaderBuilder = {"_p_ppc__protocol__MessageOptionalHeaderBuilder", "ppc::protocol::MessageOptionalHeaderBuilder *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_ppc__protocol__MessagePayload = {"_p_ppc__protocol__MessagePayload", "ppc::protocol::MessagePayload *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_ppc__protocol__MessagePayloadBuilder = {"_p_ppc__protocol__MessagePayloadBuilder", "ppc::protocol::MessagePayloadBuilder *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_ppc__protocol__RouteType = {"_p_ppc__protocol__RouteType", "ppc::protocol::RouteType *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_ppc__sdk__Transport = {"_p_ppc__sdk__Transport", "ppc::sdk::Transport *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_ppc__sdk__TransportBuilder = {"_p_ppc__sdk__TransportBuilder", "ppc::sdk::TransportBuilder *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_short = {"_p_short", "int16_t *|int_least16_t *|short *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_signed_char = {"_p_signed_char", "int8_t *|int_fast8_t *|int_least8_t *|signed char *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_size_type = {"_p_size_type", "size_type *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_std__allocatorT_signed_char_t = {"_p_std__allocatorT_signed_char_t", "std::vector< signed char >::allocator_type *|std::allocator< signed char > *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_std__allocatorT_std__shared_ptrT_ppc__protocol__INodeInfo_t_t = {"_p_std__allocatorT_std__shared_ptrT_ppc__protocol__INodeInfo_t_t", "std::vector< std::shared_ptr< ppc::protocol::INodeInfo > >::allocator_type *|std::allocator< std::shared_ptr< ppc::protocol::INodeInfo > > *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_std__allocatorT_std__string_t = {"_p_std__allocatorT_std__string_t", "std::vector< std::string >::allocator_type *|std::allocator< std::string > *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_std__allocatorT_unsigned_char_t = {"_p_std__allocatorT_unsigned_char_t", "std::vector< unsigned char >::allocator_type *|std::allocator< unsigned char > *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_std__exception = {"_p_std__exception", "std::exception *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_std__functionT_void_fF_t = {"_p_std__functionT_void_fF_t", "std::function< void () > *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_std__functionT_void_fstd__shared_ptrT_bcos__Error_tF_t = {"_p_std__functionT_void_fstd__shared_ptrT_bcos__Error_tF_t", "ppc::protocol::ReceiveMsgFunc *|std::function< void (std::shared_ptr< bcos::Error >) > *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_std__functionT_void_fstd__shared_ptrT_bcos__Error_t_std__shared_ptrT_ppc__protocol__Message_t_std__functionT_void_fstd__shared_ptrT_bcos__bytes_t_RRF_tF_t = {"_p_std__functionT_void_fstd__shared_ptrT_bcos__Error_t_std__shared_ptrT_ppc__protocol__Message_t_std__functionT_void_fstd__shared_ptrT_bcos__bytes_t_RRF_tF_t", "ppc::protocol::MessageCallback *|std::function< void (std::shared_ptr< bcos::Error >,std::shared_ptr< ppc::protocol::Message >,std::function< void (std::shared_ptr< bcos::bytes > &&) >) > *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_std__functionT_void_fstd__shared_ptrT_bcos__bytes_t_RRF_t = {"_p_std__functionT_void_fstd__shared_ptrT_bcos__bytes_t_RRF_t", "ppc::protocol::SendResponseFunction *|std::function< void (std::shared_ptr< bcos::bytes > &&) > *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_std__functionT_void_fstd__shared_ptrT_ppc__protocol__Message_tF_t = {"_p_std__functionT_void_fstd__shared_ptrT_ppc__protocol__Message_tF_t", "ppc::protocol::MessageDispatcherCallback *|std::function< void (std::shared_ptr< ppc::protocol::Message >) > *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_std__invalid_argument = {"_p_std__invalid_argument", "std::invalid_argument *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_std__shared_ptrT_bcos__Error_t = {"_p_std__shared_ptrT_bcos__Error_t", "std::shared_ptr< bcos::Error > *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_std__shared_ptrT_bcos__bytes_t = {"_p_std__shared_ptrT_bcos__bytes_t", "std::shared_ptr< bcos::bytes > *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_std__shared_ptrT_ppc__front__ErrorCallback_t = {"_p_std__shared_ptrT_ppc__front__ErrorCallback_t", "std::shared_ptr< ppc::front::ErrorCallback > *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_std__shared_ptrT_ppc__front__FrontConfigBuilder_t = {"_p_std__shared_ptrT_ppc__front__FrontConfigBuilder_t", "ppc::front::FrontConfigBuilder::Ptr *|std::shared_ptr< ppc::front::FrontConfigBuilder > *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_std__shared_ptrT_ppc__front__FrontConfig_t = {"_p_std__shared_ptrT_ppc__front__FrontConfig_t", "std::shared_ptr< ppc::front::FrontConfig > *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_std__shared_ptrT_ppc__front__GetPeersInfoHandler_t = {"_p_std__shared_ptrT_ppc__front__GetPeersInfoHandler_t", "std::shared_ptr< ppc::front::GetPeersInfoHandler > *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_std__shared_ptrT_ppc__front__IFrontClient_t = {"_p_std__shared_ptrT_ppc__front__IFrontClient_t", "std::shared_ptr< ppc::front::IFrontClient > *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_std__shared_ptrT_ppc__front__IFront_t = {"_p_std__shared_ptrT_ppc__front__IFront_t", "std::shared_ptr< ppc::front::IFront > *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_std__shared_ptrT_ppc__front__IMessageHandler_t = {"_p_std__shared_ptrT_ppc__front__IMessageHandler_t", "std::shared_ptr< ppc::front::IMessageHandler > *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_std__shared_ptrT_ppc__front__INodeDiscovery_t = {"_p_std__shared_ptrT_ppc__front__INodeDiscovery_t", "std::shared_ptr< ppc::front::INodeDiscovery > *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_std__shared_ptrT_ppc__front__MessageDispatcherHandler_t = {"_p_std__shared_ptrT_ppc__front__MessageDispatcherHandler_t", "std::shared_ptr< ppc::front::MessageDispatcherHandler > *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_std__shared_ptrT_ppc__gateway__IGateway_t = {"_p_std__shared_ptrT_ppc__gateway__IGateway_t", "std::shared_ptr< ppc::gateway::IGateway > *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_std__shared_ptrT_ppc__protocol__GrpcConfig_t = {"_p_std__shared_ptrT_ppc__protocol__GrpcConfig_t", "std::shared_ptr< ppc::protocol::GrpcConfig > *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_std__shared_ptrT_ppc__protocol__INodeInfo_t = {"_p_std__shared_ptrT_ppc__protocol__INodeInfo_t", "std::shared_ptr< ppc::protocol::INodeInfo > *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_std__shared_ptrT_ppc__protocol__MessageBuilder_t = {"_p_std__shared_ptrT_ppc__protocol__MessageBuilder_t", "std::shared_ptr< ppc::protocol::MessageBuilder > *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_std__shared_ptrT_ppc__protocol__MessageHeaderBuilder_t = {"_p_std__shared_ptrT_ppc__protocol__MessageHeaderBuilder_t", "std::shared_ptr< ppc::protocol::MessageHeaderBuilder > *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_std__shared_ptrT_ppc__protocol__MessageHeader_t = {"_p_std__shared_ptrT_ppc__protocol__MessageHeader_t", "std::shared_ptr< ppc::protocol::MessageHeader > *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_std__shared_ptrT_ppc__protocol__MessageOptionalHeaderBuilder_t = {"_p_std__shared_ptrT_ppc__protocol__MessageOptionalHeaderBuilder_t", "std::shared_ptr< ppc::protocol::MessageOptionalHeaderBuilder > *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_std__shared_ptrT_ppc__protocol__MessageOptionalHeader_t = {"_p_std__shared_ptrT_ppc__protocol__MessageOptionalHeader_t", "std::shared_ptr< ppc::protocol::MessageOptionalHeader > *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_std__shared_ptrT_ppc__protocol__MessagePayloadBuilder_t = {"_p_std__shared_ptrT_ppc__protocol__MessagePayloadBuilder_t", "std::shared_ptr< ppc::protocol::MessagePayloadBuilder > *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_std__shared_ptrT_ppc__protocol__MessagePayload_t = {"_p_std__shared_ptrT_ppc__protocol__MessagePayload_t", "std::shared_ptr< ppc::protocol::MessagePayload > *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_std__shared_ptrT_ppc__protocol__Message_t = {"_p_std__shared_ptrT_ppc__protocol__Message_t", "std::shared_ptr< ppc::protocol::Message > *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_std__shared_ptrT_ppc__sdk__Transport_t = {"_p_std__shared_ptrT_ppc__sdk__Transport_t", "std::shared_ptr< ppc::sdk::Transport > *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_std__string = {"_p_std__string", "std::string *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_std__string_view = {"_p_std__string_view", "std::string_view *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_std__vectorT_int8_t_t = {"_p_std__vectorT_int8_t_t", "std::vector< int8_t > *|std::vector< signed char,std::allocator< signed char > > *|std::vector< signed char > *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_std__vectorT_std__shared_ptrT_ppc__protocol__INodeInfo_t_t = {"_p_std__vectorT_std__shared_ptrT_ppc__protocol__INodeInfo_t_t", "std::vector< std::shared_ptr< ppc::protocol::INodeInfo >,std::allocator< std::shared_ptr< ppc::protocol::INodeInfo > > > *|std::vector< std::shared_ptr< ppc::protocol::INodeInfo > > *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_std__vectorT_std__string_t = {"_p_std__vectorT_std__string_t", "std::vector< std::string,std::allocator< std::string > > *|std::vector< std::string > *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_std__vectorT_uint8_t_t = {"_p_std__vectorT_uint8_t_t", "bcos::bytes *|std::vector< uint8_t > *|std::vector< unsigned char,std::allocator< unsigned char > > *|std::vector< unsigned char > *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_swig__SwigPyIterator = {"_p_swig__SwigPyIterator", "swig::SwigPyIterator *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_unsigned_char = {"_p_unsigned_char", "bcos::byte *|uint8_t *|uint_fast8_t *|uint_least8_t *|unsigned char *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_unsigned_int = {"_p_unsigned_int", "uint32_t *|uint_fast16_t *|uint_fast32_t *|uint_least32_t *|uintptr_t *|unsigned int *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_unsigned_long_long = {"_p_unsigned_long_long", "uint64_t *|uint_fast64_t *|uint_least64_t *|uintmax_t *|unsigned long long *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_unsigned_short = {"_p_unsigned_short", "uint16_t *|uint_least16_t *|unsigned short *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_value_type = {"_p_value_type", "value_type *", 0, 0, (void*)0, 0}; + +static swig_type_info *swig_type_initial[] = { + &_swigt__p_ConstPtr, + &_swigt__p_InputBuffer, + &_swigt__p_OutputBuffer, + &_swigt__p_PrevStdError, + &_swigt__p_Ptr, + &_swigt__p_UniqueConstPtr, + &_swigt__p_UniquePtr, + &_swigt__p_allocator_type, + &_swigt__p_bcos__Error, + &_swigt__p_bcos__bytesConstRef, + &_swigt__p_char, + &_swigt__p_difference_type, + &_swigt__p_int, + &_swigt__p_long_long, + &_swigt__p_p_PyObject, + &_swigt__p_ppc__front__ErrorCallback, + &_swigt__p_ppc__front__FrontConfig, + &_swigt__p_ppc__front__FrontConfigBuilder, + &_swigt__p_ppc__front__GetPeersInfoHandler, + &_swigt__p_ppc__front__IFront, + &_swigt__p_ppc__front__IFrontBuilder, + &_swigt__p_ppc__front__IFrontClient, + &_swigt__p_ppc__front__IMessageHandler, + &_swigt__p_ppc__front__INodeDiscovery, + &_swigt__p_ppc__front__MessageDispatcherHandler, + &_swigt__p_ppc__front__SendResponseHandler, + &_swigt__p_ppc__gateway__IGateway__Ptr, + &_swigt__p_ppc__protocol__EndPoint, + &_swigt__p_ppc__protocol__GrpcConfig, + &_swigt__p_ppc__protocol__GrpcServerConfig, + &_swigt__p_ppc__protocol__INodeInfo, + &_swigt__p_ppc__protocol__Message, + &_swigt__p_ppc__protocol__MessageBuilder, + &_swigt__p_ppc__protocol__MessageHeader, + &_swigt__p_ppc__protocol__MessageHeaderBuilder, + &_swigt__p_ppc__protocol__MessageOptionalHeader, + &_swigt__p_ppc__protocol__MessageOptionalHeaderBuilder, + &_swigt__p_ppc__protocol__MessagePayload, + &_swigt__p_ppc__protocol__MessagePayloadBuilder, + &_swigt__p_ppc__protocol__RouteType, + &_swigt__p_ppc__sdk__Transport, + &_swigt__p_ppc__sdk__TransportBuilder, + &_swigt__p_short, + &_swigt__p_signed_char, + &_swigt__p_size_type, + &_swigt__p_std__allocatorT_signed_char_t, + &_swigt__p_std__allocatorT_std__shared_ptrT_ppc__protocol__INodeInfo_t_t, + &_swigt__p_std__allocatorT_std__string_t, + &_swigt__p_std__allocatorT_unsigned_char_t, + &_swigt__p_std__exception, + &_swigt__p_std__functionT_void_fF_t, + &_swigt__p_std__functionT_void_fstd__shared_ptrT_bcos__Error_tF_t, + &_swigt__p_std__functionT_void_fstd__shared_ptrT_bcos__Error_t_std__shared_ptrT_ppc__protocol__Message_t_std__functionT_void_fstd__shared_ptrT_bcos__bytes_t_RRF_tF_t, + &_swigt__p_std__functionT_void_fstd__shared_ptrT_bcos__bytes_t_RRF_t, + &_swigt__p_std__functionT_void_fstd__shared_ptrT_ppc__protocol__Message_tF_t, + &_swigt__p_std__invalid_argument, + &_swigt__p_std__shared_ptrT_bcos__Error_t, + &_swigt__p_std__shared_ptrT_bcos__bytes_t, + &_swigt__p_std__shared_ptrT_ppc__front__ErrorCallback_t, + &_swigt__p_std__shared_ptrT_ppc__front__FrontConfigBuilder_t, + &_swigt__p_std__shared_ptrT_ppc__front__FrontConfig_t, + &_swigt__p_std__shared_ptrT_ppc__front__GetPeersInfoHandler_t, + &_swigt__p_std__shared_ptrT_ppc__front__IFrontClient_t, + &_swigt__p_std__shared_ptrT_ppc__front__IFront_t, + &_swigt__p_std__shared_ptrT_ppc__front__IMessageHandler_t, + &_swigt__p_std__shared_ptrT_ppc__front__INodeDiscovery_t, + &_swigt__p_std__shared_ptrT_ppc__front__MessageDispatcherHandler_t, + &_swigt__p_std__shared_ptrT_ppc__gateway__IGateway_t, + &_swigt__p_std__shared_ptrT_ppc__protocol__GrpcConfig_t, + &_swigt__p_std__shared_ptrT_ppc__protocol__INodeInfo_t, + &_swigt__p_std__shared_ptrT_ppc__protocol__MessageBuilder_t, + &_swigt__p_std__shared_ptrT_ppc__protocol__MessageHeaderBuilder_t, + &_swigt__p_std__shared_ptrT_ppc__protocol__MessageHeader_t, + &_swigt__p_std__shared_ptrT_ppc__protocol__MessageOptionalHeaderBuilder_t, + &_swigt__p_std__shared_ptrT_ppc__protocol__MessageOptionalHeader_t, + &_swigt__p_std__shared_ptrT_ppc__protocol__MessagePayloadBuilder_t, + &_swigt__p_std__shared_ptrT_ppc__protocol__MessagePayload_t, + &_swigt__p_std__shared_ptrT_ppc__protocol__Message_t, + &_swigt__p_std__shared_ptrT_ppc__sdk__Transport_t, + &_swigt__p_std__string, + &_swigt__p_std__string_view, + &_swigt__p_std__vectorT_int8_t_t, + &_swigt__p_std__vectorT_std__shared_ptrT_ppc__protocol__INodeInfo_t_t, + &_swigt__p_std__vectorT_std__string_t, + &_swigt__p_std__vectorT_uint8_t_t, + &_swigt__p_swig__SwigPyIterator, + &_swigt__p_unsigned_char, + &_swigt__p_unsigned_int, + &_swigt__p_unsigned_long_long, + &_swigt__p_unsigned_short, + &_swigt__p_value_type, +}; + +static swig_cast_info _swigc__p_ConstPtr[] = { {&_swigt__p_ConstPtr, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_InputBuffer[] = { {&_swigt__p_InputBuffer, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_OutputBuffer[] = { {&_swigt__p_OutputBuffer, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_PrevStdError[] = { {&_swigt__p_PrevStdError, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_Ptr[] = { {&_swigt__p_Ptr, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_UniqueConstPtr[] = { {&_swigt__p_UniqueConstPtr, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_UniquePtr[] = { {&_swigt__p_UniquePtr, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_allocator_type[] = { {&_swigt__p_allocator_type, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_bcos__Error[] = { {&_swigt__p_bcos__Error, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_bcos__bytesConstRef[] = { {&_swigt__p_bcos__bytesConstRef, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_char[] = { {&_swigt__p_char, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_difference_type[] = { {&_swigt__p_difference_type, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_int[] = { {&_swigt__p_int, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_long_long[] = { {&_swigt__p_long_long, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_p_PyObject[] = { {&_swigt__p_p_PyObject, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_ppc__front__ErrorCallback[] = { {&_swigt__p_ppc__front__ErrorCallback, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_ppc__front__FrontConfig[] = { {&_swigt__p_ppc__front__FrontConfig, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_ppc__front__FrontConfigBuilder[] = { {&_swigt__p_ppc__front__FrontConfigBuilder, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_ppc__front__GetPeersInfoHandler[] = { {&_swigt__p_ppc__front__GetPeersInfoHandler, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_ppc__front__IFront[] = { {&_swigt__p_ppc__front__IFront, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_ppc__front__IFrontBuilder[] = { {&_swigt__p_ppc__front__IFrontBuilder, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_ppc__front__IFrontClient[] = { {&_swigt__p_ppc__front__IFrontClient, 0, 0, 0}, {&_swigt__p_ppc__front__IFront, _p_ppc__front__IFrontTo_p_ppc__front__IFrontClient, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_ppc__front__IMessageHandler[] = { {&_swigt__p_ppc__front__IMessageHandler, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_ppc__front__INodeDiscovery[] = { {&_swigt__p_ppc__front__INodeDiscovery, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_ppc__front__MessageDispatcherHandler[] = { {&_swigt__p_ppc__front__MessageDispatcherHandler, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_ppc__front__SendResponseHandler[] = { {&_swigt__p_ppc__front__SendResponseHandler, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_ppc__gateway__IGateway__Ptr[] = { {&_swigt__p_ppc__gateway__IGateway__Ptr, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_ppc__protocol__EndPoint[] = { {&_swigt__p_ppc__protocol__EndPoint, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_ppc__protocol__GrpcConfig[] = { {&_swigt__p_ppc__protocol__GrpcConfig, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_ppc__protocol__GrpcServerConfig[] = { {&_swigt__p_ppc__protocol__GrpcServerConfig, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_ppc__protocol__INodeInfo[] = { {&_swigt__p_ppc__protocol__INodeInfo, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_ppc__protocol__Message[] = { {&_swigt__p_ppc__protocol__Message, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_ppc__protocol__MessageBuilder[] = { {&_swigt__p_ppc__protocol__MessageBuilder, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_ppc__protocol__MessageHeader[] = { {&_swigt__p_ppc__protocol__MessageHeader, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_ppc__protocol__MessageHeaderBuilder[] = { {&_swigt__p_ppc__protocol__MessageHeaderBuilder, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_ppc__protocol__MessageOptionalHeader[] = { {&_swigt__p_ppc__protocol__MessageOptionalHeader, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_ppc__protocol__MessageOptionalHeaderBuilder[] = { {&_swigt__p_ppc__protocol__MessageOptionalHeaderBuilder, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_ppc__protocol__MessagePayload[] = { {&_swigt__p_ppc__protocol__MessagePayload, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_ppc__protocol__MessagePayloadBuilder[] = { {&_swigt__p_ppc__protocol__MessagePayloadBuilder, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_ppc__protocol__RouteType[] = { {&_swigt__p_ppc__protocol__RouteType, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_ppc__sdk__Transport[] = { {&_swigt__p_ppc__sdk__Transport, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_ppc__sdk__TransportBuilder[] = { {&_swigt__p_ppc__sdk__TransportBuilder, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_short[] = { {&_swigt__p_short, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_signed_char[] = { {&_swigt__p_signed_char, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_size_type[] = { {&_swigt__p_size_type, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_std__allocatorT_signed_char_t[] = { {&_swigt__p_std__allocatorT_signed_char_t, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_std__allocatorT_std__shared_ptrT_ppc__protocol__INodeInfo_t_t[] = { {&_swigt__p_std__allocatorT_std__shared_ptrT_ppc__protocol__INodeInfo_t_t, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_std__allocatorT_std__string_t[] = { {&_swigt__p_std__allocatorT_std__string_t, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_std__allocatorT_unsigned_char_t[] = { {&_swigt__p_std__allocatorT_unsigned_char_t, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_std__exception[] = { {&_swigt__p_std__exception, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_std__functionT_void_fF_t[] = { {&_swigt__p_std__functionT_void_fF_t, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_std__functionT_void_fstd__shared_ptrT_bcos__Error_tF_t[] = { {&_swigt__p_std__functionT_void_fstd__shared_ptrT_bcos__Error_tF_t, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_std__functionT_void_fstd__shared_ptrT_bcos__Error_t_std__shared_ptrT_ppc__protocol__Message_t_std__functionT_void_fstd__shared_ptrT_bcos__bytes_t_RRF_tF_t[] = { {&_swigt__p_std__functionT_void_fstd__shared_ptrT_bcos__Error_t_std__shared_ptrT_ppc__protocol__Message_t_std__functionT_void_fstd__shared_ptrT_bcos__bytes_t_RRF_tF_t, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_std__functionT_void_fstd__shared_ptrT_bcos__bytes_t_RRF_t[] = { {&_swigt__p_std__functionT_void_fstd__shared_ptrT_bcos__bytes_t_RRF_t, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_std__functionT_void_fstd__shared_ptrT_ppc__protocol__Message_tF_t[] = { {&_swigt__p_std__functionT_void_fstd__shared_ptrT_ppc__protocol__Message_tF_t, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_std__invalid_argument[] = { {&_swigt__p_std__invalid_argument, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_std__shared_ptrT_bcos__Error_t[] = { {&_swigt__p_std__shared_ptrT_bcos__Error_t, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_std__shared_ptrT_bcos__bytes_t[] = { {&_swigt__p_std__shared_ptrT_bcos__bytes_t, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_std__shared_ptrT_ppc__front__ErrorCallback_t[] = { {&_swigt__p_std__shared_ptrT_ppc__front__ErrorCallback_t, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_std__shared_ptrT_ppc__front__FrontConfigBuilder_t[] = { {&_swigt__p_std__shared_ptrT_ppc__front__FrontConfigBuilder_t, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_std__shared_ptrT_ppc__front__FrontConfig_t[] = { {&_swigt__p_std__shared_ptrT_ppc__front__FrontConfig_t, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_std__shared_ptrT_ppc__front__GetPeersInfoHandler_t[] = { {&_swigt__p_std__shared_ptrT_ppc__front__GetPeersInfoHandler_t, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_std__shared_ptrT_ppc__front__IFrontClient_t[] = { {&_swigt__p_std__shared_ptrT_ppc__front__IFrontClient_t, 0, 0, 0}, {&_swigt__p_std__shared_ptrT_ppc__front__IFront_t, _p_std__shared_ptrT_ppc__front__IFront_tTo_p_std__shared_ptrT_ppc__front__IFrontClient_t, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_std__shared_ptrT_ppc__front__IFront_t[] = { {&_swigt__p_std__shared_ptrT_ppc__front__IFront_t, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_std__shared_ptrT_ppc__front__IMessageHandler_t[] = { {&_swigt__p_std__shared_ptrT_ppc__front__IMessageHandler_t, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_std__shared_ptrT_ppc__front__INodeDiscovery_t[] = { {&_swigt__p_std__shared_ptrT_ppc__front__INodeDiscovery_t, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_std__shared_ptrT_ppc__front__MessageDispatcherHandler_t[] = { {&_swigt__p_std__shared_ptrT_ppc__front__MessageDispatcherHandler_t, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_std__shared_ptrT_ppc__gateway__IGateway_t[] = { {&_swigt__p_std__shared_ptrT_ppc__gateway__IGateway_t, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_std__shared_ptrT_ppc__protocol__GrpcConfig_t[] = { {&_swigt__p_std__shared_ptrT_ppc__protocol__GrpcConfig_t, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_std__shared_ptrT_ppc__protocol__INodeInfo_t[] = { {&_swigt__p_std__shared_ptrT_ppc__protocol__INodeInfo_t, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_std__shared_ptrT_ppc__protocol__MessageBuilder_t[] = { {&_swigt__p_std__shared_ptrT_ppc__protocol__MessageBuilder_t, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_std__shared_ptrT_ppc__protocol__MessageHeaderBuilder_t[] = { {&_swigt__p_std__shared_ptrT_ppc__protocol__MessageHeaderBuilder_t, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_std__shared_ptrT_ppc__protocol__MessageHeader_t[] = { {&_swigt__p_std__shared_ptrT_ppc__protocol__MessageHeader_t, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_std__shared_ptrT_ppc__protocol__MessageOptionalHeaderBuilder_t[] = { {&_swigt__p_std__shared_ptrT_ppc__protocol__MessageOptionalHeaderBuilder_t, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_std__shared_ptrT_ppc__protocol__MessageOptionalHeader_t[] = { {&_swigt__p_std__shared_ptrT_ppc__protocol__MessageOptionalHeader_t, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_std__shared_ptrT_ppc__protocol__MessagePayloadBuilder_t[] = { {&_swigt__p_std__shared_ptrT_ppc__protocol__MessagePayloadBuilder_t, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_std__shared_ptrT_ppc__protocol__MessagePayload_t[] = { {&_swigt__p_std__shared_ptrT_ppc__protocol__MessagePayload_t, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_std__shared_ptrT_ppc__protocol__Message_t[] = { {&_swigt__p_std__shared_ptrT_ppc__protocol__Message_t, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_std__shared_ptrT_ppc__sdk__Transport_t[] = { {&_swigt__p_std__shared_ptrT_ppc__sdk__Transport_t, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_std__string[] = { {&_swigt__p_std__string, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_std__string_view[] = { {&_swigt__p_std__string_view, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_std__vectorT_int8_t_t[] = { {&_swigt__p_std__vectorT_int8_t_t, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_std__vectorT_std__shared_ptrT_ppc__protocol__INodeInfo_t_t[] = { {&_swigt__p_std__vectorT_std__shared_ptrT_ppc__protocol__INodeInfo_t_t, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_std__vectorT_std__string_t[] = { {&_swigt__p_std__vectorT_std__string_t, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_std__vectorT_uint8_t_t[] = { {&_swigt__p_std__vectorT_uint8_t_t, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_swig__SwigPyIterator[] = { {&_swigt__p_swig__SwigPyIterator, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_unsigned_char[] = { {&_swigt__p_unsigned_char, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_unsigned_int[] = { {&_swigt__p_unsigned_int, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_unsigned_long_long[] = { {&_swigt__p_unsigned_long_long, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_unsigned_short[] = { {&_swigt__p_unsigned_short, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_value_type[] = { {&_swigt__p_value_type, 0, 0, 0},{0, 0, 0, 0}}; + +static swig_cast_info *swig_cast_initial[] = { + _swigc__p_ConstPtr, + _swigc__p_InputBuffer, + _swigc__p_OutputBuffer, + _swigc__p_PrevStdError, + _swigc__p_Ptr, + _swigc__p_UniqueConstPtr, + _swigc__p_UniquePtr, + _swigc__p_allocator_type, + _swigc__p_bcos__Error, + _swigc__p_bcos__bytesConstRef, + _swigc__p_char, + _swigc__p_difference_type, + _swigc__p_int, + _swigc__p_long_long, + _swigc__p_p_PyObject, + _swigc__p_ppc__front__ErrorCallback, + _swigc__p_ppc__front__FrontConfig, + _swigc__p_ppc__front__FrontConfigBuilder, + _swigc__p_ppc__front__GetPeersInfoHandler, + _swigc__p_ppc__front__IFront, + _swigc__p_ppc__front__IFrontBuilder, + _swigc__p_ppc__front__IFrontClient, + _swigc__p_ppc__front__IMessageHandler, + _swigc__p_ppc__front__INodeDiscovery, + _swigc__p_ppc__front__MessageDispatcherHandler, + _swigc__p_ppc__front__SendResponseHandler, + _swigc__p_ppc__gateway__IGateway__Ptr, + _swigc__p_ppc__protocol__EndPoint, + _swigc__p_ppc__protocol__GrpcConfig, + _swigc__p_ppc__protocol__GrpcServerConfig, + _swigc__p_ppc__protocol__INodeInfo, + _swigc__p_ppc__protocol__Message, + _swigc__p_ppc__protocol__MessageBuilder, + _swigc__p_ppc__protocol__MessageHeader, + _swigc__p_ppc__protocol__MessageHeaderBuilder, + _swigc__p_ppc__protocol__MessageOptionalHeader, + _swigc__p_ppc__protocol__MessageOptionalHeaderBuilder, + _swigc__p_ppc__protocol__MessagePayload, + _swigc__p_ppc__protocol__MessagePayloadBuilder, + _swigc__p_ppc__protocol__RouteType, + _swigc__p_ppc__sdk__Transport, + _swigc__p_ppc__sdk__TransportBuilder, + _swigc__p_short, + _swigc__p_signed_char, + _swigc__p_size_type, + _swigc__p_std__allocatorT_signed_char_t, + _swigc__p_std__allocatorT_std__shared_ptrT_ppc__protocol__INodeInfo_t_t, + _swigc__p_std__allocatorT_std__string_t, + _swigc__p_std__allocatorT_unsigned_char_t, + _swigc__p_std__exception, + _swigc__p_std__functionT_void_fF_t, + _swigc__p_std__functionT_void_fstd__shared_ptrT_bcos__Error_tF_t, + _swigc__p_std__functionT_void_fstd__shared_ptrT_bcos__Error_t_std__shared_ptrT_ppc__protocol__Message_t_std__functionT_void_fstd__shared_ptrT_bcos__bytes_t_RRF_tF_t, + _swigc__p_std__functionT_void_fstd__shared_ptrT_bcos__bytes_t_RRF_t, + _swigc__p_std__functionT_void_fstd__shared_ptrT_ppc__protocol__Message_tF_t, + _swigc__p_std__invalid_argument, + _swigc__p_std__shared_ptrT_bcos__Error_t, + _swigc__p_std__shared_ptrT_bcos__bytes_t, + _swigc__p_std__shared_ptrT_ppc__front__ErrorCallback_t, + _swigc__p_std__shared_ptrT_ppc__front__FrontConfigBuilder_t, + _swigc__p_std__shared_ptrT_ppc__front__FrontConfig_t, + _swigc__p_std__shared_ptrT_ppc__front__GetPeersInfoHandler_t, + _swigc__p_std__shared_ptrT_ppc__front__IFrontClient_t, + _swigc__p_std__shared_ptrT_ppc__front__IFront_t, + _swigc__p_std__shared_ptrT_ppc__front__IMessageHandler_t, + _swigc__p_std__shared_ptrT_ppc__front__INodeDiscovery_t, + _swigc__p_std__shared_ptrT_ppc__front__MessageDispatcherHandler_t, + _swigc__p_std__shared_ptrT_ppc__gateway__IGateway_t, + _swigc__p_std__shared_ptrT_ppc__protocol__GrpcConfig_t, + _swigc__p_std__shared_ptrT_ppc__protocol__INodeInfo_t, + _swigc__p_std__shared_ptrT_ppc__protocol__MessageBuilder_t, + _swigc__p_std__shared_ptrT_ppc__protocol__MessageHeaderBuilder_t, + _swigc__p_std__shared_ptrT_ppc__protocol__MessageHeader_t, + _swigc__p_std__shared_ptrT_ppc__protocol__MessageOptionalHeaderBuilder_t, + _swigc__p_std__shared_ptrT_ppc__protocol__MessageOptionalHeader_t, + _swigc__p_std__shared_ptrT_ppc__protocol__MessagePayloadBuilder_t, + _swigc__p_std__shared_ptrT_ppc__protocol__MessagePayload_t, + _swigc__p_std__shared_ptrT_ppc__protocol__Message_t, + _swigc__p_std__shared_ptrT_ppc__sdk__Transport_t, + _swigc__p_std__string, + _swigc__p_std__string_view, + _swigc__p_std__vectorT_int8_t_t, + _swigc__p_std__vectorT_std__shared_ptrT_ppc__protocol__INodeInfo_t_t, + _swigc__p_std__vectorT_std__string_t, + _swigc__p_std__vectorT_uint8_t_t, + _swigc__p_swig__SwigPyIterator, + _swigc__p_unsigned_char, + _swigc__p_unsigned_int, + _swigc__p_unsigned_long_long, + _swigc__p_unsigned_short, + _swigc__p_value_type, +}; + + +/* -------- TYPE CONVERSION AND EQUIVALENCE RULES (END) -------- */ + +static swig_const_info swig_const_table[] = { +{0, 0, 0, 0.0, 0, 0}}; + +#ifdef __cplusplus +} +#endif +/* ----------------------------------------------------------------------------- + * Type initialization: + * This problem is tough by the requirement that no dynamic + * memory is used. Also, since swig_type_info structures store pointers to + * swig_cast_info structures and swig_cast_info structures store pointers back + * to swig_type_info structures, we need some lookup code at initialization. + * The idea is that swig generates all the structures that are needed. + * The runtime then collects these partially filled structures. + * The SWIG_InitializeModule function takes these initial arrays out of + * swig_module, and does all the lookup, filling in the swig_module.types + * array with the correct data and linking the correct swig_cast_info + * structures together. + * + * The generated swig_type_info structures are assigned statically to an initial + * array. We just loop through that array, and handle each type individually. + * First we lookup if this type has been already loaded, and if so, use the + * loaded structure instead of the generated one. Then we have to fill in the + * cast linked list. The cast data is initially stored in something like a + * two-dimensional array. Each row corresponds to a type (there are the same + * number of rows as there are in the swig_type_initial array). Each entry in + * a column is one of the swig_cast_info structures for that type. + * The cast_initial array is actually an array of arrays, because each row has + * a variable number of columns. So to actually build the cast linked list, + * we find the array of casts associated with the type, and loop through it + * adding the casts to the list. The one last trick we need to do is making + * sure the type pointer in the swig_cast_info struct is correct. + * + * First off, we lookup the cast->type name to see if it is already loaded. + * There are three cases to handle: + * 1) If the cast->type has already been loaded AND the type we are adding + * casting info to has not been loaded (it is in this module), THEN we + * replace the cast->type pointer with the type pointer that has already + * been loaded. + * 2) If BOTH types (the one we are adding casting info to, and the + * cast->type) are loaded, THEN the cast info has already been loaded by + * the previous module so we just ignore it. + * 3) Finally, if cast->type has not already been loaded, then we add that + * swig_cast_info to the linked list (because the cast->type) pointer will + * be correct. + * ----------------------------------------------------------------------------- */ + +#ifdef __cplusplus +extern "C" { +#if 0 +} /* c-mode */ +#endif +#endif + +#if 0 +#define SWIGRUNTIME_DEBUG +#endif + +#ifndef SWIG_INIT_CLIENT_DATA_TYPE +#define SWIG_INIT_CLIENT_DATA_TYPE void * +#endif + +SWIGRUNTIME void +SWIG_InitializeModule(SWIG_INIT_CLIENT_DATA_TYPE clientdata) { + size_t i; + swig_module_info *module_head, *iter; + int init; + + /* check to see if the circular list has been setup, if not, set it up */ + if (swig_module.next==0) { + /* Initialize the swig_module */ + swig_module.type_initial = swig_type_initial; + swig_module.cast_initial = swig_cast_initial; + swig_module.next = &swig_module; + init = 1; + } else { + init = 0; + } + + /* Try and load any already created modules */ + module_head = SWIG_GetModule(clientdata); + if (!module_head) { + /* This is the first module loaded for this interpreter */ + /* so set the swig module into the interpreter */ + SWIG_SetModule(clientdata, &swig_module); + } else { + /* the interpreter has loaded a SWIG module, but has it loaded this one? */ + iter=module_head; + do { + if (iter==&swig_module) { + /* Our module is already in the list, so there's nothing more to do. */ + return; + } + iter=iter->next; + } while (iter!= module_head); + + /* otherwise we must add our module into the list */ + swig_module.next = module_head->next; + module_head->next = &swig_module; + } + + /* When multiple interpreters are used, a module could have already been initialized in + a different interpreter, but not yet have a pointer in this interpreter. + In this case, we do not want to continue adding types... everything should be + set up already */ + if (init == 0) return; + + /* Now work on filling in swig_module.types */ +#ifdef SWIGRUNTIME_DEBUG + printf("SWIG_InitializeModule: size %lu\n", (unsigned long)swig_module.size); +#endif + for (i = 0; i < swig_module.size; ++i) { + swig_type_info *type = 0; + swig_type_info *ret; + swig_cast_info *cast; + +#ifdef SWIGRUNTIME_DEBUG + printf("SWIG_InitializeModule: type %lu %s\n", (unsigned long)i, swig_module.type_initial[i]->name); +#endif + + /* if there is another module already loaded */ + if (swig_module.next != &swig_module) { + type = SWIG_MangledTypeQueryModule(swig_module.next, &swig_module, swig_module.type_initial[i]->name); + } + if (type) { + /* Overwrite clientdata field */ +#ifdef SWIGRUNTIME_DEBUG + printf("SWIG_InitializeModule: found type %s\n", type->name); +#endif + if (swig_module.type_initial[i]->clientdata) { + type->clientdata = swig_module.type_initial[i]->clientdata; +#ifdef SWIGRUNTIME_DEBUG + printf("SWIG_InitializeModule: found and overwrite type %s \n", type->name); +#endif + } + } else { + type = swig_module.type_initial[i]; + } + + /* Insert casting types */ + cast = swig_module.cast_initial[i]; + while (cast->type) { + /* Don't need to add information already in the list */ + ret = 0; +#ifdef SWIGRUNTIME_DEBUG + printf("SWIG_InitializeModule: look cast %s\n", cast->type->name); +#endif + if (swig_module.next != &swig_module) { + ret = SWIG_MangledTypeQueryModule(swig_module.next, &swig_module, cast->type->name); +#ifdef SWIGRUNTIME_DEBUG + if (ret) printf("SWIG_InitializeModule: found cast %s\n", ret->name); +#endif + } + if (ret) { + if (type == swig_module.type_initial[i]) { +#ifdef SWIGRUNTIME_DEBUG + printf("SWIG_InitializeModule: skip old type %s\n", ret->name); +#endif + cast->type = ret; + ret = 0; + } else { + /* Check for casting already in the list */ + swig_cast_info *ocast = SWIG_TypeCheck(ret->name, type); +#ifdef SWIGRUNTIME_DEBUG + if (ocast) printf("SWIG_InitializeModule: skip old cast %s\n", ret->name); +#endif + if (!ocast) ret = 0; + } + } + + if (!ret) { +#ifdef SWIGRUNTIME_DEBUG + printf("SWIG_InitializeModule: adding cast %s\n", cast->type->name); +#endif + if (type->cast) { + type->cast->prev = cast; + cast->next = type->cast; + } + type->cast = cast; + } + cast++; + } + /* Set entry in modules->types array equal to the type */ + swig_module.types[i] = type; + } + swig_module.types[i] = 0; + +#ifdef SWIGRUNTIME_DEBUG + printf("**** SWIG_InitializeModule: Cast List ******\n"); + for (i = 0; i < swig_module.size; ++i) { + int j = 0; + swig_cast_info *cast = swig_module.cast_initial[i]; + printf("SWIG_InitializeModule: type %lu %s\n", (unsigned long)i, swig_module.type_initial[i]->name); + while (cast->type) { + printf("SWIG_InitializeModule: cast type %s\n", cast->type->name); + cast++; + ++j; + } + printf("---- Total casts: %d\n",j); + } + printf("**** SWIG_InitializeModule: Cast List ******\n"); +#endif +} + +/* This function will propagate the clientdata field of type to +* any new swig_type_info structures that have been added into the list +* of equivalent types. It is like calling +* SWIG_TypeClientData(type, clientdata) a second time. +*/ +SWIGRUNTIME void +SWIG_PropagateClientData(void) { + size_t i; + swig_cast_info *equiv; + static int init_run = 0; + + if (init_run) return; + init_run = 1; + + for (i = 0; i < swig_module.size; i++) { + if (swig_module.types[i]->clientdata) { + equiv = swig_module.types[i]->cast; + while (equiv) { + if (!equiv->converter) { + if (equiv->type && !equiv->type->clientdata) + SWIG_TypeClientData(equiv->type, swig_module.types[i]->clientdata); + } + equiv = equiv->next; + } + } + } +} + +#ifdef __cplusplus +#if 0 +{ + /* c-mode */ +#endif +} +#endif + + + +#ifdef __cplusplus +extern "C" { +#endif + + /* ----------------------------------------------------------------------------- + * constants/methods manipulation + * ----------------------------------------------------------------------------- */ + + /* Install Constants */ + SWIGINTERN void + SWIG_Python_InstallConstants(PyObject *d, swig_const_info constants[]) { + PyObject *obj = 0; + size_t i; + for (i = 0; constants[i].type; ++i) { + switch(constants[i].type) { + case SWIG_PY_POINTER: + obj = SWIG_InternalNewPointerObj(constants[i].pvalue, *(constants[i]).ptype,0); + break; + case SWIG_PY_BINARY: + obj = SWIG_NewPackedObj(constants[i].pvalue, constants[i].lvalue, *(constants[i].ptype)); + break; + default: + obj = 0; + break; + } + if (obj) { + PyDict_SetItemString(d, constants[i].name, obj); + Py_DECREF(obj); + } + } + } + + /* ----------------------------------------------------------------------------- + * Patch %callback methods' docstrings to hold the callback ptrs + * -----------------------------------------------------------------------------*/ + + SWIGINTERN void + SWIG_Python_FixMethods(PyMethodDef *methods, const swig_const_info *const_table, swig_type_info **types, swig_type_info **types_initial) { + size_t i; + for (i = 0; methods[i].ml_name; ++i) { + const char *c = methods[i].ml_doc; + if (!c) continue; + c = strstr(c, "swig_ptr: "); + if (c) { + int j; + const swig_const_info *ci = 0; + const char *name = c + 10; + for (j = 0; const_table[j].type; ++j) { + if (strncmp(const_table[j].name, name, + strlen(const_table[j].name)) == 0) { + ci = &(const_table[j]); + break; + } + } + if (ci) { + void *ptr = (ci->type == SWIG_PY_POINTER) ? ci->pvalue : 0; + if (ptr) { + size_t shift = (ci->ptype) - types; + swig_type_info *ty = types_initial[shift]; + size_t ldoc = (c - methods[i].ml_doc); + size_t lptr = strlen(ty->name)+2*sizeof(void*)+2; + char *ndoc = (char*)malloc(ldoc + lptr + 10); + if (ndoc) { + char *buff = ndoc; + memcpy(buff, methods[i].ml_doc, ldoc); + buff += ldoc; + memcpy(buff, "swig_ptr: ", 10); + buff += 10; + SWIG_PackVoidPtr(buff, ptr, ty->name, lptr); + methods[i].ml_doc = ndoc; + } + } + } + } + } + } + +#ifdef __cplusplus +} +#endif + + + + +/* -----------------------------------------------------------------------------* + * Partial Init method + * -----------------------------------------------------------------------------*/ + +#ifdef __cplusplus +extern "C" +#endif + +SWIGEXPORT +#if PY_VERSION_HEX >= 0x03000000 +PyObject* +#else +void +#endif +SWIG_init(void) { + PyObject *m, *d, *md, *globals; + +#if PY_VERSION_HEX >= 0x03000000 + static struct PyModuleDef SWIG_module = { + PyModuleDef_HEAD_INIT, + SWIG_name, + NULL, + -1, + SwigMethods, + NULL, + NULL, + NULL, + NULL + }; +#endif + +#if defined(SWIGPYTHON_BUILTIN) + static SwigPyClientData SwigPyObject_clientdata = { + 0, 0, 0, 0, 0, 0, 0 + }; + static PyGetSetDef this_getset_def = { + (char *)"this", &SwigPyBuiltin_ThisClosure, NULL, NULL, NULL + }; + static SwigPyGetSet thisown_getset_closure = { + SwigPyObject_own, + SwigPyObject_own + }; + static PyGetSetDef thisown_getset_def = { + (char *)"thisown", SwigPyBuiltin_GetterClosure, SwigPyBuiltin_SetterClosure, NULL, &thisown_getset_closure + }; + PyTypeObject *builtin_pytype; + int builtin_base_count; + swig_type_info *builtin_basetype; + PyObject *tuple; + PyGetSetDescrObject *static_getset; + PyTypeObject *metatype; + PyTypeObject *swigpyobject; + SwigPyClientData *cd; + PyObject *public_interface, *public_symbol; + PyObject *this_descr; + PyObject *thisown_descr; + PyObject *self = 0; + int i; + + (void)builtin_pytype; + (void)builtin_base_count; + (void)builtin_basetype; + (void)tuple; + (void)static_getset; + (void)self; + + /* Metaclass is used to implement static member variables */ + metatype = SwigPyObjectType(); + assert(metatype); +#endif + + (void)globals; + + /* Create singletons now to avoid potential deadlocks with multi-threaded usage after module initialization */ + SWIG_This(); + SWIG_Python_TypeCache(); + SwigPyPacked_type(); +#ifndef SWIGPYTHON_BUILTIN + SwigPyObject_type(); +#endif + + /* Fix SwigMethods to carry the callback ptrs when needed */ + SWIG_Python_FixMethods(SwigMethods, swig_const_table, swig_types, swig_type_initial); + +#if PY_VERSION_HEX >= 0x03000000 + m = PyModule_Create(&SWIG_module); +#else + m = Py_InitModule(SWIG_name, SwigMethods); +#endif + + md = d = PyModule_GetDict(m); + (void)md; + + SWIG_InitializeModule(0); + +#ifdef SWIGPYTHON_BUILTIN + swigpyobject = SwigPyObject_TypeOnce(); + + SwigPyObject_stype = SWIG_MangledTypeQuery("_p_SwigPyObject"); + assert(SwigPyObject_stype); + cd = (SwigPyClientData*) SwigPyObject_stype->clientdata; + if (!cd) { + SwigPyObject_stype->clientdata = &SwigPyObject_clientdata; + SwigPyObject_clientdata.pytype = swigpyobject; + } else if (swigpyobject->tp_basicsize != cd->pytype->tp_basicsize) { + PyErr_SetString(PyExc_RuntimeError, "Import error: attempted to load two incompatible swig-generated modules."); +# if PY_VERSION_HEX >= 0x03000000 + return NULL; +# else + return; +# endif + } + + /* All objects have a 'this' attribute */ + this_descr = PyDescr_NewGetSet(SwigPyObject_type(), &this_getset_def); + (void)this_descr; + + /* All objects have a 'thisown' attribute */ + thisown_descr = PyDescr_NewGetSet(SwigPyObject_type(), &thisown_getset_def); + (void)thisown_descr; + + public_interface = PyList_New(0); + public_symbol = 0; + (void)public_symbol; + + PyDict_SetItemString(md, "__all__", public_interface); + Py_DECREF(public_interface); + for (i = 0; SwigMethods[i].ml_name != NULL; ++i) + SwigPyBuiltin_AddPublicSymbol(public_interface, SwigMethods[i].ml_name); + for (i = 0; swig_const_table[i].name != 0; ++i) + SwigPyBuiltin_AddPublicSymbol(public_interface, swig_const_table[i].name); +#endif + + SWIG_InstallConstants(d,swig_const_table); + + SWIG_Python_SetConstant(d, "SHARED_PTR_DISOWN",SWIG_From_int(static_cast< int >(0))); + + // thread safe initialization + swig::container_owner_attribute(); + + SWIG_Python_SetConstant(d, "FrontMsgExtFlag_Response",SWIG_From_int(static_cast< int >(ppc::protocol::FrontMsgExtFlag::Response))); + SWIG_Python_SetConstant(d, "SDKMode_AIR",SWIG_From_int(static_cast< int >(ppc::sdk::SDKMode::AIR))); + SWIG_Python_SetConstant(d, "SDKMode_PRO",SWIG_From_int(static_cast< int >(ppc::sdk::SDKMode::PRO))); +#if PY_VERSION_HEX >= 0x03000000 + return m; +#else + return; +#endif +} + diff --git a/cpp/wedpr-transport/sdk-wrapper/python/src/wedpr_python_transportPYTHON_wrap.h b/cpp/wedpr-transport/sdk-wrapper/python/src/wedpr_python_transportPYTHON_wrap.h new file mode 100644 index 00000000..36d8b00b --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/python/src/wedpr_python_transportPYTHON_wrap.h @@ -0,0 +1,184 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (https://www.swig.org). + * Version 4.2.1 + * + * Do not make changes to this file unless you know what you are doing - modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +#ifndef SWIG_wedpr_python_transport_WRAP_H_ +#define SWIG_wedpr_python_transport_WRAP_H_ + +#include +#include + + +class SwigDirector_ErrorCallback : public ppc::front::ErrorCallback, public Swig::Director { + +public: + SwigDirector_ErrorCallback(PyObject *self); + virtual ~SwigDirector_ErrorCallback(); + virtual void onError(bcos::Error::Ptr error); + +/* Internal director utilities */ +public: + bool swig_get_inner(const char *swig_protected_method_name) const { + std::map::const_iterator iv = swig_inner.find(swig_protected_method_name); + return (iv != swig_inner.end() ? iv->second : false); + } + void swig_set_inner(const char *swig_protected_method_name, bool swig_val) const { + swig_inner[swig_protected_method_name] = swig_val; + } +private: + mutable std::map swig_inner; + +#if defined(SWIG_PYTHON_DIRECTOR_VTABLE) +/* VTable implementation */ + PyObject *swig_get_method(size_t method_index, const char *method_name) const { + PyObject *method = vtable[method_index]; + if (!method) { + swig::SwigVar_PyObject name = SWIG_Python_str_FromChar(method_name); + method = PyObject_GetAttr(swig_get_self(), name); + if (!method) { + std::string msg = "Method in class ErrorCallback doesn't exist, undefined "; + msg += method_name; + Swig::DirectorMethodException::raise(msg.c_str()); + } + vtable[method_index] = method; + } + return method; + } +private: + mutable swig::SwigVar_PyObject vtable[1]; +#endif + +}; + + +class SwigDirector_MessageDispatcherHandler : public ppc::front::MessageDispatcherHandler, public Swig::Director { + +public: + SwigDirector_MessageDispatcherHandler(PyObject *self); + virtual ~SwigDirector_MessageDispatcherHandler(); + virtual void onMessage(ppc::protocol::Message::Ptr msg); + +/* Internal director utilities */ +public: + bool swig_get_inner(const char *swig_protected_method_name) const { + std::map::const_iterator iv = swig_inner.find(swig_protected_method_name); + return (iv != swig_inner.end() ? iv->second : false); + } + void swig_set_inner(const char *swig_protected_method_name, bool swig_val) const { + swig_inner[swig_protected_method_name] = swig_val; + } +private: + mutable std::map swig_inner; + +#if defined(SWIG_PYTHON_DIRECTOR_VTABLE) +/* VTable implementation */ + PyObject *swig_get_method(size_t method_index, const char *method_name) const { + PyObject *method = vtable[method_index]; + if (!method) { + swig::SwigVar_PyObject name = SWIG_Python_str_FromChar(method_name); + method = PyObject_GetAttr(swig_get_self(), name); + if (!method) { + std::string msg = "Method in class MessageDispatcherHandler doesn't exist, undefined "; + msg += method_name; + Swig::DirectorMethodException::raise(msg.c_str()); + } + vtable[method_index] = method; + } + return method; + } +private: + mutable swig::SwigVar_PyObject vtable[1]; +#endif + +}; + + +class SwigDirector_IMessageHandler : public ppc::front::IMessageHandler, public Swig::Director { + +public: + SwigDirector_IMessageHandler(PyObject *self); + virtual ~SwigDirector_IMessageHandler(); + virtual void onMessage(bcos::Error::Ptr e,ppc::protocol::Message::Ptr msg,ppc::front::SendResponseHandler sendResponseHandler); + +/* Internal director utilities */ +public: + bool swig_get_inner(const char *swig_protected_method_name) const { + std::map::const_iterator iv = swig_inner.find(swig_protected_method_name); + return (iv != swig_inner.end() ? iv->second : false); + } + void swig_set_inner(const char *swig_protected_method_name, bool swig_val) const { + swig_inner[swig_protected_method_name] = swig_val; + } +private: + mutable std::map swig_inner; + +#if defined(SWIG_PYTHON_DIRECTOR_VTABLE) +/* VTable implementation */ + PyObject *swig_get_method(size_t method_index, const char *method_name) const { + PyObject *method = vtable[method_index]; + if (!method) { + swig::SwigVar_PyObject name = SWIG_Python_str_FromChar(method_name); + method = PyObject_GetAttr(swig_get_self(), name); + if (!method) { + std::string msg = "Method in class IMessageHandler doesn't exist, undefined "; + msg += method_name; + Swig::DirectorMethodException::raise(msg.c_str()); + } + vtable[method_index] = method; + } + return method; + } +private: + mutable swig::SwigVar_PyObject vtable[1]; +#endif + +}; + + +class SwigDirector_GetPeersInfoHandler : public ppc::front::GetPeersInfoHandler, public Swig::Director { + +public: + SwigDirector_GetPeersInfoHandler(PyObject *self); + virtual ~SwigDirector_GetPeersInfoHandler(); + virtual void onPeersInfo(bcos::Error::Ptr e,std::string const &peersInfo); + +/* Internal director utilities */ +public: + bool swig_get_inner(const char *swig_protected_method_name) const { + std::map::const_iterator iv = swig_inner.find(swig_protected_method_name); + return (iv != swig_inner.end() ? iv->second : false); + } + void swig_set_inner(const char *swig_protected_method_name, bool swig_val) const { + swig_inner[swig_protected_method_name] = swig_val; + } +private: + mutable std::map swig_inner; + +#if defined(SWIG_PYTHON_DIRECTOR_VTABLE) +/* VTable implementation */ + PyObject *swig_get_method(size_t method_index, const char *method_name) const { + PyObject *method = vtable[method_index]; + if (!method) { + swig::SwigVar_PyObject name = SWIG_Python_str_FromChar(method_name); + method = PyObject_GetAttr(swig_get_self(), name); + if (!method) { + std::string msg = "Method in class GetPeersInfoHandler doesn't exist, undefined "; + msg += method_name; + Swig::DirectorMethodException::raise(msg.c_str()); + } + vtable[method_index] = method; + } + return method; + } +private: + mutable swig::SwigVar_PyObject vtable[1]; +#endif + +}; + + +#endif diff --git a/cpp/wedpr-transport/sdk-wrapper/python/swig/wedpr_python_transport.i b/cpp/wedpr-transport/sdk-wrapper/python/swig/wedpr_python_transport.i new file mode 100644 index 00000000..83be7ca0 --- /dev/null +++ b/cpp/wedpr-transport/sdk-wrapper/python/swig/wedpr_python_transport.i @@ -0,0 +1,230 @@ +%define MODULEIMPORT +" +# Import the low-level C/C++ module +from wedpr_python_gateway_sdk.libs import _wedpr_python_transport +" +%enddef + +%module(moduleimport=MODULEIMPORT) wedpr_python_transport +%module(directors="1") wedpr_python_transport + +%include "stdint.i" +%include "cpointer.i" +%include "std_vector.i" +%include "std_string.i" +%include "std_shared_ptr.i" +%include "typemaps.i" + +// shared_ptr definition +%shared_ptr(ppc::front::FrontConfig); +%shared_ptr(ppc::front::IFront); +%shared_ptr(ppc::front::INodeDiscovery); +%shared_ptr(ppc::protocol::INodeInfo); +%shared_ptr(ppc::front::IFrontClient); +// the callbacks +%shared_ptr(ppc::front::ErrorCallback); +%shared_ptr(ppc::front::MessageDispatcherHandler); +%shared_ptr(ppc::front::IMessageHandler); +%shared_ptr(ppc::front::GetPeersInfoHandler); + +%shared_ptr(ppc::gateway::IGateway); +%shared_ptr(bcos::Error); +%shared_ptr(bcos::bytes); +%shared_ptr(ppc::protocol::Message); +%shared_ptr(ppc::protocol::MessageOptionalHeader); +%shared_ptr(ppc::protocol::MessageHeader); +%shared_ptr(ppc::protocol::MessagePayload); +%shared_ptr(ppc::protocol::MessageBuilder); +%shared_ptr(ppc::protocol::MessageHeaderBuilder); +%shared_ptr(ppc::protocol::MessagePayloadBuilder); +%shared_ptr(ppc::protocol::MessageOptionalHeaderBuilder); +%shared_ptr(ppc::protocol::GrpcConfig); +%shared_ptr(ppc::sdk::Transport); + + +%{ +#define SWIG_FILE_WITH_INIT +#include +#include +#include +#include +#include +#include "wedpr-transport/sdk/src/TransportBuilder.h" +#include "wedpr-transport/sdk/src/Transport.h" +#include "ppc-framework/libwrapper/Buffer.h" +#include "ppc-framework/front/IFront.h" +#include "ppc-framework/protocol/INodeInfo.h" +#include "ppc-framework/front/INodeDiscovery.h" +#include "ppc-framework/protocol/RouteType.h" +#include "ppc-framework/front/FrontConfig.h" +#include "ppc-framework/protocol/GrpcConfig.h" +#include +#include "ppc-framework/protocol/EndPoint.h" +#include "ppc-framework/protocol/Message.h" +#include "ppc-framework/protocol/MessagePayload.h" +%} +namespace ppc::sdk{ + class Transport; + class TransportBuilder; +} + +namespace ppc::gateway{ + class IGateway; +} + +namespace ppc::protocol{ + class Message; + class MessageHeader; + class MessagePayload; + class MessageOptionalHeader; + class MessageBuilder; + class MessageHeaderBuilder; + class MessagePayloadBuilder; + class MessageOptionalHeaderBuilder; + class EndPoint; + class GrpcConfig; + class RouteType; + class INodeInfo; +} + +namespace ppc::front{ + class FrontConfig; + class IFront; + class INodeDiscovery; + class IFrontClient; + class FrontImpl; + class FrontBuilderImpl; + class GatewayEndPoint; + class ErrorCallback; + class MessageDispatcherHandler; + class IMessageHandler; + class SendResponseHandler; +} + +namespace std{ + class vector; + class string; +} + +namespace bcos{ + using byte = uint8_t; + using bytes = std::vector; + class Error; +} + +// define shared_ptr objects +%template(SharedBcosError) std::shared_ptr; + +%template(SharedFrontConfig) std::shared_ptr; +%template(SharedGrpcConfig) std::shared_ptr; + +%template(SharedFront) std::shared_ptr; +%template(SharedNodeDiscovery) std::shared_ptr; +%template(SharedNodeInfo) std::shared_ptr; +%template(SharedFrontClient) std::shared_ptr; + +%template(SharedErrorCallback) std::shared_ptr; +%template(SharedMessageDispatcherHandler) std::shared_ptr; +%template(SharedIMessageHandler) std::shared_ptr; +%template(SharedGetPeersInfoHandler) std::shared_ptr; + +%template(SharedGateway) std::shared_ptr; + +%template(SharedMessage) std::shared_ptr; +%template(SharedMessageHeader) std::shared_ptr; +%template(SharedMessagePayload) std::shared_ptr; +%template(SharedRouteInfo) std::shared_ptr; + +%template(SharedMessageBuilder) std::shared_ptr; +%template(SharedMessageHeaderBuilder) std::shared_ptr; +%template(SharedMessagePayloadBuilder) std::shared_ptr; +%template(SharedRouteInfoBuilder) std::shared_ptr; + +%template(ubytes) std::vector; +%template(ibytes) std::vector; +%template(StringVec) std::vector; +%template(NodeInfoVec) std::vector>; + +%include +%pybuffer_binary(char* data, uint64_t length) +%pybuffer_binary(char* payload, uint64_t payloadSize) + +%typemap(out) OutputBuffer { + $result = PyBytes_FromStringAndSize((const char *)$1.data, $1.len); +} + +/// callbacks +%feature("director") ppc::front::ErrorCallback; +%feature("director") ppc::front::MessageDispatcherHandler; +%feature("director") ppc::front::IMessageHandler; +%feature("director") ppc::front::GetPeersInfoHandler; + +// the method no need to wrapper +%ignore ppc::sdk::TransportBuilder::build; +%ignore ppc::front::IFront::onReceiveMessage; +%ignore ppc::front::IFront::asyncSendMessage; +%ignore ppc::front::IFront::asyncGetAgencies; +%ignore ppc::front::IFront::registerTopicHandler; +%ignore ppc::front::IFront::registerMessageHandler; +%ignore ppc::front::IFront::asyncSendResponse; +%ignore ppc::front::IFront::populateErrorCallback; +%ignore ppc::front::IFront::populateMessageDispatcherCallback; +%ignore ppc::front::IFront::populateMsgCallback; +%ignore ppc::front::IFront::push; +%ignore ppc::front::IFront::registerNodeInfo; +%ignore ppc::front::IFront::unRegisterNodeInfo; +%ignore ppc::protocol::MessageOptionalHeader::srcNode; +%ignore ppc::protocol::MessageOptionalHeader::dstNode; +%ignore ppc::protocol::MessageOptionalHeader::setDstNode; +%ignore ppc::protocol::MessageOptionalHeader::setSrcNode; +%ignore ppc::protocol::MessagePayload::data; +%ignore ppc::protocol::MessagePayload::setData; +%ignore ppc::protocol::MessagePayload::setDataPtr; +%ignore ppc::protocol::MessagePayload::dataPtr; +%ignore ppc::front::INodeDiscovery::start; +%ignore ppc::front::INodeDiscovery::stop; +%ignore ppc::protocol::INodeInfo::INodeInfo; +%ignore ppc::protocol::INodeInfo::setFront; +%ignore ppc::protocol::INodeInfo::getFront; +%ignore ppc::protocol::INodeInfo::components; +%ignore ppc::protocol::INodeInfo::encode; +%ignore ppc::protocol::INodeInfo::decode; +%ignore ppc::protocol::INodeInfo::equal; +%ignore ppc::protocol::INodeInfo::toJson; +%ignore ppc::protocol::INodeInfo::setComponents; +%ignore ppc::protocol::INodeInfoFactory; +%ignore ppc::protocol::Message::setFrontMessage; + +%ignore ppc::protocol::GrpcConfig::~GrpcConfig; +%ignore ppc::protocol::GrpcServerConfig::~GrpcServerConfig; +/* +///// tests /// +%inline { +} +///// tests /// +*/ +%include "exception.i" +%exception { + try { + $action + } + catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, std::string(boost::diagnostic_information(e)).c_str()); + } +} + +// define the interface should been exposed +%include "bcos-utilities/Error.h" +%include "ppc-framework/libwrapper/Buffer.h" +%include "ppc-framework/front/FrontConfig.h" +%include "ppc-framework/protocol/EndPoint.h" +%include "ppc-framework/protocol/GrpcConfig.h" +%include "ppc-framework/protocol/Message.h" +%include "ppc-framework/protocol/MessagePayload.h" + +%include "ppc-framework/front/IFront.h" +%include "ppc-framework/front/INodeDiscovery.h" + +%include "wedpr-transport/sdk/src/TransportBuilder.h" +%include "wedpr-transport/sdk/src/Transport.h" +%include "ppc-framework/protocol/INodeInfo.h" \ No newline at end of file diff --git a/cpp/wedpr-transport/sdk/CMakeLists.txt b/cpp/wedpr-transport/sdk/CMakeLists.txt new file mode 100644 index 00000000..4606f2dd --- /dev/null +++ b/cpp/wedpr-transport/sdk/CMakeLists.txt @@ -0,0 +1,8 @@ +cmake_minimum_required(VERSION 3.14) + +add_subdirectory(src) + +if (DEMO) + add_subdirectory(demo) + enable_testing() +endif () \ No newline at end of file diff --git a/cpp/wedpr-transport/sdk/demo/CMakeLists.txt b/cpp/wedpr-transport/sdk/demo/CMakeLists.txt new file mode 100644 index 00000000..4ee3354c --- /dev/null +++ b/cpp/wedpr-transport/sdk/demo/CMakeLists.txt @@ -0,0 +1,7 @@ +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) +# cmake settings +set(BINARY_NAME transport_sdk_demo) +add_executable(${BINARY_NAME} transport_client.cpp) +target_link_libraries(${BINARY_NAME} ${WEDPR_TRANSPORT_SDK_TARGET}) + +unset(CMAKE_RUNTIME_OUTPUT_DIRECTORY) \ No newline at end of file diff --git a/cpp/wedpr-transport/sdk/demo/transport_client.cpp b/cpp/wedpr-transport/sdk/demo/transport_client.cpp new file mode 100644 index 00000000..b9e59d30 --- /dev/null +++ b/cpp/wedpr-transport/sdk/demo/transport_client.cpp @@ -0,0 +1,132 @@ +/* + * Copyright (C) 2022 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 transport_bench.cpp + * @desc: bench for transport + * @author: yujiechen + * @date 2024-09-13 + */ +#include "ppc-framework/protocol/RouteType.h" +#include "wedpr-transport/sdk/src/TransportBuilder.h" +#include + +using namespace ppc::front; +using namespace ppc::sdk; +using namespace ppc::protocol; + +void Usage(std::string const& _appName) +{ + std::cout << _appName << " [hostIp] [listenPort] [gatewayTargets] [nodeID] [dstNode]" + << std::endl; + std::cout << "example:" << std::endl; + std::cout << _appName + << " 127.0.0.1 9020 ipv4:127.0.0.1:40600,127.0.0.1:40601 agency0Node agency1Node" + << std::endl; + std::cout << _appName + << " 127.0.0.1 9021 ipv4:127.0.0.1:40620,127.0.0.1:40621 agency1Node agency0Node" + << std::endl; +} + +int main(int argc, char* argv[]) +{ + if (argc < 6) + { + Usage(argv[0]); + return -1; + } + // the hostIp + std::string hostIp = argv[1]; + // the clientPort + int port = atoi(argv[2]); + std::string listenIp = "0.0.0.0"; + // the gatewayTargets + std::string gatewayTargets = argv[3]; + // the nodeID + std::string nodeID = argv[4]; + // the dstNode + std::string dstNode = argv[5]; + + auto transportBuilder = std::make_shared(); + auto frontConfig = transportBuilder->buildConfig(2, nodeID); + frontConfig->setGatewayGrpcTarget(gatewayTargets); + EndPoint endPoint(hostIp, port); + frontConfig->setSelfEndPoint(endPoint); + auto transport = transportBuilder->buildProTransport(frontConfig); + + // start the transport + std::cout << "#### start the front, detail: " << printFrontDesc(frontConfig); + transport->start(); + auto routeInfo = transport->routeInfoBuilder()->build(); + std::string topic = "sync_testDemo"; + routeInfo->setDstNode(bcos::bytes(dstNode.begin(), dstNode.end())); + routeInfo->setTopic(topic); + transport->getFront()->registerTopicHandler(topic, [](Message::Ptr msg) { + std::cout << "=== async receive message: " << printMessage(msg) << "====" << std::endl; + }); + std::string syncTopic = "sync__" + topic; + auto syncRouteInfo = transport->routeInfoBuilder()->build(); + syncRouteInfo->setDstNode(bcos::bytes(dstNode.begin(), dstNode.end())); + syncRouteInfo->setTopic(syncTopic); + // sendMessage test + long i = 0; + while (true) + { + try + { + std::string payload = "payload+++" + std::to_string(i); + bcos::bytes payloadBytes = bcos::bytes(payload.begin(), payload.end()); + // async test + transport->getFront()->asyncSendMessage((uint16_t)RouteType::ROUTE_THROUGH_NODEID, + routeInfo, std::move(bcos::bytes(payload.begin(), payload.end())), 0, 10000, + [](bcos::Error::Ptr error) { + if (error && error->errorCode() != 0) + { + std::cout << "!**** send message failed for: " << error->errorMessage() + << "***!" << std::endl; + } + }, + nullptr); + + // push + auto error = transport->getFront()->push((uint16_t)RouteType::ROUTE_THROUGH_NODEID, + syncRouteInfo, std::move(payloadBytes), 0, 10000); + if (!error && error->errorCode() != 0) + { + std::cout << "!**** send message failed for: " << error->errorMessage() << "***!" + << std::endl; + } + // pop + auto msg = transport->getFront()->pop(syncTopic, 10000); + if (msg == nullptr) + { + std::cout << "try to receive message timeout" << std::endl; + } + else + { + std::cout << "=== sync receive message: " << printMessage(msg) + << "====" << std::endl; + } + i++; + } + catch (std::exception const& e) + { + std::cout << "!**** exception: " << boost::diagnostic_information(e) << "****!" + << std::endl; + } + // wait for 2s + std::this_thread::sleep_for(std::chrono::milliseconds(2000)); + }; + return 0; +} diff --git a/cpp/wedpr-transport/sdk/src/CMakeLists.txt b/cpp/wedpr-transport/sdk/src/CMakeLists.txt new file mode 100644 index 00000000..18e585fb --- /dev/null +++ b/cpp/wedpr-transport/sdk/src/CMakeLists.txt @@ -0,0 +1,6 @@ +cmake_minimum_required(VERSION 3.14) +file(GLOB_RECURSE SRCS *.cpp) + +add_library(${WEDPR_TRANSPORT_SDK_TARGET} ${SRCS}) +target_link_libraries(${WEDPR_TRANSPORT_SDK_TARGET} PUBLIC + ${FRONT_TARGET} ${PB_PROTOCOL_TARGET} ${SERVICE_CLIENT_TARGET} ${SERVICE_SERVER_TARGET} ${CPU_FEATURES_LIB}) \ No newline at end of file diff --git a/cpp/wedpr-transport/sdk/src/Common.h b/cpp/wedpr-transport/sdk/src/Common.h new file mode 100644 index 00000000..e7a1831f --- /dev/null +++ b/cpp/wedpr-transport/sdk/src/Common.h @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2022 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 Common.h + * @author: shawnhe + * @date 2022-10-23 + */ + +#pragma once + +#include "ppc-framework/Common.h" +#include + +namespace ppc::sdk +{ +#define TRANSPORT_LOG(LEVEL) BCOS_LOG(LEVEL) << "[TRASPORT]" +} // namespace ppc::sdk \ No newline at end of file diff --git a/cpp/wedpr-transport/sdk/src/ProTransportImpl.cpp b/cpp/wedpr-transport/sdk/src/ProTransportImpl.cpp new file mode 100644 index 00000000..dbc5bb5c --- /dev/null +++ b/cpp/wedpr-transport/sdk/src/ProTransportImpl.cpp @@ -0,0 +1,117 @@ +/** + * 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 ProTransportImpl.cpp + * @author: yujiechen + * @date 2024-09-04 + */ +#include "ProTransportImpl.h" +#include "Common.h" +#include "wedpr-protocol/grpc/client/GatewayClient.h" +#include "wedpr-protocol/grpc/server/FrontServer.h" +#include "wedpr-protocol/grpc/server/GrpcServer.h" + +using namespace ppc::front; +using namespace ppc::protocol; +using namespace ppc::sdk; + + +ProTransportImpl::ProTransportImpl(ppc::front::FrontConfig::Ptr config, int keepAlivePeriodMs) + : Transport(config), m_keepAlivePeriodMs(keepAlivePeriodMs) +{ + // Note: since the config has been moved away, should not use the `config`, use `m_config` + // instead default enable health-check + auto grpcServerConfig = std::make_shared(m_config->selfEndPoint(), true); + m_server = std::make_shared(grpcServerConfig); + + FrontFactory frontFactory; + auto nodeInfoFactory = std::make_shared(); + m_gateway = std::make_shared( + m_config->grpcConfig(), m_config->gatewayGrpcTarget(), nodeInfoFactory); + m_front = frontFactory.build( + nodeInfoFactory, m_msgPayloadBuilder, m_routeInfoBuilder, m_gateway, m_config); + + m_frontService = std::make_shared(m_msgBuilder, m_front); + // register the frontService + m_server->registerService(m_frontService); +} + +ProTransportImpl::~ProTransportImpl() +{ + TRANSPORT_LOG(INFO) << LOG_DESC("stop pro transport"); + stop(); + TRANSPORT_LOG(INFO) << LOG_DESC("stop pro transport success"); +} + +void ProTransportImpl::start() +{ + m_timer = std::make_shared(m_keepAlivePeriodMs, "frontKeepAlive"); + auto self = weak_from_this(); + m_timer->registerTimeoutHandler([self]() { + auto transport = self.lock(); + if (!transport) + { + return; + } + transport->keepAlive(); + }); + if (m_timer) + { + m_timer->start(); + } + if (m_server) + { + m_server->start(); + } + if (m_frontService) + { + // Note: the server is inited after start + m_frontService->setHealthCheckService(m_server->server()->GetHealthCheckService()); + } + if (m_front) + { + m_front->start(); + } +} + +void ProTransportImpl::stop() +{ + if (m_timer) + { + m_timer->stop(); + } + if (m_server) + { + m_server->stop(); + } + if (m_front) + { + m_front->stop(); + } +} + +void ProTransportImpl::keepAlive() +{ + try + { + m_gateway->registerNodeInfo(m_front->nodeInfo()); + } + catch (std::exception const& e) + { + TRANSPORT_LOG(WARNING) << LOG_DESC("keepAlive exception") + << LOG_KV("error", boost::diagnostic_information(e)); + } + m_timer->restart(); +} \ No newline at end of file diff --git a/cpp/wedpr-transport/sdk/src/ProTransportImpl.h b/cpp/wedpr-transport/sdk/src/ProTransportImpl.h new file mode 100644 index 00000000..663fd1aa --- /dev/null +++ b/cpp/wedpr-transport/sdk/src/ProTransportImpl.h @@ -0,0 +1,52 @@ +/** + * 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 ProTransportImpl.h + * @author: yujiechen + * @date 2024-09-04 + */ +#pragma once +#include "TransportImpl.h" +#include "bcos-utilities/Timer.h" +#include "protocol/src/v1/MessageImpl.h" + +namespace ppc::protocol +{ +class GrpcServer; +class FrontServer; +} // namespace ppc::protocol + + +namespace ppc::sdk +{ +class ProTransportImpl : public Transport, public std::enable_shared_from_this +{ +public: + using Ptr = std::shared_ptr; + ProTransportImpl(ppc::front::FrontConfig::Ptr config, int keepAlivePeriodMs = 3000); + ~ProTransportImpl(); + void start() override; + void stop() override; + +protected: + void keepAlive(); + +protected: + std::shared_ptr m_server; + std::shared_ptr m_frontService; + int m_keepAlivePeriodMs; + std::shared_ptr m_timer; +}; +} // namespace ppc::sdk \ No newline at end of file diff --git a/cpp/wedpr-transport/sdk/src/Transport.cpp b/cpp/wedpr-transport/sdk/src/Transport.cpp new file mode 100644 index 00000000..ea7b112f --- /dev/null +++ b/cpp/wedpr-transport/sdk/src/Transport.cpp @@ -0,0 +1,33 @@ +/** + * 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 Transport.cpp + * @author: yujiechen + * @date 2024-09-04 + */ +#include "Transport.h" +#include "protocol/src/v1/MessageHeaderImpl.h" +#include "protocol/src/v1/MessageImpl.h" +#include "protocol/src/v1/MessagePayloadImpl.h" + +using namespace ppc::sdk; + +Transport::Transport(ppc::front::FrontConfig::Ptr config) + : m_config(std::move(config)), + m_msgPayloadBuilder(std::make_shared()), + m_msgHeaderBuilder(std::make_shared()), + m_msgBuilder(std::make_shared(m_msgHeaderBuilder)), + m_routeInfoBuilder(std::make_shared()) +{} diff --git a/cpp/wedpr-transport/sdk/src/Transport.h b/cpp/wedpr-transport/sdk/src/Transport.h new file mode 100644 index 00000000..bfcc4414 --- /dev/null +++ b/cpp/wedpr-transport/sdk/src/Transport.h @@ -0,0 +1,85 @@ +/** + * 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 Transport.h + * @author: yujiechen + * @date 2024-09-04 + */ +#pragma once +#include "ppc-framework/front/FrontConfig.h" +#include "ppc-framework/front/IFront.h" +#include "ppc-framework/gateway/IGateway.h" +#include "ppc-framework/protocol/Message.h" +#include "ppc-framework/protocol/MessagePayload.h" + +namespace ppc::sdk +{ +class Transport +{ +public: + using Ptr = std::shared_ptr; + Transport(ppc::front::FrontConfig::Ptr config); + virtual ~Transport() { stop(); } + + virtual void start() + { + if (!m_front) + { + return; + } + m_front->start(); + } + virtual void stop() + { + if (!m_front) + { + return; + } + m_front->stop(); + } + + virtual ppc::front::IFront::Ptr const& getFront() const { return m_front; } + + virtual ppc::gateway::IGateway::Ptr const& gateway() const { return m_gateway; } + + virtual ppc::protocol::MessagePayloadBuilder::Ptr const& msgPayloadBuilder() const + { + return m_msgPayloadBuilder; + } + virtual ppc::protocol::MessageBuilder::Ptr const& msgBuilder() const { return m_msgBuilder; } + virtual ppc::protocol::MessageHeaderBuilder::Ptr const& msgHeaderBuilder() const + { + return m_msgHeaderBuilder; + } + + virtual ppc::protocol::MessageOptionalHeaderBuilder::Ptr const& routeInfoBuilder() const + { + return m_routeInfoBuilder; + } + + virtual ppc::front::FrontConfig::Ptr const& getConfig() const { return m_config; } + +protected: + ppc::front::IFront::Ptr m_front; + ppc::gateway::IGateway::Ptr m_gateway; + + ppc::front::FrontConfig::Ptr m_config; + + ppc::protocol::MessageHeaderBuilder::Ptr m_msgHeaderBuilder; + ppc::protocol::MessagePayloadBuilder::Ptr m_msgPayloadBuilder; + ppc::protocol::MessageOptionalHeaderBuilder::Ptr m_routeInfoBuilder; + ppc::protocol::MessageBuilder::Ptr m_msgBuilder; +}; +} // namespace ppc::sdk \ No newline at end of file diff --git a/cpp/wedpr-transport/sdk/src/TransportBuilder.cpp b/cpp/wedpr-transport/sdk/src/TransportBuilder.cpp new file mode 100644 index 00000000..69d60d31 --- /dev/null +++ b/cpp/wedpr-transport/sdk/src/TransportBuilder.cpp @@ -0,0 +1,85 @@ +/** + * 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 TransportBuilder.cpp + * @author: yujiechen + * @date 2024-09-04 + */ + +#include "TransportBuilder.h" +#include "Common.h" +#include "ProTransportImpl.h" +#include "Transport.h" +#include "TransportImpl.h" +#include "ppc-front/FrontConfigImpl.h" +#include "protobuf/src/NodeInfoImpl.h" +#include + +using namespace ppc::sdk; +using namespace ppc::front; + +TransportBuilder::TransportBuilder() +{ + m_frontConfigBuilder = std::make_shared( + std::make_shared()); +} + +Transport::Ptr TransportBuilder::build( + SDKMode mode, ppc::front::FrontConfig::Ptr config, ppc::gateway::IGateway::Ptr gateway) +{ + switch (mode) + { + case SDKMode::AIR: + { + return std::make_shared(config, gateway); + } + case SDKMode::PRO: + { + return std::make_shared(config); + } + default: + throw std::runtime_error("Unsupported sdk mode, only support AIR/PRO mode!"); + } +} + +ppc::front::FrontConfig::Ptr TransportBuilder::buildConfig(int threadPoolSize, std::string nodeID) +{ + return m_frontConfigBuilder->build(threadPoolSize, nodeID); +} + + +void TransportBuilder::initLog(const std::string& configPath) +{ + bcos::Guard l(x_logInited); + if (m_logInited) + { + return; + } + m_logInited = true; + // init the log + boost::property_tree::ptree pt; + try + { + boost::property_tree::read_ini(configPath, pt); + } + catch (std::exception const& e) + { + // disable the log when the configPath not exists + pt.put("log.enable", false); + } + m_logInitializer = std::make_shared(); + m_logInitializer->initLog(pt, bcos::FileLogger, "gateway_sdk_log"); + TRANSPORT_LOG(INFO) << LOG_DESC("init log success") << LOG_KV("configPath", configPath); +} \ No newline at end of file diff --git a/cpp/wedpr-transport/sdk/src/TransportBuilder.h b/cpp/wedpr-transport/sdk/src/TransportBuilder.h new file mode 100644 index 00000000..51727fa9 --- /dev/null +++ b/cpp/wedpr-transport/sdk/src/TransportBuilder.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 TransportBuilder.h + * @author: yujiechen + * @date 2024-09-04 + */ +#pragma once +#include "Transport.h" +#include "ppc-framework/front/FrontConfig.h" +#include "ppc-framework/gateway/IGateway.h" +#include +#include +namespace ppc::sdk +{ +enum class SDKMode : uint8_t +{ + AIR = 0x00, + PRO = 0x01, +}; +class TransportBuilder +{ +public: + using Ptr = std::shared_ptr; + TransportBuilder(); + virtual ~TransportBuilder() = default; + + Transport::Ptr build( + SDKMode mode, ppc::front::FrontConfig::Ptr config, ppc::gateway::IGateway::Ptr gateway); + + // Note: the swig-wrapper can't receive the null shared_ptr + Transport::Ptr buildProTransport(ppc::front::FrontConfig::Ptr config) + { + return build(SDKMode::PRO, config, nullptr); + } + + ppc::front::FrontConfig::Ptr buildConfig(int threadPoolSize, std::string nodeID); + + ppc::front::FrontConfigBuilder::Ptr const& frontConfigBuilder() { return m_frontConfigBuilder; } + + + void initLog(const std::string& configPath); + +private: + ppc::front::FrontConfigBuilder::Ptr m_frontConfigBuilder; + bcos::BoostLogInitializer::Ptr m_logInitializer; + bool m_logInited = false; + bcos::Mutex x_logInited; +}; +} // namespace ppc::sdk \ No newline at end of file diff --git a/cpp/wedpr-transport/sdk/src/TransportImpl.h b/cpp/wedpr-transport/sdk/src/TransportImpl.h new file mode 100644 index 00000000..5ebda37b --- /dev/null +++ b/cpp/wedpr-transport/sdk/src/TransportImpl.h @@ -0,0 +1,44 @@ +/** + * 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 TransportImpl.h + * @author: yujiechen + * @date 2024-09-04 + */ +#pragma once +#include "Transport.h" +#include "ppc-framework/gateway/IGateway.h" +#include "ppc-front/FrontFactory.h" +#include "protobuf/src/NodeInfoImpl.h" + + +namespace ppc::sdk +{ +class TransportImpl : public Transport +{ +public: + TransportImpl(ppc::front::FrontConfig::Ptr config, ppc::gateway::IGateway::Ptr const& gateway) + : Transport(config) + + { + m_gateway = gateway; + + ppc::front::FrontFactory frontFactory; + m_front = frontFactory.build(std::make_shared(), + m_msgPayloadBuilder, m_routeInfoBuilder, gateway, m_config); + } + ~TransportImpl() override = default; +}; +} // namespace ppc::sdk diff --git a/docker-files/cpp/Dockerfile b/docker-files/cpp/Dockerfile new file mode 100644 index 00000000..6a6144c2 --- /dev/null +++ b/docker-files/cpp/Dockerfile @@ -0,0 +1,79 @@ +FROM ubuntu:22.04 as builder + +LABEL maintainer=service@webank.com + +WORKDIR / + +ARG SOURCE_BRANCH +ENV DEBIAN_FRONTEND=noninteractive \ + SOURCE=${SOURCE_BRANCH:-main} + +# Note: depends on python3; default jdk for jni +RUN apt-get -q update && apt-get install -qy --no-install-recommends \ + vim curl lcov git make nasm build-essential cmake wget libtool ca-certificates python3.11 python3-dev \ + libgmp-dev flex bison patch libzstd-dev unzip ninja-build pkg-config zip tar ccache uuid-runtime automake autoconf \ + m4 tcpdump net-tools gcc g++ default-jdk \ + && ln -fs /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \ + && apt-get install -qy --no-install-recommends tzdata \ + && dpkg-reconfigure --frontend noninteractive tzdata \ + && rm -rf /var/lib/apt/lists/* + +# install rust +RUN curl https://sh.rustup.rs -sSf | bash -s -- -y + +ENV PATH="/root/.cargo/bin:${PATH}" + +ENV VCPKG_FORCE_SYSTEM_BINARIES=1 + +RUN git clone https://github.com/WeBankBlockchain/WeDPR-Component --recursive --depth=1 -b ${SOURCE} + +# ln the cached vcpkg and compile +RUN cd WeDPR-Component/cpp \ + && mkdir -p build && cd build \ + && cmake .. -DCMAKE_BUILD_TYPE=Release -DBUILD_STATIC=ON \ + && make -j8 + +FROM ubuntu:22.04 as wedpr-gateway-service +LABEL maintainer=service@webank.com + +RUN apt-get -q update && apt-get install -qy --no-install-recommends vim \ + && ln -fs /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \ + && apt-get install -qy --no-install-recommends tzdata \ + && dpkg-reconfigure --frontend noninteractive tzdata \ + && rm -rf /var/lib/apt/lists/* + +RUN mkdir -p /data/home/wedpr/wedpr-gateway-service + +COPY --from=builder /WeDPR-Component/cpp/build/bin/ppc-gateway-service /data/home/wedpr/wedpr-gateway-service/ppc-gateway-service + +ENTRYPOINT ["/data/home/wedpr/wedpr-gateway-service/ppc-gateway-service", "-c", "config.ini"] + +FROM ubuntu:22.04 as wedpr-pro-node-service +LABEL maintainer=service@webank.com + +RUN apt-get -q update && apt-get install -qy --no-install-recommends vim libkrb5-dev krb5-user \ + && ln -fs /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \ + && apt-get install -qy --no-install-recommends tzdata \ + && dpkg-reconfigure --frontend noninteractive tzdata \ + && rm -rf /var/lib/apt/lists/* + +RUN mkdir -p /data/home/wedpr/wedpr-pro-node-service + +COPY --from=builder /WeDPR-Component/cpp/build/bin/ppc-pro-node /data/home/wedpr/wedpr-pro-node-service/ppc-pro-node + +ENTRYPOINT ["/data/home/wedpr/wedpr-pro-node-service/ppc-pro-node", "-c", "config.ini"] + +FROM fiscoorg/wedpr-mpc-base-ubuntu:v3.0.0 as wedpr-mpc-service +LABEL maintainer=service@webank.com + +RUN apt-get -q update && apt-get install -qy --no-install-recommends vim libkrb5-dev krb5-user \ + && ln -fs /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \ + && apt-get install -qy --no-install-recommends tzdata \ + && dpkg-reconfigure --frontend noninteractive tzdata \ + && rm -rf /var/lib/apt/lists/* + +RUN mkdir -p /data/home/wedpr/wedpr-mpc-service + +COPY --from=builder /WeDPR-Component/cpp/build/bin/wedpr-mpc /data/home/wedpr/wedpr-mpc-service/wedpr-mpc + +ENTRYPOINT ["/data/home/wedpr/wedpr-mpc-service/wedpr-mpc", "-c", "config.ini"] diff --git a/docker-files/cpp/build.sh b/docker-files/cpp/build.sh new file mode 100644 index 00000000..0e13dd39 --- /dev/null +++ b/docker-files/cpp/build.sh @@ -0,0 +1,16 @@ +#!/bin/bash +echo "========= BUILD IMAGES for WEDPR-COMPONENT, BRANCH: ${1} =========" + +echo "* build wedpr-gateway-service image" +docker build --target wedpr-gateway-service --build-arg SOURCE_BRANCH=${1} -t wedpr-gateway-service . +echo "* build wedpr-gateway-service image success" + +echo "* build wedpr-pro-node-service image" +docker build --target wedpr-pro-node-service --build-arg SOURCE_BRANCH=${1} -t wedpr-pro-node-service . +echo "* build wedpr-pro-node-service image success" + +echo "* build wedpr-mpc-service image" +docker build --target wedpr-mpc-service --build-arg SOURCE_BRANCH=${1} -t wedpr-mpc-service . +echo "* build wedpr-mpc-service image success" + +echo "========= BUILD IMAGES for WEDPR-COMPONENT, BRANCH: ${1} =========" \ No newline at end of file diff --git a/docker-files/cpp/vcpkg/Dockerfile b/docker-files/cpp/vcpkg/Dockerfile new file mode 100644 index 00000000..9e1d75f4 --- /dev/null +++ b/docker-files/cpp/vcpkg/Dockerfile @@ -0,0 +1,37 @@ +FROM ubuntu:22.04 as wedpr-component-vcpkg-cache + +LABEL maintainer=service@webank.com + +WORKDIR / + +ARG SOURCE_BRANCH +ENV DEBIAN_FRONTEND=noninteractive \ + SOURCE=${SOURCE_BRANCH:-main} +# Note: depends on python3; default jdk for jni +RUN apt-get -q update && apt-get install -qy --no-install-recommends \ + vim curl lcov git make nasm build-essential cmake wget libtool ca-certificates python3.11 python3-dev \ + libgmp-dev flex bison patch libzstd-dev unzip ninja-build pkg-config zip tar ccache uuid-runtime automake autoconf \ + m4 tcpdump net-tools gcc g++ default-jdk \ + && ln -fs /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \ + && apt-get install -qy --no-install-recommends tzdata \ + && dpkg-reconfigure --frontend noninteractive tzdata \ + && rm -rf /var/lib/apt/lists/* + +# install rust +RUN curl https://sh.rustup.rs -sSf | bash -s -- -y + +ENV PATH="/root/.cargo/bin:${PATH}" + +ENV VCPKG_FORCE_SYSTEM_BINARIES=1 + +# first download and compile the vcpkg dependecies +RUN git clone https://github.com/cyjseagull/WeDPR-Component --recursive --depth=1 -b ${SOURCE} \ + && mkdir -p WeDPR-Component/cpp/build && cd WeDPR-Component/cpp/build \ + && cmake .. -DBUILD_STATIC=ON + +# move the vcpkg dependecies to /vcpkg +RUN mv /WeDPR-Component/cpp/vcpkg / + +# remove the WeDPR-Component +RUN rm -rf /WeDPR-Component/ && rm -rf /vcpkg/buildtrees/*/src && rm -rf /vcpkg/buildtrees/*/*-dbg + diff --git a/docker-files/cpp/vcpkg/build.sh b/docker-files/cpp/vcpkg/build.sh new file mode 100644 index 00000000..56ed1efa --- /dev/null +++ b/docker-files/cpp/vcpkg/build.sh @@ -0,0 +1,4 @@ +#!/bin/bash +echo "* build image: wedpr-component-vcpkg-cache, branch: ${1}" +docker build --build-arg SOURCE_BRANCH=${1} -t wedpr-component-vcpkg-cache . +echo "* build image: wedpr-component-vcpkg-cache success, branch: ${1}" diff --git a/docker-files/model/base/Dockerfile b/docker-files/model/base/Dockerfile new file mode 100644 index 00000000..05c5a433 --- /dev/null +++ b/docker-files/model/base/Dockerfile @@ -0,0 +1,11 @@ +FROM fiscoorg/wedpr-image:v3.0.0 as wedpr-model-service-base-image + +LABEL maintainer=service@webank.com + +RUN apt-get install -qy --no-install-recommends pkg-config default-libmysqlclient-dev +RUN mkdir -p /data/home/wedpr +# copy requirements +COPY depends/requirements.txt /data/home/wedpr/requirements.txt + +# install the requirements +RUN pip install -i https://pypi.mirrors.ustc.edu.cn/simple/ -r /data/home/wedpr/requirements.txt diff --git a/docker-files/model/base/build.sh b/docker-files/model/base/build.sh new file mode 100644 index 00000000..55788924 --- /dev/null +++ b/docker-files/model/base/build.sh @@ -0,0 +1,4 @@ +#!/bin/bash +echo "* build image: wedpr-model-service-base-image" +docker build -t wedpr-model-service-base-image . +echo "* build image: wedpr-model-service-base-image success" \ No newline at end of file diff --git a/docker-files/model/base/depends/requirements.txt b/docker-files/model/base/depends/requirements.txt new file mode 100644 index 00000000..7b753c1b --- /dev/null +++ b/docker-files/model/base/depends/requirements.txt @@ -0,0 +1,59 @@ +cx-Oracle==8.3.0 +click>=8.0 +pytest +cheroot==8.5.2 +flask_restx==1.3.0 +configobj~=5.0.6 +Flask_SQLAlchemy==3.1.0 +cryptography~=41.0.5 +pandas +hypothesis~=5.48.0 +parsimonious~=0.8.1 +SQLAlchemy==2.0.16 +argcomplete~=1.12.2 +cytoolz~=0.10.1 +six~=1.15.0 +attrdict~=2.0.1 +Flask~=2.2.5 +pymitter~=0.3.0 +requests~=2.31.0 +requests_toolbelt==0.9.1 +lru_dict==1.1.6 +promise~=2.3 +#protobuf==3.19.0 +# protobuf>=4.21.6,<5.0dev +protobuf>=5.27.1 +pycryptodome==3.9.9 +pyjwt +pyyaml +mysqlclient==2.1.0 +waitress==3.0.0 +sqlparse~=0.4.1 +toolz~=0.11.1 +tenacity==7.0.0 +coincurve~=13.0.0 +google~=3.0.0 +paste~=3.5.0 +func_timeout==4.3.0 +cheroot==8.5.2 +gmssl~=3.2.1 +readerwriterlock~=1.0.4 +jsoncomment~=0.2.3 +matplotlib~=3.2.2 +seaborn~=0.10.1 +sqlvalidator==0.0.17 +requests-toolbelt==0.9.1 +hdfs +scikit-learn~=0.24.2 +gmpy2 +networkx +pydot +snowland-smx +numpy==1.23.1 +graphviz +xlrd~=1.0.0 +MarkupSafe>=2.1.1 +urllib3==1.26.18 +phe +chardet +requests_kerberos>=0.15.0 diff --git a/docker-files/model/model/Dockerfile b/docker-files/model/model/Dockerfile new file mode 100644 index 00000000..9d6a044b --- /dev/null +++ b/docker-files/model/model/Dockerfile @@ -0,0 +1,29 @@ +FROM fiscoorg/wedpr-model-service-base-image:v3.0.0 as wedpr-model-service +LABEL maintainer=service@webank.com + +ENV LANG zh_CN.UTF-8 +ENV LANGUAGE zh_CN.UTF-8 +ENV LC_ALL zh_CN.UTF-8 + +WORKDIR /data/home/wedpr +ARG SOURCE_BRANCH +ENV DEBIAN_FRONTEND=noninteractive \ + SOURCE=${SOURCE_BRANCH:-main} + +# install the gateway sdk +# TODO: replace with pypip +RUN pip install -i https://test.pypi.org/simple/ wedpr-python-gateway-sdk + +# obtain the source, no need to fetch the submodule(vcpkg) here +RUN git clone https://github.com/WeBankBlockchain/WeDPR-Component.git -b ${SOURCE} +# move the files to the /data/app path +RUN mkdir -p /data/home/wedpr/wedpr-model/ \ + && mv /data/home/wedpr/WeDPR-Component/python/ppc_common /data/home/wedpr/wedpr-model/ppc_common \ + && mv /data/home/wedpr/WeDPR-Component/python/ppc_model /data/home/wedpr/wedpr-model/ppc_model \ + && mv /data/home/wedpr/WeDPR-Component/python/aes_key.bin /data/home/wedpr/wedpr-model/ppc_model \ + && cp /data/home/wedpr/wedpr-model/ppc_model/tools/*.sh /data/home/wedpr/wedpr-model/ppc_model + +# clear the WeDPR-Component +RUN rm -rf /data/home/wedpr/WeDPR-Component + +ENTRYPOINT ["/bin/bash", "/data/home/wedpr/wedpr-model/start.sh", "true"] diff --git a/docker-files/model/model/build.sh b/docker-files/model/model/build.sh new file mode 100644 index 00000000..51ffda7a --- /dev/null +++ b/docker-files/model/model/build.sh @@ -0,0 +1,4 @@ +#!/bin/bash +echo "* build image: wedpr-model-service, branch: ${1}" +docker build --build-arg SOURCE_BRANCH=${1} -t wedpr-model-service . +echo "* build image: wedpr-model-service success, branch: ${1}" \ No newline at end of file diff --git a/python/__init__.py b/python/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/python/aes_key.bin b/python/aes_key.bin new file mode 100644 index 00000000..0d516172 --- /dev/null +++ b/python/aes_key.bin @@ -0,0 +1,2 @@ +m}9H +褊c?Ӈ!<> \ No newline at end of file diff --git a/python/ppc_common/__init__.py b/python/ppc_common/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/python/ppc_common/application-sample.yml b/python/ppc_common/application-sample.yml new file mode 100644 index 00000000..b30c0146 --- /dev/null +++ b/python/ppc_common/application-sample.yml @@ -0,0 +1,6 @@ +# mysql or dm +DB_TYPE: "mysql" +SQLALCHEMY_DATABASE_URI: "mysql://root:12345678@127.0.0.1:3306/ppc?autocommit=true&charset=utf8" +# SQLALCHEMY_DATABASE_URI: "dm+dmPython://ppcv16:ppc12345678@127.0.0.1:5236" + +MPC_BIT_LENGTH: [@IDC_PPCS_COMMON_MPC_BIT] diff --git a/python/ppc_common/application.yml b/python/ppc_common/application.yml new file mode 100644 index 00000000..0ada951d --- /dev/null +++ b/python/ppc_common/application.yml @@ -0,0 +1,6 @@ +# mysql or dm +DB_TYPE: "mysql" +SQLALCHEMY_DATABASE_URI: "mysql://root:12345678@127.0.0.1:3306/ppc?autocommit=true&charset=utf8" +# SQLALCHEMY_DATABASE_URI: "dm+dmPython://ppcv16:ppc12345678@127.0.0.1:5236" + +MPC_BIT_LENGTH: 1000 diff --git a/python/ppc_common/config.py b/python/ppc_common/config.py new file mode 100644 index 00000000..e8e565ae --- /dev/null +++ b/python/ppc_common/config.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +import os +import yaml + + +dirName, _ = os.path.split(os.path.abspath(__file__)) +config_path = '{}/application.yml'.format(dirName) + +CONFIG_DATA = {} + + +def read_config(): + global CONFIG_DATA + with open(config_path, 'rb') as f: + CONFIG_DATA = yaml.safe_load(f.read()) + + +read_config() diff --git a/python/ppc_common/db_models/__init__.py b/python/ppc_common/db_models/__init__.py new file mode 100644 index 00000000..591b4182 --- /dev/null +++ b/python/ppc_common/db_models/__init__.py @@ -0,0 +1,6 @@ +from flask_sqlalchemy import SQLAlchemy + + +db = SQLAlchemy() + +# __all__ = ['computation_provider','data_provider','job_computation_queue','job_data_queue', 'job_result'] diff --git a/python/ppc_common/db_models/file_object_meta.py b/python/ppc_common/db_models/file_object_meta.py new file mode 100644 index 00000000..ef48ef9a --- /dev/null +++ b/python/ppc_common/db_models/file_object_meta.py @@ -0,0 +1,12 @@ +from ppc_common.db_models import db +from sqlalchemy import text + + +class FileObjectMeta(db.Model): + __tablename__ = 't_file_object' + file_path = db.Column(db.String(255), primary_key=True) + file_count = db.Column(db.Integer) + create_time = db.Column(db.TIMESTAMP( + True), nullable=False, server_default=text('NOW()')) + last_update_time = db.Column(db.TIMESTAMP(True), nullable=False, server_default=text( + 'CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP')) diff --git a/python/ppc_common/db_models/file_path.py b/python/ppc_common/db_models/file_path.py new file mode 100644 index 00000000..4c626750 --- /dev/null +++ b/python/ppc_common/db_models/file_path.py @@ -0,0 +1,10 @@ +from ppc_common.db_models import db + + +class FilePathRecord(db.Model): + __tablename__ = 't_file_path' + path = db.Column(db.String(255), primary_key=True) + storage_type = db.Column(db.String(255)) + file_id = db.Column(db.String(255)) + file_hash = db.Column(db.String(255)) + create_time = db.Column(db.BigInteger) diff --git a/python/ppc_common/deps_services/__init__.py b/python/ppc_common/deps_services/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/python/ppc_common/deps_services/hdfs_storage.py b/python/ppc_common/deps_services/hdfs_storage.py new file mode 100644 index 00000000..aae0d851 --- /dev/null +++ b/python/ppc_common/deps_services/hdfs_storage.py @@ -0,0 +1,99 @@ +import os +from typing import AnyStr + +from hdfs.client import InsecureClient +from ppc_common.ppc_utils import common_func +from ppc_common.deps_services.storage_api import StorageApi, StorageType, HDFSStorageConfig + +from ppc_common.ppc_utils import utils + + +class HdfsStorage(StorageApi): + + # endpoint: http://127.0.0.1:50070 + def __init__(self, hdfs_config: HDFSStorageConfig, init_client: bool = True): + self.endpoint = hdfs_config.hdfs_url + self._user = hdfs_config.hdfs_user + self._hdfs_storage_path = hdfs_config.hdfs_home + if init_client: + self.client = InsecureClient(self.endpoint, user=self._user) + + def get_home_path(self): + return self._hdfs_storage_path + + def storage_type(self): + return StorageType.HDFS + + def download_file(self, hdfs_path, local_file_path, enable_cache=False): + # hit the cache + if enable_cache is True and utils.file_exists(local_file_path): + return + if utils.file_exists(local_file_path): + utils.delete_file(local_file_path) + local_path = os.path.dirname(local_file_path) + if len(local_path) > 0 and not os.path.exists(local_path): + os.makedirs(local_path) + self.client.download(os.path.join(self._hdfs_storage_path, + hdfs_path), local_file_path) + return + + def upload_file(self, local_file_path, hdfs_path, owner=None, group=None): + self.make_file_path(hdfs_path) + hdfs_abs_path = os.path.join(self._hdfs_storage_path, hdfs_path) + self.client.upload(hdfs_abs_path, + local_file_path, overwrite=True) + if owner is None and group is None: + return + group_info = group + if group is None: + group_info = self._user + owner_info = group_info + if owner is not None: + owner_info = owner + # set the permission information + self.client.set_owner(hdfs_path=hdfs_abs_path, + owner=owner_info, group=group_info) + return + + def make_file_path(self, hdfs_path): + hdfs_dir = os.path.dirname(hdfs_path) + if self.client.status(os.path.join(self._hdfs_storage_path, hdfs_dir), strict=False) is None: + self.client.makedirs(os.path.join( + self._hdfs_storage_path, hdfs_dir)) + return + + def delete_file(self, hdfs_path): + self.client.delete(os.path.join( + self._hdfs_storage_path, hdfs_path), recursive=True) + return + + def save_data(self, data: AnyStr, hdfs_path): + self.make_file_path(hdfs_path) + self.client.write(os.path.join(self._hdfs_storage_path, + hdfs_path), data, overwrite=True) + return + + def get_data(self, hdfs_path): + with self.client.read(os.path.join(self._hdfs_storage_path, hdfs_path)) as reader: + content = reader.read() + return content + + def mkdir(self, hdfs_dir): + self.client.makedirs(hdfs_dir) + + def file_existed(self, hdfs_path): + if self.client.status(os.path.join(self._hdfs_storage_path, hdfs_path), strict=False) is None: + return False + return True + + def file_rename(self, old_hdfs_path, hdfs_path): + old_path = os.path.join(self._hdfs_storage_path, old_hdfs_path) + new_path = os.path.join(self._hdfs_storage_path, hdfs_path) + # return for the file not exists + if not self.file_existed(old_path): + return + parent_path = os.path.dirname(new_path) + if len(parent_path) > 0 and not self.file_existed(parent_path): + self.mkdir(parent_path) + self.client.rename(old_path, new_path) + return diff --git a/python/ppc_common/deps_services/krb5_hdfs_storage.py b/python/ppc_common/deps_services/krb5_hdfs_storage.py new file mode 100644 index 00000000..fe5de3c1 --- /dev/null +++ b/python/ppc_common/deps_services/krb5_hdfs_storage.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +from hdfs.ext.kerberos import KerberosClient +from ppc_common.deps_services.hdfs_storage import HdfsStorage +from ppc_common.deps_services.storage_api import HDFSStorageConfig + + +class Krb5HdfsStorage(HdfsStorage): + def __init__(self, hdfs_config: HDFSStorageConfig, logger): + super().__init__(hdfs_config, False) + self.hdfs_config = hdfs_config + self.client = KerberosClient( + url=self.hdfs_config.hdfs_url, + principal=self.hdfs_config.hdfs_auth_principal, + hostname_override=self.hdfs_config.hdfs_hostname_override, + password=self.hdfs_config.hdfs_auth_password, + timeout=10000) diff --git a/python/ppc_common/deps_services/mysql_storage.py b/python/ppc_common/deps_services/mysql_storage.py new file mode 100644 index 00000000..d8c45f53 --- /dev/null +++ b/python/ppc_common/deps_services/mysql_storage.py @@ -0,0 +1,64 @@ +# -*- coding: utf-8 -*- +from ppc_common.deps_services.sql_storage_api import SQLStorageAPI +from sqlalchemy.orm import sessionmaker, scoped_session +from sqlalchemy import create_engine +from sqlalchemy import delete +from sqlalchemy import text +from contextlib import contextmanager + + +class MySQLStorage(SQLStorageAPI): + def __init__(self, storage_config): + self._engine_url = storage_config.engine_url + self._storage_config = storage_config + connect_args = {} + if storage_config.db_name is not None: + connect_args = {'schema': storage_config.db_name} + self._mysql_engine = create_engine(self._engine_url, pool_recycle=self._storage_config.pool_recycle, + pool_size=self._storage_config.pool_size, max_overflow=self._storage_config.max_overflow, + pool_timeout=self._storage_config.pool_timeout, + pool_pre_ping=self._storage_config.pool_pre_ping, + connect_args=connect_args) + self._session_factory = sessionmaker(bind=self._mysql_engine) + + @contextmanager + def _get_session(self): + session = self._session_factory() + try: + yield session + session.commit() + except Exception: + session.rollback() + raise + finally: + session.close() + + def query(self, object, condition): + """ + query according to the condition + """ + with self._get_session() as session: + return session.query(object).filter(condition) + + def merge(self, record): + """merge the given record to db + Args: + record (Any): the record should been inserted + """ + with self._get_session() as session: + session.merge(record) + + def execute(self, sql: str): + text_sql = text(sql) + with self._get_session() as session: + session.execute(text_sql) + + def delete(self, object, condition): + """delete according to condition + Args: + object (Any): the object + condition (Any): the condition + """ + stmt = delete(object).where(condition) + with self._get_session() as session: + session.execute(stmt) diff --git a/python/ppc_common/deps_services/serialize_type.py b/python/ppc_common/deps_services/serialize_type.py new file mode 100644 index 00000000..31b84f6f --- /dev/null +++ b/python/ppc_common/deps_services/serialize_type.py @@ -0,0 +1,7 @@ +# -*- coding: utf-8 -*- +from enum import Enum + + +class SerializeType(Enum): + CSV = 'csv' + JSON = 'gain' diff --git a/python/ppc_common/deps_services/sql_storage_api.py b/python/ppc_common/deps_services/sql_storage_api.py new file mode 100644 index 00000000..a8eba6c7 --- /dev/null +++ b/python/ppc_common/deps_services/sql_storage_api.py @@ -0,0 +1,58 @@ +# -*- coding: utf-8 -*- +from abc import ABC, abstractmethod +from ppc_common.ppc_utils import common_func + + +class SQLStorageConfig(ABC): + """ + configuration for sql storage + """ + DEFAULT_RECYCLE = 3600 + DEFAULT_POOL_SIZE = 16 + DEFAULT_MAX_OVERFLOW = 8 + DEFAULT_POOL_TIMEOUT = 30 + + def __init__(self, url, pool_recycle=None, pool_size=None, max_overflow=None, pool_timeout=None, db_type="mysql", db_name=None): + self.pool_recycle = common_func.get_config_value("pool_recycle", + SQLStorageConfig.DEFAULT_RECYCLE, pool_recycle, False) + self.pool_size = common_func.get_config_value("pool_size", + SQLStorageConfig.DEFAULT_POOL_SIZE, pool_size, False) + self.max_overflow = common_func.get_config_value("max_overflow", + SQLStorageConfig.DEFAULT_MAX_OVERFLOW, max_overflow, False) + self.pool_timeout = common_func.get_config_value("pool_timeout", + SQLStorageConfig.DEFAULT_POOL_TIMEOUT, pool_timeout, False) + self.db_type = db_type + self.engine_url = url + self.db_name = db_name + self.pool_pre_ping = True + + +class SQLStorageAPI: + @abstractmethod + def query(self, object, condition): + """ + query the result + """ + pass + + @abstractmethod + def merge(self, record): + """insert the record into db + + Args: + record (Any): the record need to be inserted + """ + pass + + @abstractmethod + def execute(self, sql: str): + pass + + @abstractmethod + def delete(self, object, condition): + """delete according to condition + Args: + object (Any): the object + condition (Any): the condition + """ + pass diff --git a/python/ppc_common/deps_services/storage_api.py b/python/ppc_common/deps_services/storage_api.py new file mode 100644 index 00000000..c07ad210 --- /dev/null +++ b/python/ppc_common/deps_services/storage_api.py @@ -0,0 +1,114 @@ +from abc import ABC, abstractmethod +from enum import Enum +from typing import AnyStr +from ppc_common.ppc_utils import common_func +import os + + +class StorageType(Enum): + HDFS = 'HDFS' + + +class HDFSStorageConfig: + DEFAULT_HDFS_USER = "ppc" + DEFAULT_HDFS_USER_PATH = "/user/" + + def __init__(self, hdfs_url: str = None, + hdfs_user: str = None, + hdfs_home: str = None, + enable_krb5_auth: bool = False, + hdfs_auth_principal: str = None, + hdfs_auth_password: str = None, + hdfs_hostname_override: str = None): + self.hdfs_url = hdfs_url + self.hdfs_user = hdfs_user + self.hdfs_home = hdfs_home + self.enable_krb5_auth = enable_krb5_auth + self.hdfs_auth_principal = hdfs_auth_principal + self.hdfs_auth_password = hdfs_auth_password + self.hdfs_hostname_override = hdfs_hostname_override + + def __repr__(self): + return f"hdfs_user: {self.hdfs_user}, hdfs_home: {self.hdfs_home}, hdfs_url: {self.hdfs_url}, " \ + f"enable_krb5_auth: {self.enable_krb5_auth}, hdfs_auth_principal: {self.hdfs_auth_principal}" + + def load_config(self, config: dict, logger): + self.hdfs_url = common_func.get_config_value( + 'HDFS_URL', None, config, True) + self.hdfs_user = common_func.get_config_value( + 'HDFS_USER', self.DEFAULT_HDFS_USER, config, False) + self.hdfs_home = common_func.get_config_value( + "HDFS_HOME", os.path.join(self.DEFAULT_HDFS_USER_PATH, self.hdfs_user), config, False) + + # the auth information + self.enable_krb5_auth = common_func.get_config_value( + "HDFS_ENABLE_AUTH", False, config, False) + require_auth_info = False + if self.enable_krb5_auth is True: + require_auth_info = True + # the principal + self.hdfs_auth_principal = common_func.get_config_value( + "HDFS_AUTH_PRINCIPAL", None, config, require_auth_info + ) + # the password + self.hdfs_auth_password = common_func.get_config_value( + "HDFS_AUTH_PASSWORD", None, config, require_auth_info) + # the hostname override + self.hdfs_hostname_override = common_func.get_config_value( + "HDFS_HOSTNAME_OVERRIDE", None, config, require_auth_info) + if logger is not None: + logger.info(f"*** load hdfs storage config : {self}") + else: + print(f"*** load hdfs storage config : {self}") + self._check() + + def _check(self): + common_func.require_non_empty("HDFS_URL", self.hdfs_url) + common_func.require_non_empty("HDFS_USER", self.hdfs_user) + common_func.require_non_empty("HDFS_HOME", self.hdfs_home) + + +class StorageApi(ABC): + @abstractmethod + def download_file(self, storage_path: str, local_file_path: str, enable_cache=False): + pass + + @abstractmethod + def upload_file(self, local_file_path: str, storage_path: str, owner=None, group=None): + pass + + @abstractmethod + def make_file_path(self, storage_path: str): + pass + + @abstractmethod + def delete_file(self, storage_path: str): + pass + + @abstractmethod + def save_data(self, data: AnyStr, storage_path: str): + pass + + @abstractmethod + def get_data(self, storage_path: str) -> AnyStr: + pass + + @abstractmethod + def mkdir(self, storage_path: str): + pass + + @abstractmethod + def file_existed(self, storage_path: str) -> bool: + pass + + @abstractmethod + def file_rename(self, old_storage_path: str, storage_path: str): + pass + + @abstractmethod + def storage_type(self): + pass + + @abstractmethod + def get_home_path(self): + return "" diff --git a/python/ppc_common/deps_services/storage_loader.py b/python/ppc_common/deps_services/storage_loader.py new file mode 100644 index 00000000..959d6e78 --- /dev/null +++ b/python/ppc_common/deps_services/storage_loader.py @@ -0,0 +1,21 @@ +from ppc_common.deps_services.storage_api import StorageType +from ppc_common.deps_services.storage_api import HDFSStorageConfig +from ppc_common.deps_services.hdfs_storage import HdfsStorage +from ppc_common.deps_services.krb5_hdfs_storage import Krb5HdfsStorage + + +class HDFSStorageLoader: + @staticmethod + def load(hdfs_config: HDFSStorageConfig, logger): + if hdfs_config.enable_krb5_auth is False: + return HdfsStorage(hdfs_config) + return Krb5HdfsStorage(hdfs_config, logger) + + +def load(config: dict, logger): + if config['STORAGE_TYPE'] == StorageType.HDFS.value: + hdfs_config = HDFSStorageConfig() + hdfs_config.load_config(config, logger) + return HDFSStorageLoader.load(hdfs_config, logger) + else: + raise Exception('unsupported storage type') diff --git a/python/ppc_common/deps_services/tests/hdfs_storage_test.py b/python/ppc_common/deps_services/tests/hdfs_storage_test.py new file mode 100644 index 00000000..0618b04b --- /dev/null +++ b/python/ppc_common/deps_services/tests/hdfs_storage_test.py @@ -0,0 +1,49 @@ +# -*- coding: utf-8 -*- +import unittest +from ppc_common.deps_services.storage_api import HDFSStorageConfig +from ppc_common.deps_services.storage_loader import HDFSStorageLoader +import logging + + +class HDFSStorageWrapper: + def __init__(self): + self.logger = logging.getLogger("HDFSStorageWrapper") + # use the default config + hdfs_url = "http://127.0.0.1:50070" + hdfs_user = "root" + hdfs_home = "/user/ppc" + enable_krb5_auth = True + hdfs_auth_principal = "root@NODE.DC1.CONSUL" + hdfs_auth_password = "root" + hdfs_hostname_override = "wedpr-0001" + self.hdfs_config = HDFSStorageConfig( + hdfs_url=hdfs_url, hdfs_user=hdfs_user, + hdfs_home=hdfs_home, enable_krb5_auth=enable_krb5_auth, + hdfs_auth_principal=hdfs_auth_principal, + hdfs_auth_password=hdfs_auth_password, + hdfs_hostname_override=hdfs_hostname_override) + self.hdfs_storage = HDFSStorageLoader.load( + self.hdfs_config, self.logger) + + def test_file_op(self, file_path): + hdfs_file_path = f"test/{file_path}" + print(f"*** upload file test ***") + self.hdfs_storage.upload_file( + local_file_path=file_path, hdfs_path=hdfs_file_path) + print(f"*** upload file test success***") + print(f"*** download file test ***") + local_file_path = f"{file_path}.download" + self.hdfs_storage.download_file( + hdfs_path=hdfs_file_path, local_file_path=local_file_path) + print(f"*** download file test success ***") + + +class TestHDFSStorage(unittest.TestCase): + def test_file_op(self): + file_path = "test.csv" + wrapper = HDFSStorageWrapper() + wrapper.test_file_op(file_path) + + +if __name__ == '__main__': + unittest.main() diff --git a/python/ppc_common/deps_services/tests/mysql_storage_test.py b/python/ppc_common/deps_services/tests/mysql_storage_test.py new file mode 100644 index 00000000..b0854d7a --- /dev/null +++ b/python/ppc_common/deps_services/tests/mysql_storage_test.py @@ -0,0 +1,104 @@ +# -*- coding: utf-8 -*- + +import unittest +from ppc_common.deps_services.mysql_storage import MySQLStorage +from ppc_common.deps_services.sql_storage_api import SQLStorageConfig +from ppc_common.db_models.file_object_meta import FileObjectMeta +import threading + + +class MySQLStorageWrapper: + def __init__(self): + # use the default config + self.engine_url = "mysql://root:12345678@127.0.0.1:3306/ppc?autocommit=true&charset=utf8mb4" + self.sql_storage_config = SQLStorageConfig(url=self.engine_url) + self.sql_storage = MySQLStorage(self.sql_storage_config) + + def single_thread_test(self, thread_name, path, ut_obj): + print(f"# begin test for thread: {thread_name}, path: {path}") + record_num = 100 + # insert records + file_count_set = set() + for i in range(0, record_num): + tmp_path = path + "_" + str(i) + file_object_meta = FileObjectMeta(file_path=tmp_path, file_count=i) + self.sql_storage.merge(file_object_meta) + file_count_set.add(i) + # query records + result_list = self.sql_storage.query( + FileObjectMeta, FileObjectMeta.file_path.startswith(path)) + ut_obj.assertEqual(result_list.count(), record_num) + # check the file_count + for item in result_list: + ut_obj.assertTrue(item.file_count in file_count_set) + # check the path + expected_path = path + "_" + str(item.file_count) + ut_obj.assertEqual(item.file_path, expected_path) + file_count_set.remove(item.file_count) + ut_obj.assertEqual(len(file_count_set), 0) + # update the file_count + delta = 100 + for i in range(0, record_num): + tmp_path = path + "_" + str(i) + file_count = i + delta + file_object_meta = FileObjectMeta( + file_path=tmp_path, file_count=file_count) + self.sql_storage.merge(file_object_meta) + file_count_set.add(file_count) + # query and check + result_list = self.sql_storage.query( + FileObjectMeta, FileObjectMeta.file_path.startswith(path)) + ut_obj.assertEqual(result_list.count(), record_num) + for item in result_list: + ut_obj.assertTrue(item.file_count in file_count_set) + # check the path + expected_path = path + "_" + str(item.file_count - delta) + ut_obj.assertEqual(item.file_path, expected_path) + file_count_set.remove(item.file_count) + ut_obj.assertEqual(len(file_count_set), 0) + # delete test + tmp_path = path + "_0" + self.sql_storage.delete( + FileObjectMeta, FileObjectMeta.file_path == tmp_path) + result_list = self.sql_storage.query( + FileObjectMeta, FileObjectMeta.file_path == tmp_path) + ut_obj.assertEqual(result_list.count(), 0) + result_list = self.sql_storage.query( + FileObjectMeta, FileObjectMeta.file_path.startswith(path)) + ut_obj.assertEqual(result_list.count(), record_num - 1) + # delete all data throw raw sql + self.sql_storage.execute( + f"delete from t_file_object where file_path like '{path}%'") + result_list = self.sql_storage.query( + FileObjectMeta, FileObjectMeta.file_path.startswith(path)) + ut_obj.assertEqual(result_list.count(), 0) + print(f"# test for thread: {thread_name}, path: {path} success") + + +class TestMySQLStorage(unittest.TestCase): + def test_single_thread(self): + wrapper = MySQLStorageWrapper() + path = "a/b/c/test_single_thread.csv" + wrapper.single_thread_test(path, "single_thread", self) + + def test_multi_thread(self): + loops = 5 + for j in range(loops): + thread_list = [] + thread_num = 20 + path = "a/b/c/test_multi_thread.csv" + wrapper = MySQLStorageWrapper() + for i in range(thread_num): + thread_name = "job_" + str(i) + tmp_path = "thread_" + str(i) + "_" + path + t = threading.Thread(target=wrapper.single_thread_test, name=thread_name, args=( + thread_name, tmp_path, self,)) + thread_list.append(t) + for t in thread_list: + t.start() + for t in thread_list: + t.join() + + +if __name__ == '__main__': + unittest.main() diff --git a/python/ppc_common/ppc_async_executor/__init__.py b/python/ppc_common/ppc_async_executor/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/python/ppc_common/ppc_async_executor/async_executor.py b/python/ppc_common/ppc_async_executor/async_executor.py new file mode 100644 index 00000000..3b151b3e --- /dev/null +++ b/python/ppc_common/ppc_async_executor/async_executor.py @@ -0,0 +1,36 @@ +from abc import ABC +from typing import Callable + + +class AsyncExecutor(ABC): + def execute(self, + job_id: str, + task_id: str, + target: Callable, + on_target_finish: Callable[[str, bool, Exception], None], + args=()): + """ + 启动一个新进程/线程执行指定的目标函数。 + :param task_id: 任务id + :param target: 目标函数 + :param on_target_finish: 目标函数函数退出后的回调 + :param args: 函数的参数元组 + """ + pass + + def kill(self, task_id: str) -> bool: + """ + 强制终止目标函数。 + :param task_id: 任务id + :return 是否成功 + """ + pass + + def kill_all(self): + """ + 强制终止所有目标函数。 + """ + pass + + def __del__(self): + self.kill_all() diff --git a/python/ppc_common/ppc_async_executor/async_subprocess_executor.py b/python/ppc_common/ppc_async_executor/async_subprocess_executor.py new file mode 100644 index 00000000..afff9950 --- /dev/null +++ b/python/ppc_common/ppc_async_executor/async_subprocess_executor.py @@ -0,0 +1,60 @@ +import multiprocessing +import threading +import time +from typing import Callable + +from ppc_common.ppc_async_executor.async_executor import AsyncExecutor + + +class AsyncSubprocessExecutor(AsyncExecutor): + def __init__(self, logger): + self.logger = logger + self.processes = {} + self.lock = threading.Lock() + self._cleanup_thread = threading.Thread(target=self._loop_cleanup) + self._cleanup_thread.daemon = True + self._cleanup_thread.start() + + def execute(self, target_id: str, target: Callable, on_target_finish: Callable[[str, bool, Exception], None], + args=()): + process = multiprocessing.Process(target=target, args=args) + process.start() + with self.lock: + self.processes[target_id] = process + + def kill(self, target_id: str): + with self.lock: + if target_id not in self.processes: + return False + else: + process = self.processes[target_id] + + process.terminate() + self.logger.info(f"Target {target_id} has been terminated!") + return True + + def kill_all(self): + with self.lock: + keys = self.processes.keys() + + for target_id in keys: + self.kill(target_id) + + def _loop_cleanup(self): + while True: + self._cleanup_finished_processes() + time.sleep(3) + + def _cleanup_finished_processes(self): + with self.lock: + finished_processes = [ + (target_id, proc) for target_id, proc in self.processes.items() if not proc.is_alive()] + + for target_id, process in finished_processes: + with self.lock: + process.join() # 确保进程资源释放 + del self.processes[target_id] + self.logger.info(f"Cleanup finished process {target_id}") + + def __del__(self): + self.kill_all() diff --git a/python/ppc_common/ppc_async_executor/async_thread_executor.py b/python/ppc_common/ppc_async_executor/async_thread_executor.py new file mode 100644 index 00000000..04fa1756 --- /dev/null +++ b/python/ppc_common/ppc_async_executor/async_thread_executor.py @@ -0,0 +1,101 @@ +import threading +import inspect +import ctypes +import time +import traceback +from typing import Callable + +from ppc_common.ppc_async_executor.async_executor import AsyncExecutor +from ppc_common.ppc_async_executor.thread_event_manager import ThreadEventManager + + +class AsyncThreadExecutor(AsyncExecutor): + def __init__(self, event_manager: ThreadEventManager, logger): + self.event_manager = event_manager + self.logger = logger + self.threads = {} + self.lock = threading.Lock() + self._cleanup_thread = threading.Thread(target=self._loop_cleanup) + self._cleanup_thread.daemon = True + self._cleanup_thread.start() + + def execute(self, job_id: str, target_id: str, + target: Callable, on_target_finish: Callable[[str, bool, Exception], None], + args=()): + def thread_target(logger, on_finish, *args): + try: + target(target_id, *args) + on_finish(target_id, True) + except Exception as e: + error_detail = traceback.format_exc().replace('\n', + f'\n{job_id}.{target_id}') + logger.warn( + f"Execute task: {target_id} error, job: {job_id}, error: {e}, traceback: {error_detail}") + on_finish(target_id, False, error_detail) + + thread = threading.Thread(target=thread_target, args=( + self.logger, on_target_finish) + args) + thread.start() + + with self.lock: + self.threads[target_id] = thread + + stop_event = threading.Event() + self.event_manager.add_event(target_id, stop_event) + + def _thread_exit_(self, thread, exit_type): + """Raises an exception in the threads with id tid""" + thread_id = thread.ident + if not inspect.isclass(exit_type): + raise TypeError("Only types can be raised (not instances)") + res = ctypes.pythonapi.PyThreadState_SetAsyncExc( + ctypes.c_long(thread_id), ctypes.py_object(exit_type)) + if res == 0: + self.logger.warn("Invalid thread id") + elif res != 1: + # """if it returns a number greater than one, you're in trouble, + # and you should call it again with exc=NULL to revert the effect""" + ctypes.pythonapi.PyThreadState_SetAsyncExc(thread_id, None) + self.logger.warn("PyThreadState_SetAsyncExc failed") + raise SystemError("PyThreadState_SetAsyncExc failed") + self.logger.info(f"thread_exit success, thread_id: {thread_id}") + + def kill(self, target_id: str): + with self.lock: + if target_id not in self.threads: + return False + else: + thread = self.threads[target_id] + self.event_manager.set_event(target_id) + self._thread_exit_(thread, SystemExit) + thread.join() + # clear the thread information + with self.lock: + self.threads.pop(target_id) + self.logger.info(f"Target {target_id} has been stopped!") + return True + + def kill_all(self): + with self.lock: + keys = self.threads.keys() + + for target_id in keys: + self.kill(target_id) + + def _loop_cleanup(self): + while True: + self._cleanup_finished_threads() + time.sleep(3) + + def _cleanup_finished_threads(self): + with self.lock: + finished_threads = [ + target_id for target_id, thread in self.threads.items() if not thread.is_alive()] + + for target_id in finished_threads: + with self.lock: + del self.threads[target_id] + self.logger.info(f"Cleanup finished thread {target_id}") + + def __del__(self): + self.kill_all() diff --git a/python/ppc_common/ppc_async_executor/test/__init__.py b/python/ppc_common/ppc_async_executor/test/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/python/ppc_common/ppc_async_executor/test/async_executor_unittest.py b/python/ppc_common/ppc_async_executor/test/async_executor_unittest.py new file mode 100644 index 00000000..b59122ab --- /dev/null +++ b/python/ppc_common/ppc_async_executor/test/async_executor_unittest.py @@ -0,0 +1,109 @@ +import multiprocessing +import time +import unittest + +# 示例用法 +from ppc_common.ppc_async_executor.async_subprocess_executor import AsyncSubprocessExecutor +from ppc_common.ppc_async_executor.async_thread_executor import AsyncThreadExecutor +from ppc_common.ppc_async_executor.thread_event_manager import ThreadEventManager +from ppc_common.ppc_mock.mock_objects import MockLogger + + +def task1(shared_status1, key, dur): + shared_status1[key] = 1 + time.sleep(dur) + shared_status1[key] = 2 + + +def task2(shared_status2, key, dur): + shared_status2[key] = 1 + time.sleep(dur) + shared_status2[key] = 2 + + +def on_target_finish(task_id, flag, e=None): + if flag: + print(f'{task_id}, success') + else: + print(f'{task_id}, failed, {e}') + + +class TestSubprocessExecutor(unittest.TestCase): + + def test_kill(self): + logger = MockLogger() + executor = AsyncSubprocessExecutor(logger) + + # 使用 Manager 来创建共享状态字典 + manager = multiprocessing.Manager() + shared_status1 = manager.dict() + shared_status2 = manager.dict() + + # 启动两个任务 + key = 'test_kill' + executor.execute('0xaa', task1, on_target_finish, + (shared_status1, key, 2)) + executor.execute('0xbb', task2, on_target_finish, + (shared_status2, key, 2)) + + time.sleep(1) + + # 终止一个任务 + if executor.kill('0xaa'): + print(f"Task {'0xaa'} has been terminated") + + # 等待一段时间 + time.sleep(3) + + self.assertEqual(shared_status1.get(key, None), 1) + self.assertEqual(shared_status2.get(key, None), 2) + + +thread_event_manager = ThreadEventManager() + + +def thread_task1(shared_status1, task_id, key, dur): + shared_status1[key] = 1 + while not thread_event_manager.event_status(task_id): + time.sleep(dur) + shared_status1[key] = 2 + + +def thread_task2(shared_status2, key, dur): + shared_status2[key] = 1 + time.sleep(dur) + shared_status2[key] = 2 + raise Exception("raise error") + + +class TestThreadExecutor(unittest.TestCase): + + def test_kill(self): + logger = MockLogger() + executor = AsyncThreadExecutor(thread_event_manager, logger) + + shared_status1 = {'test': 'test'} + shared_status2 = {'test': 'test'} + key = 'test_kill' + task_id_1 = '0xaa' + task_id_2 = '0xbb' + + executor.execute("job1", task_id_1, thread_task1, on_target_finish, + (shared_status1, task_id_1, key, 1)) + executor.execute("job2", task_id_2, thread_task2, + on_target_finish, (shared_status2, key, 1)) + + time.sleep(2) + + # 终止一个任务 + if executor.kill(task_id_1): + print(f"Task {task_id_1} has been terminated") + + # 等待一段时间 + time.sleep(1) + self.assertEqual(shared_status1.get(key, None), 2) + self.assertEqual(shared_status2.get(key, None), 2) + + +if __name__ == '__main__': + unittest.main() diff --git a/python/ppc_common/ppc_async_executor/thread_event_manager.py b/python/ppc_common/ppc_async_executor/thread_event_manager.py new file mode 100644 index 00000000..b78a7883 --- /dev/null +++ b/python/ppc_common/ppc_async_executor/thread_event_manager.py @@ -0,0 +1,34 @@ +import threading +from typing import Dict + +from readerwriterlock import rwlock + + +class ThreadEventManager: + def __init__(self): + # Event清理由TaskManager完成 + self.events: Dict[str, threading.Event] = {} + self.rw_lock = rwlock.RWLockWrite() + + def add_event(self, target_id: str, event: threading.Event) -> None: + with self.rw_lock.gen_wlock(): + self.events[target_id] = event + + def remove_event(self, target_id: str): + with self.rw_lock.gen_wlock(): + if target_id in self.events: + del self.events[target_id] + + def set_event(self, target_id: str): + with self.rw_lock.gen_wlock(): + if target_id in self.events: + self.events[target_id].set() + else: + raise KeyError(f"Target id {target_id} not found") + + def event_status(self, target_id: str) -> bool: + with self.rw_lock.gen_rlock(): + if target_id in self.events: + return self.events[target_id].is_set() + else: + return False diff --git a/python/ppc_common/ppc_config/__init__.py b/python/ppc_common/ppc_config/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/python/ppc_common/ppc_config/file_chunk_config.py b/python/ppc_common/ppc_config/file_chunk_config.py new file mode 100644 index 00000000..80049ce4 --- /dev/null +++ b/python/ppc_common/ppc_config/file_chunk_config.py @@ -0,0 +1,27 @@ +# -*- coding: utf-8 -*- +from ppc_common.ppc_utils import common_func + + +class FileChunkConfig: + # default read chunk size is 512M + DEFAULT_READ_CHUNK_SIZE = 512 + # default file object chunk size is 2G + DEFAULT_FILE_OBJECT_CHUNK_SIZE = 2048 + + READ_CHUNK_SIZE_MB_KEY = "read_chunk_size_mb" + FILE_CHUNK_SIZE_MB_KEY = "file_chunk_size_mb" + ENABLE_ALL_CHUNCK_FILE_MGR_KEY = "enable_file_chunk_on_all_mode" + + def __init__(self, config): + read_chunk_size = common_func.get_config_value( + FileChunkConfig.READ_CHUNK_SIZE_MB_KEY, + FileChunkConfig.DEFAULT_READ_CHUNK_SIZE, + config, False) + self.read_chunk_size = int(read_chunk_size) * 1024 * 1024 + file_object_chunk_size = common_func.get_config_value( + FileChunkConfig.FILE_CHUNK_SIZE_MB_KEY, + FileChunkConfig.DEFAULT_FILE_OBJECT_CHUNK_SIZE, config, False) + self.file_object_chunk_size = int(file_object_chunk_size) * 1024 * 1024 + self.enable_file_chunk_on_all_mode = common_func.get_config_value( + FileChunkConfig.ENABLE_ALL_CHUNCK_FILE_MGR_KEY, + False, config, False) diff --git a/python/ppc_common/ppc_config/sql_storage_config_loader.py b/python/ppc_common/ppc_config/sql_storage_config_loader.py new file mode 100644 index 00000000..9ed1cf3b --- /dev/null +++ b/python/ppc_common/ppc_config/sql_storage_config_loader.py @@ -0,0 +1,37 @@ +# -*- coding: utf-8 -*- + +from ppc_common.deps_services.sql_storage_api import SQLStorageConfig +from ppc_common.ppc_utils import common_func + + +class SQLStorageConfigLoader: + POOL_RECYCLE_KEY = "SQL_POOL_RECYCLE_SECONDS" + POOL_SIZE_KEY = "SQL_POOL_SIZE" + MAX_OVERFLOW_KEY = "SQL_MAX_OVERFLOW_SIZE" + POOL_TIMEOUT_KEY = "SQL_POOL_TIMEOUT_SECONDS" + DATABASE_URL_KEY = "SQLALCHEMY_DATABASE_URI" + DATABASE_TYPE_KEY = "DB_TYPE" + DATABASE_NAME_KEY = "DB_NAME" + + @staticmethod + def load(config): + db_url = common_func.get_config_value( + SQLStorageConfigLoader.DATABASE_URL_KEY, None, config, True) + db_type = common_func.get_config_value( + SQLStorageConfigLoader.DATABASE_TYPE_KEY, None, config, True) + db_name = common_func.get_config_value( + SQLStorageConfigLoader.DATABASE_NAME_KEY, None, config, False) + pool_recycle = common_func.get_config_value( + SQLStorageConfigLoader.POOL_RECYCLE_KEY, None, config, False) + pool_size = common_func.get_config_value( + SQLStorageConfigLoader.POOL_SIZE_KEY, None, config, False) + max_overflow = common_func.get_config_value( + SQLStorageConfigLoader.MAX_OVERFLOW_KEY, None, config, False) + pool_timeout = common_func.get_config_value( + SQLStorageConfigLoader.POOL_TIMEOUT_KEY, None, config, False) + return SQLStorageConfig( + pool_recycle=pool_recycle, + pool_size=pool_size, + max_overflow=max_overflow, + pool_timeout=pool_timeout, + url=db_url, db_type=db_type, db_name=db_name) diff --git a/python/ppc_common/ppc_crypto/__init__.py b/python/ppc_common/ppc_crypto/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/python/ppc_common/ppc_crypto/crypto_utils.py b/python/ppc_common/ppc_crypto/crypto_utils.py new file mode 100644 index 00000000..43a13aaa --- /dev/null +++ b/python/ppc_common/ppc_crypto/crypto_utils.py @@ -0,0 +1,130 @@ +import binascii + +import base64 +import random +from Crypto.Cipher import AES +from Crypto.Cipher import PKCS1_v1_5 as Cipher_PKCS1_v1_5 +from Crypto.PublicKey import RSA + +from ppc_common.config import CONFIG_DATA + +try: + import gmpy2 + + IS_GMP = True +except ImportError: + IS_GMP = False + +_USE_MOD_GMP_SIZE = (1 << (8 * 2)) +_USE_MULMOD_GMP_SIZE = (1 << 1000) + +RSA_PUBLIC_HEADER = "-----BEGIN PUBLIC KEY-----" +RSA_PUBLIC_END = "-----END PUBLIC KEY-----" + +RSA_PRIVATE_HEADER = "-----BEGIN RSA PRIVATE KEY-----" +RSA_PRIVATE_END = "-----END RSA PRIVATE KEY-----" + + +def powmod(a, b, c): + if a == 1: + return 1 + if not IS_GMP or max(a, b, c) < _USE_MOD_GMP_SIZE: + return pow(a, b, c) + else: + return int(gmpy2.powmod(a, b, c)) + + +def mulmod(a, b, c): + if not IS_GMP or max(a, b, c) < _USE_MULMOD_GMP_SIZE: + return a * b % c + else: + a, b, c = gmpy2.mpz(a), gmpy2.mpz(b), gmpy2.mpz(c) + return int(gmpy2.mod(gmpy2.mul(a, b), c)) + + +DEFAULT_KEYSIZE = 1024 +DEFAULT_G = 9020881489161854992071763483314773468341853433975756385639545080944698236944020124874820917267762049756743282301106459062535797137327360192691469027152272 +DEFAULT_N = 102724610959913950919762303151320427896415051258714708724768326174083057407299433043362228762657118029566890747043004760241559786931866234640457856691885212534669604964926915306738569799518792945024759514373214412797317972739022405456550476153212687312211184540248262330559143446510677062823907392904449451177 +DEFAULT_FI = 102724610959913950919762303151320427896415051258714708724768326174083057407299433043362228762657118029566890747043004760241559786931866234640457856691885192126363163670343672910761259882348623401714459980712242233796355982147797162316532450768783823909695360736554767341443201861573989081253763975895939627220 + +# OUTPUT_BIT_LENGTH = 128 +OUTPUT_BIT_LENGTH = CONFIG_DATA['MPC_BIT_LENGTH'] +DEFAULT_MPC_N = pow(2, OUTPUT_BIT_LENGTH) + + +# DEFAULT_MPC_N = DEFAULT_N + +def ot_base_pown(value): + return powmod(DEFAULT_G, value, DEFAULT_N) + + +def ot_pown(base, value): + return powmod(base, value, DEFAULT_N) + + +def ot_mul_fi(a_val, b_val): + return mulmod(a_val, b_val, DEFAULT_FI) + + +def ot_mul_n(a_val, b_val): + return mulmod(a_val, b_val, DEFAULT_N) + + +# def ot_add(a_val, b_val): +# return (a_val + b_val)%DEFAULT_N + + +def ot_str_to_int(input_str): + return int.from_bytes(input_str.encode('utf-8'), 'big'), len(input_str) + + +def ot_int_to_str(input_int, len_input_str): + # len_int = len(str(input_int))//2 + result = input_int.to_bytes(len_input_str, 'big').decode('utf-8') + # TODO: check all 0x00 valid + # if result[0].encode('ascii') == b'\x00': + # result = result[1:] + return result + + +def get_random_int(): + return random.SystemRandom().randrange(1, DEFAULT_N) + + +def make_rsa_decrypt(encrypted_hex, private_key): + if RSA_PRIVATE_HEADER not in private_key: + private_key = RSA_PRIVATE_HEADER + "\n" + private_key + if RSA_PRIVATE_END not in private_key: + private_key = private_key + "\n" + RSA_PRIVATE_END + rsa_private_key = RSA.importKey(private_key) + encrypted_text = binascii.unhexlify(encrypted_hex) + cipher = Cipher_PKCS1_v1_5.new(rsa_private_key) + decrypted_text = cipher.decrypt(encrypted_text, None) + return decrypted_text.decode('utf-8') + + +class AESCipher: + + def __init__(self, key): + # self.key = bytes(key, 'utf-8') + self.key = key + + def encrypt(self, raw): + raw = pad(raw) + iv = "encryptionIntVec".encode('utf-8') + cipher = AES.new(self.key, AES.MODE_CBC, iv) + return base64.b64encode(cipher.encrypt(raw)) + + def decrypt(self, enc): + iv = "encryptionIntVec".encode('utf-8') + enc = base64.b64decode(enc) + cipher = AES.new(self.key, AES.MODE_CBC, iv) + return unpad(cipher.decrypt(enc)).decode('utf8') + + +BS = 16 +def pad(s): return bytes(s + (BS - len(s) % + BS) * chr(BS - len(s) % BS), 'utf-8') + + +def unpad(s): return s[0:-ord(s[-1:])] diff --git a/python/ppc_common/ppc_crypto/ihc_cipher.py b/python/ppc_common/ppc_crypto/ihc_cipher.py new file mode 100644 index 00000000..0ac4723f --- /dev/null +++ b/python/ppc_common/ppc_crypto/ihc_cipher.py @@ -0,0 +1,124 @@ +# from abc import ABC +# import namedTuple +from dataclasses import dataclass + +import struct +from ppc_common.ppc_crypto.phe_cipher import PheCipher +import secrets + + +class NumberCodec: + def __init__(self, key_length): + self.key_length = key_length + self.max_mod = 1 << key_length + self.non_negative_range = int((1 << key_length) / 3) + self.negative_range = int((1 << int(key_length + 1)) / 3) + + def encode(self, value): + if value > 0: + if value > self.non_negative_range: + raise Exception(f"The value {value} out of range") + return value + return value % self.max_mod + + def decode(self, value): + if value > self.negative_range: + return value - self.max_mod + return value + + +@dataclass +class IhcCiphertext(): + __slots__ = ['c_left', 'c_right', 'number_codec'] + + def __init__(self, c_left: int, c_right: int, number_codec: NumberCodec) -> None: + self.c_left = c_left + self.c_right = c_right + self.number_codec = number_codec + + def __add__(self, other): + cipher_left = self.c_left + other.c_left + cipher_right = self.c_right + other.c_right + return IhcCiphertext(cipher_left, cipher_right, self.number_codec) + + def __mul__(self, num: int): + num_value = self.number_codec.encode(num) + return IhcCiphertext(num_value * self.c_left, num_value * self.c_right, self.number_codec) + + def __eq__(self, other): + return self.c_left == other.c_left and self.c_right == other.c_right + + def encode(self) -> bytes: + # 计算每个整数的字节长度 + len_c_left = (self.c_left.bit_length() + 7) // 8 + len_c_right = (self.c_right.bit_length() + 7) // 8 + + # 将整数转换为字节序列,使用大端字节序和带符号整数 + c_left_bytes = self.c_left.to_bytes(len_c_left, byteorder='big') + c_right_bytes = self.c_right.to_bytes(len_c_right, byteorder='big') + + # 编码整数的长度 + len_bytes = struct.pack('>II', len_c_left, len_c_right) + + # 返回所有数据 + return len_bytes + c_left_bytes + c_right_bytes + + @classmethod + def decode(cls, encoded_data: bytes, key_length: int = 256): + # 解码整数的长度 + len_c_left, len_c_right = struct.unpack('>II', encoded_data[:8]) + + # 根据长度解码整数 + c_left = int.from_bytes( + encoded_data[8:8 + len_c_left], byteorder='big') + c_right = int.from_bytes( + encoded_data[8 + len_c_left:8 + len_c_left + len_c_right], byteorder='big') + return cls(c_left, c_right, NumberCodec(key_length)) + + +class IhcCipher(PheCipher): + def __init__(self, key_length: int = 256, iter_round: int = 16) -> None: + super().__init__(key_length) + key = secrets.randbits(key_length) + self.public_key = key + self.private_key = key + self.iter_round = iter_round + self.key_length = key_length + + self.max_mod = 1 << key_length + self.number_codec = NumberCodec(self.key_length) + + def encrypt(self, number: int) -> IhcCiphertext: + random_u = secrets.randbits(self.key_length) + x_this = self.number_codec.encode(number) + # print(f"###### x_this: {x_this}, number: {number}") + x_last = random_u + for i in range(0, self.iter_round): + x_tmp = (self.private_key * x_this - x_last) % self.max_mod + x_last = x_this + x_this = x_tmp + cipher = IhcCiphertext(x_this, x_last, self.number_codec) + return cipher + + def decrypt(self, cipher: IhcCiphertext) -> int: + x_this = cipher.c_right + x_last = cipher.c_left + for i in range(0, self.iter_round-1): + x_tmp = (self.private_key * x_this - x_last) % self.max_mod + x_last = x_this + x_this = x_tmp + result = self.number_codec.decode(x_this) + # print(f"###### x_this: {x_this}, result: {result}") + return result + + def encrypt_batch(self, numbers) -> list: + return [self.encrypt(num) for num in numbers] + + def decrypt_batch(self, ciphers) -> list: + return [self.decrypt(cipher) for cipher in ciphers] + + def encrypt_batch_parallel(self, numbers: list) -> list: + return self.encrypt_batch(numbers) + + def decrypt_batch_parallel(self, ciphers: list) -> list: + return self.decrypt_batch(ciphers) diff --git a/python/ppc_common/ppc_crypto/ihc_codec.py b/python/ppc_common/ppc_crypto/ihc_codec.py new file mode 100644 index 00000000..9de0c858 --- /dev/null +++ b/python/ppc_common/ppc_crypto/ihc_codec.py @@ -0,0 +1,29 @@ +from typing import Tuple + +from ppc_common.ppc_crypto.ihc_cipher import IhcCiphertext + + +class IhcCodec: + @staticmethod + def _int_to_bytes(x): + return x.to_bytes((x.bit_length() + 7) // 8, 'big') + + @staticmethod + def _bytes_to_int(x): + return int.from_bytes(x, 'big') + + @staticmethod + def encode_enc_key(public_key) -> bytes: + return bytes() + + @staticmethod + def decode_enc_key(public_key_bytes) -> bytes: + return bytes() + + @staticmethod + def encode_cipher(cipher: IhcCiphertext, be_secure=True) -> Tuple[bytes, bytes]: + return cipher.encode(), bytes() + + @staticmethod + def decode_cipher(enc_key, ciphertext: bytes, exponent) -> IhcCiphertext: + return IhcCiphertext.decode(ciphertext) diff --git a/python/ppc_common/ppc_crypto/paillier_cipher.py b/python/ppc_common/ppc_crypto/paillier_cipher.py new file mode 100644 index 00000000..822093be --- /dev/null +++ b/python/ppc_common/ppc_crypto/paillier_cipher.py @@ -0,0 +1,49 @@ +import math +import os +from concurrent.futures import ProcessPoolExecutor + +from phe import paillier, EncryptedNumber + +from ppc_common.ppc_crypto.phe_cipher import PheCipher + + +class PaillierCipher(PheCipher): + + def __init__(self, key_length: int = 2048) -> None: + super().__init__(key_length) + self.public_key, self.private_key = paillier.generate_paillier_keypair( + n_length=self.key_length) + + def encrypt(self, number) -> EncryptedNumber: + return self.public_key.encrypt(int(number)) + + def decrypt(self, cipher: EncryptedNumber) -> int: + return self.private_key.decrypt(cipher) + + def encrypt_batch(self, numbers) -> list: + return [self.encrypt(num) for num in numbers] + + def decrypt_batch(self, ciphers) -> list: + return [self.decrypt(cipher) for cipher in ciphers] + + def encrypt_batch_parallel(self, numbers) -> list: + num_cores = os.cpu_count() + batch_size = math.ceil(len(numbers) / num_cores) + batches = [numbers[i:i + batch_size] + for i in range(0, len(numbers), batch_size)] + with ProcessPoolExecutor(max_workers=num_cores) as executor: + futures = [executor.submit(self.encrypt_batch, batch) + for batch in batches] + result = [future.result() for future in futures] + return [item for sublist in result for item in sublist] + + def decrypt_batch_parallel(self, ciphers) -> list: + num_cores = os.cpu_count() + batch_size = math.ceil(len(ciphers) / num_cores) + batches = [ciphers[i:i + batch_size] + for i in range(0, len(ciphers), batch_size)] + with ProcessPoolExecutor(max_workers=num_cores) as executor: + futures = [executor.submit(self.decrypt_batch, batch) + for batch in batches] + result = [future.result() for future in futures] + return [item for sublist in result for item in sublist] diff --git a/python/ppc_common/ppc_crypto/paillier_codec.py b/python/ppc_common/ppc_crypto/paillier_codec.py new file mode 100644 index 00000000..d66f3c95 --- /dev/null +++ b/python/ppc_common/ppc_crypto/paillier_codec.py @@ -0,0 +1,34 @@ +from typing import Tuple + +from phe import PaillierPublicKey, paillier, EncryptedNumber + + +class PaillierCodec: + @staticmethod + def _int_to_bytes(x): + return x.to_bytes((x.bit_length() + 7) // 8, 'big') + + @staticmethod + def _bytes_to_int(x): + return int.from_bytes(x, 'big') + + @staticmethod + def encode_enc_key(public_key: PaillierPublicKey) -> bytes: + return PaillierCodec._int_to_bytes(public_key.n) + + @staticmethod + def decode_enc_key(public_key_bytes: bytes) -> PaillierPublicKey: + public_key_n = PaillierCodec._bytes_to_int(public_key_bytes) + return paillier.PaillierPublicKey(n=public_key_n) + + @staticmethod + def encode_cipher(cipher: EncryptedNumber, be_secure=True) -> Tuple[bytes, bytes]: + return PaillierCodec._int_to_bytes(cipher.ciphertext(be_secure=be_secure)), \ + PaillierCodec._int_to_bytes(cipher.exponent) + + @staticmethod + def decode_cipher(public_key: PaillierPublicKey, ciphertext: bytes, exponent: bytes) -> EncryptedNumber: + return paillier.EncryptedNumber(public_key, + PaillierCodec._bytes_to_int( + ciphertext), + PaillierCodec._bytes_to_int(exponent)) diff --git a/python/ppc_common/ppc_crypto/phe_cipher.py b/python/ppc_common/ppc_crypto/phe_cipher.py new file mode 100644 index 00000000..3581ac45 --- /dev/null +++ b/python/ppc_common/ppc_crypto/phe_cipher.py @@ -0,0 +1,25 @@ +from abc import ABC + + +class PheCipher(ABC): + def __init__(self, key_length: int) -> None: + self.key_length = key_length + pass + + def encrypt(self, number: int): + pass + + def decrypt(self, cipher) -> int: + pass + + def encrypt_batch(self, numbers: list) -> list: + pass + + def decrypt_batch(self, ciphers: list) -> list: + pass + + def encrypt_batch_parallel(self, numbers: list) -> list: + pass + + def decrypt_batch_parallel(self, ciphers: list) -> list: + pass diff --git a/python/ppc_common/ppc_crypto/phe_factory.py b/python/ppc_common/ppc_crypto/phe_factory.py new file mode 100644 index 00000000..5db01063 --- /dev/null +++ b/python/ppc_common/ppc_crypto/phe_factory.py @@ -0,0 +1,25 @@ +from ppc_common.ppc_crypto.ihc_cipher import IhcCipher +from ppc_common.ppc_crypto.ihc_codec import IhcCodec +from ppc_common.ppc_crypto.paillier_cipher import PaillierCipher +from ppc_common.ppc_crypto.paillier_codec import PaillierCodec + + +class PheCipherFactory(object): + + @staticmethod + def build_phe(homo_algorithm=0, key_length=2048): + if homo_algorithm == 0: + return IhcCipher() + if homo_algorithm == 1: + return PaillierCipher(key_length) + else: + raise ValueError("Unsupported homo algorithm") + + @staticmethod + def build_codec(homo_algorithm=0): + if homo_algorithm == 0: + return IhcCodec() + if homo_algorithm == 1: + return PaillierCodec() + else: + raise ValueError("Unsupported homo algorithm") diff --git a/python/ppc_common/ppc_crypto/test/__init__.py b/python/ppc_common/ppc_crypto/test/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/python/ppc_common/ppc_crypto/test/phe_unittest.py b/python/ppc_common/ppc_crypto/test/phe_unittest.py new file mode 100644 index 00000000..db610243 --- /dev/null +++ b/python/ppc_common/ppc_crypto/test/phe_unittest.py @@ -0,0 +1,168 @@ +import time +import unittest + +import numpy as np + +from ppc_common.ppc_crypto.ihc_cipher import IhcCipher, IhcCiphertext +from ppc_common.ppc_crypto.ihc_codec import IhcCodec +from ppc_common.ppc_crypto.paillier_cipher import PaillierCipher + + +class HomoTest: + def __init__(self, ut): + self.paillier = PaillierCipher(key_length=1024) + self.ihc_cipher = IhcCipher(key_length=1024) + self.ut = ut + + def test_enc_and_dec_parallel(self, homo_impl, test_size, start, end): + inputs = np.random.randint(start, end, size=test_size) + + # start_time = time.time() + # paillier.encrypt_batch(inputs) + # end_time = time.time() + # print("enc:", end_time - start_time, "seconds") + + start_time = time.time() + ciphers = homo_impl.encrypt_batch_parallel(inputs) + end_time = time.time() + print("enc_p:", end_time - start_time, "seconds") + + start_time = time.time() + outputs = homo_impl.decrypt_batch_parallel(ciphers) + end_time = time.time() + print("dec_p:", end_time - start_time, "seconds") + + self.ut.assertListEqual(list(inputs), list(outputs)) + self.test_homo_mul_enc_and_dec(homo_impl, ciphers, inputs, 10) + # test add and enc dec + inputs2 = np.random.randint(start, end, size=test_size) + ciphers2 = homo_impl.encrypt_batch_parallel(inputs2) + self.test_homo_add_enc_and_desc( + homo_impl, ciphers, ciphers2, inputs, inputs2) + + def test_homo_mul_enc_and_dec(self, homo_impl, ciphers, inputs, mul_value): + start_time = time.time() + mul_ciphers = [] + for cipher in ciphers: + mul_ciphers.append(cipher * mul_value) + # decrypt + outputs = homo_impl.decrypt_batch_parallel(mul_ciphers) + mul_result = [] + for input in inputs: + mul_result.append(mul_value * input) + self.ut.assertListEqual(mul_result, list(outputs)) + end_time = time.time() + print( + f"#### test_homo_mul_enc_and_dec passed, time: {end_time - start_time} seconds") + + def test_homo_add_enc_and_desc(self, homo_impl, ciphers1, ciphers2, inputs1, inputs2): + start_time = time.time() + add_ciphers = [] + i = 0 + expected_result = [] + for cipher in ciphers1: + add_ciphers.append(cipher + ciphers2[i]) + expected_result.append(inputs1[i] + inputs2[i]) + i += 1 + outputs = homo_impl.decrypt_batch_parallel(add_ciphers) + self.ut.assertListEqual(expected_result, list(outputs)) + end_time = time.time() + print( + f"#### test_homo_add_enc_and_desc passed, time: {end_time - start_time} seconds, size: {len(inputs1)}") + + +class PaillierUtilsTest(unittest.TestCase): + def test_paillier_enc_and_dec(self): + print("######## test paillier case: ####") + homo_test = HomoTest(self) + homo_test.test_enc_and_dec_parallel(homo_test.paillier, 10, -20, -1) + homo_test.test_enc_and_dec_parallel( + homo_test.paillier, 10000, -20000, 20000) + homo_test.test_enc_and_dec_parallel( + homo_test.paillier, 10000, 0, 20000) + print("######## test paillier case end ####") + + def test_ihc_enc_and_dec(self): + print("######## test ihc case: ####") + homo_test = HomoTest(self) + homo_test.test_enc_and_dec_parallel(homo_test.ihc_cipher, 10, -20, -1) + homo_test.test_enc_and_dec_parallel( + homo_test.ihc_cipher, 10000, -20000, 20000) + homo_test.test_enc_and_dec_parallel( + homo_test.ihc_cipher, 10000, 0, 20000) + print("######## test ihc case end ####") + + def test_ihc_enc_and_dec_parallel(self): + print("##### test_ihc_enc_and_dec_parallel") + ihc = IhcCipher(key_length=256) + try_size = 100000 + inputs = np.random.randint(-10001, 10001, size=try_size) + expected = np.sum(inputs) + + start_time = time.time() + ciphers = ihc.encrypt_batch_parallel(inputs) + end_time = time.time() + print( + f"size:{try_size}, enc_p: {end_time - start_time} seconds, " + f"average times: {(end_time - start_time) / try_size * 1000 * 1000} us") + + start_time = time.time() + cipher_start = ciphers[0] + for i in range(1, len(ciphers)): + cipher_left = (cipher_start.c_left + ciphers[i].c_left) + cipher_right = (cipher_start.c_right + ciphers[i].c_right) + # IhcCiphertext(cipher_left, cipher_right, cipher_start.max_mod) + IhcCiphertext(cipher_left, cipher_right, ihc.number_codec) + end_time = time.time() + print(f"size:{try_size}, add_p raw with class: {end_time - start_time} seconds, average times: {(end_time - start_time)/try_size * 1000 * 1000} us") + + start_time = time.time() + cipher_start = ciphers[0] + for i in range(1, len(ciphers)): + cipher_left = (cipher_start.c_left + ciphers[i].c_left) + cipher_right = (cipher_start.c_right + ciphers[i].c_right) + # IhcCiphertext(cipher_left, cipher_right) + end_time = time.time() + print(f"size:{try_size}, add_p raw: {end_time - start_time} seconds, average times: {(end_time - start_time)/try_size * 1000 * 1000} us") + + start_time = time.time() + cipher_start = ciphers[0] + for i in range(1, len(ciphers)): + cipher_start = cipher_start + ciphers[i] + end_time = time.time() + print( + f"size:{try_size}, add_p: {end_time - start_time} seconds, " + f"average times: {(end_time - start_time) / try_size * 1000 * 1000} us") + + start_time = time.time() + outputs = ihc.decrypt_batch_parallel(ciphers) + end_time = time.time() + print( + f"size:{try_size}, dec_p: {end_time - start_time} seconds, " + f"average times: {(end_time - start_time) / try_size * 1000 * 1000} us") + + decrypted = ihc.decrypt(cipher_start) + self.assertListEqual(list(inputs), list(outputs)) + assert decrypted == expected + + def test_ihc_decode(self): + print("##### test_ihc_decode") + ihc = IhcCipher(key_length=256) + try_size = 100000 + inputs = np.random.randint(-10001, 10001, size=try_size) + start_time = time.time() + ciphers = ihc.encrypt_batch_parallel(inputs) + end_time = time.time() + print( + f"size:{try_size}, enc_p: {end_time - start_time} seconds, " + f"average times: {(end_time - start_time) / try_size * 1000 * 1000} us") + for i in range(0, len(ciphers)): + cipher: IhcCiphertext = ciphers[i] + encoded, _ = IhcCodec.encode_cipher(cipher) + + decoded = IhcCodec.decode_cipher(None, encoded, None) + assert cipher == decoded + + +if __name__ == '__main__': + unittest.main() diff --git a/python/ppc_common/ppc_ml/__init__.py b/python/ppc_common/ppc_ml/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/python/ppc_common/ppc_ml/feature/__init__.py b/python/ppc_common/ppc_ml/feature/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/python/ppc_common/ppc_ml/feature/feature_importance.py b/python/ppc_common/ppc_ml/feature/feature_importance.py new file mode 100644 index 00000000..2d612ff8 --- /dev/null +++ b/python/ppc_common/ppc_ml/feature/feature_importance.py @@ -0,0 +1,246 @@ +# -*- coding: utf-8 -*- +from enum import Enum +import pandas as pd +from ppc_common.deps_services.serialize_type import SerializeType + + +class FeatureGainInfo: + def __init__(self, feature_idx, feature_gain): + self.feature_idx = feature_idx + self.feature_gain = feature_gain + +# TODO: cover + + +class FeatureImportanceType(Enum): + WEIGHT = 'weight' # The number of times the feature is used in all trees + GAIN = 'gain' # The gain of features in predictions across all trees + + @classmethod + def has_value(cls, value): + return value in cls._value2member_map_ + + +class FeatureImportance: + """the feature importance + """ + + def __init__(self, importance_type: FeatureImportanceType, importance=0): + self.importance_type = importance_type + self.importance = importance + + def inc(self, value): + self.importance += value + + def desc(self): + return f"importance type: {self._importance_type}, importance: {self.importance}" + + def __cmp__(self, other): + if self.importance > other.importance: + return 1 + elif self.importance < other.importance: + return -1 + return 0 + + def __eq__(self, other): + return self.importance == other.importance + + def __lt__(self, other): + return self.importance < other.importance + + def __add__(self, other): + new_importance = FeatureImportance( + self.importance_type, importance=self.importance + other.importance) + return new_importance + + +class ReadOnlyFeatureImportanceStore: + RANK_PROPERTY = "score_rank" + DEAULT_SCORE_THRESHOLD = 0.95 + DEFAULT_TOPK_PROPERTY = "topk" + DEFAULT_EMPTY_TOPK_FLAG = " " + DEFAULT_TOPK_FLAG = "True" + + def __init__(self, feature_importance_dict, logger): + # feature_importance_type ==> fid ==> value + self.feature_importance_dict = feature_importance_dict + self.logger = logger + + def get_feature_importance(self, fid, type): + if type not in self.feature_importance_dict: + return 0 + if fid not in self.feature_importance_dict[type]: + return 0 + return self.feature_importance_dict[type][fid].importance + + def _get_sorting_columns(self): + sorting_columns = [] + ascending_list = [] + if FeatureImportanceType.GAIN in self.feature_importance_type_list: + sorting_columns.append(FeatureImportanceType.GAIN.name) + ascending_list.append(False) + if FeatureImportanceType.WEIGHT in self.feature_importance_type_list: + sorting_columns.append(FeatureImportanceType.WEIGHT.name) + ascending_list.append(False) + return (sorting_columns, ascending_list) + + @staticmethod + def load(df, logger): + """load the feature importance + + Args: + df (DataFrame): the feature importance + """ + logger.debug(f"load feature_importance data: {df}") + feature_importance_type_list = [] + for column in df.columns: + if not FeatureImportanceType.has_value(column.lower()): + continue + enum_feature_importance_type = FeatureImportanceType( + column.lower()) + feature_importance_type_list.append(enum_feature_importance_type) + logger.debug( + f"load feature_importance, feature_importance_type_list: {feature_importance_type_list}") + # feature_importance_type ==> fid_key ==> value + feature_importance_dict = dict() + for row in df.itertuples(): + fid_key = getattr( + row, FeatureImportanceStore.DEFAULT_FEATURE_PROPERTY) + for importance_type in feature_importance_type_list: + value = getattr(row, importance_type.name) + if importance_type not in feature_importance_dict: + feature_importance_dict.update({importance_type: dict()}) + feature_importance_dict[importance_type].update( + {fid_key: FeatureImportance(importance_type, value)}) + return ReadOnlyFeatureImportanceStore(feature_importance_dict, logger) + + def to_dataframe(self, topk_threshold=0.95): + """convert the feature importance into pd + the format: + | feature | score | score_rank | topk| + | x16 | 0.08234 | 1 | | + | x11 | 0.08134 | 2 | | + | x1 | 0.08034 | 3 | | + """ + if self.feature_importance_dict is None or len(self.feature_importance_dict) < 1: + return None + df = pd.DataFrame() + # the feature column + df.insert(df.shape[1], FeatureImportanceStore.DEFAULT_FEATURE_PROPERTY, + self.feature_importance_dict[self.feature_importance_type_list[0]].keys()) + # the importance columns + for importance_type in self.feature_importance_dict.keys(): + feature_importance_values = [] + for feature_importance in self.feature_importance_dict[importance_type].values(): + feature_importance_values.append(feature_importance.importance) + # calculate weight-average for the score + if importance_type == FeatureImportanceType.GAIN: + feature_importance_sum = sum(feature_importance_values) + if feature_importance_sum != 0: + for i in range(len(feature_importance_values)): + feature_importance_values[i] = float( + feature_importance_values[i]) / feature_importance_sum + + df.insert(df.shape[1], importance_type.name, + feature_importance_values) + # sort by the importance + (sorting_columns, ascending_list) = self._get_sorting_columns() + df = df.sort_values(by=sorting_columns, ascending=ascending_list) + # rank + df.insert(df.shape[1], + ReadOnlyFeatureImportanceStore.RANK_PROPERTY, + range(1, len(df) + 1)) + # top-k + if FeatureImportanceType.GAIN not in self.feature_importance_type_list: + return df + score_sum = float(0) + topk_list = [ + ReadOnlyFeatureImportanceStore.DEFAULT_EMPTY_TOPK_FLAG for _ in range(len(df))] + i = 0 + for score in df[FeatureImportanceType.GAIN.name].T: + score_sum += score + if score_sum >= topk_threshold: + topk_list[i] = ReadOnlyFeatureImportanceStore.DEFAULT_TOPK_FLAG + break + i += 1 + df.insert( + df.shape[1], ReadOnlyFeatureImportanceStore.DEFAULT_TOPK_PROPERTY, topk_list) + return df + + +class FeatureImportanceStore(ReadOnlyFeatureImportanceStore): + """store all the feature importance + """ + DEFAULT_FEATURE_PROPERTY = "feature" + DEFAULT_IMPORTANCE_LIST = [ + FeatureImportanceType.GAIN, FeatureImportanceType.WEIGHT] + + def __init__(self, feature_importance_type_list, feature_list, logger): + # feature_importance_type ==> fid ==> value + super().__init__(dict(), logger) + self.feature_list = feature_list + if self.feature_list is not None: + self.logger.info( + f"create FeatureImportanceStore, all features: {self.feature_list}") + self.feature_importance_type_list = feature_importance_type_list + for importance_type in self.feature_importance_type_list: + self.feature_importance_dict.update({importance_type: dict()}) + self._init() + + def _init(self): + if self.feature_list is None: + return + for i in range(len(self.feature_list)): + gain_list = {FeatureImportanceType.GAIN: 0, + FeatureImportanceType.WEIGHT: 0} + self.update_feature_importance(i, gain_list) + + def set_init(self, feature_list): + self.feature_list = feature_list + self._init() + + def generate_fid_key(self, fid): + if fid >= len(self.feature_list): + return None + return f"{self.feature_list[fid]}" + + def update_feature_importance(self, fid, gain_list): + """update the feature importance + + Args: + fid (int): the idx of the best feature(maxk) + gain_list (dict): the gain list for every importance_type + + Raises: + Exception: invalid gain_list + """ + fid_key = self.generate_fid_key(fid) + if fid_key is None: + return + for importance_type in gain_list.keys(): + # unknown importance_type + if importance_type not in self.feature_importance_dict: + continue + if fid_key not in self.feature_importance_dict[importance_type]: + self.feature_importance_dict[importance_type][fid_key] = FeatureImportance( + importance_type, 0) + self.feature_importance_dict[importance_type][fid_key].inc( + gain_list[importance_type]) + + def store(self, serialize_type: SerializeType, local_file_path, remote_file_path, storage_client, user=None): + """store the feature importance into file, upload using storage_client + + Args: + storage_client: the client used to upload the result + """ + df = self.to_dataframe() + if serialize_type is SerializeType.CSV: + df.to_csv(local_file_path, index=False) + else: + df.to_json(orient='split', path_or_buf=local_file_path) + self.logger.info( + f"Store feature_importance to {local_file_path}, file type: {serialize_type}") + if storage_client is not None: + storage_client.upload_file(local_file_path, remote_file_path, user) + self.logger.info( + f"Upload feature_importance to {local_file_path} success, file type: {serialize_type}") diff --git a/python/ppc_common/ppc_ml/feature/tests/feature_importance_test.py b/python/ppc_common/ppc_ml/feature/tests/feature_importance_test.py new file mode 100644 index 00000000..3b0f5661 --- /dev/null +++ b/python/ppc_common/ppc_ml/feature/tests/feature_importance_test.py @@ -0,0 +1,79 @@ +# -*- coding: utf-8 -*- +import unittest +from ppc_common.ppc_ml.feature.feature_importance import FeatureImportanceType +from ppc_common.ppc_ml.feature.feature_importance import FeatureImportanceStore +from ppc_common.ppc_ml.feature.feature_importance import ReadOnlyFeatureImportanceStore +from ppc_common.deps_services.serialize_type import SerializeType +import logging +import random +import sys +import pandas as pd + + +class FeatureImportanceWrapper: + def __init__(self, ut_obj, feature_size): + self.ut_obj = ut_obj + self.feature_size = feature_size + self.feature_list = [] + self._fake_features() + logging.basicConfig(stream=sys.stdout, level=logging.DEBUG) + self.logger = logging.getLogger(__name__) + self.feature_importance_type_list = [ + FeatureImportanceType.GAIN, FeatureImportanceType.WEIGHT] + self.feature_importance_store = FeatureImportanceStore( + self.feature_importance_type_list, self.feature_list, self.logger) + self.epsilon = 0.000000001 + + def _fake_features(self): + for i in range(self.feature_size): + self.feature_list.append("feature_" + str(i)) + + def update_feature_importance_and_check(self, rounds, local_file_path): + for i in range(rounds): + selected_feature = random.randint(0, self.feature_size - 1) + key = self.feature_importance_store.generate_fid_key( + selected_feature) + gain = random.uniform(0, 101) + pre_gain = self.feature_importance_store.get_feature_importance( + key, FeatureImportanceType.GAIN) + pre_weight = self.feature_importance_store.get_feature_importance( + key, FeatureImportanceType.WEIGHT) + self.feature_importance_store.update_feature_importance( + selected_feature, {FeatureImportanceType.GAIN: gain, FeatureImportanceType.WEIGHT: 1}) + self.ut_obj.assertEqual( + pre_gain + gain, self.feature_importance_store.get_feature_importance(key, FeatureImportanceType.GAIN)) + self.ut_obj.assertEqual( + pre_weight + 1, self.feature_importance_store.get_feature_importance(key, FeatureImportanceType.WEIGHT)) + # store + self.feature_importance_store.store( + SerializeType.CSV, local_file_path, None, None) + # load + df = pd.read_csv(local_file_path) + loaded_feature_importance_store = ReadOnlyFeatureImportanceStore.load( + df, self.logger) + # check the dict + for importance_type in loaded_feature_importance_store.feature_importance_dict: + self.ut_obj.assertTrue( + importance_type in self.feature_importance_store.feature_importance_dict) + feature_importances = self.feature_importance_store.feature_importance_dict[ + importance_type] + loaded_feature_importances = loaded_feature_importance_store.feature_importance_dict[ + importance_type] + sum_data = 0 + for fid in loaded_feature_importances.keys(): + sum_data += loaded_feature_importances[fid].importance + self.ut_obj.assertTrue(abs(sum_data - 1) < self.epsilon) + local_json_file = local_file_path + ".json" + self.feature_importance_store.store( + SerializeType.JSON, local_json_file, None, None) + + +class TestFeatureImportance(unittest.TestCase): + def test_update_gain_and_store(self): + feature_size = 100 + self.wrapper = FeatureImportanceWrapper( + self, feature_size=feature_size) + rounds = 100000 + local_file_path = "feature_importance_case1.csv" + self.wrapper.update_feature_importance_and_check( + rounds, local_file_path=local_file_path) diff --git a/python/ppc_common/ppc_ml/model/algorithm_info.py b/python/ppc_common/ppc_ml/model/algorithm_info.py new file mode 100644 index 00000000..a117887d --- /dev/null +++ b/python/ppc_common/ppc_ml/model/algorithm_info.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- + +from enum import Enum + + +class ClassificationType(Enum): + TWO = 'two' + MULTI = 'multi' + + @classmethod + def has_value(cls, value): + return value in cls._value2member_map_ + + +class EvaluationType(Enum): + ROC = "roc", + PR = "pr", + KS = "ks", + ACCURACY = "accuracy", + CONFUSION_MATRIX = "confusion_matrix" + + +class ModelRole(Enum): + ACTIVE = "active" + PASSIVE = "passive" diff --git a/python/ppc_common/ppc_mock/__init__.py b/python/ppc_common/ppc_mock/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/python/ppc_common/ppc_mock/mock_objects.py b/python/ppc_common/ppc_mock/mock_objects.py new file mode 100644 index 00000000..4ac711e0 --- /dev/null +++ b/python/ppc_common/ppc_mock/mock_objects.py @@ -0,0 +1,59 @@ +from datetime import datetime +from typing import AnyStr + +from ppc_common.deps_services.storage_api import StorageApi + + +class MockLogger: + @staticmethod + def debug(msg): + current_time = datetime.now() + print(f"{current_time}, Debug: {msg}") + + @staticmethod + def info(msg): + current_time = datetime.now() + print(f"{current_time}, Info: {msg}") + + @staticmethod + def warn(msg): + current_time = datetime.now() + print(f"{current_time}, Warn: {msg}") + + @staticmethod + def error(msg): + current_time = datetime.now() + print(f"{current_time}, Error: {msg}") + + +class MockStorageClient(StorageApi): + + def download_file(self, storage_path: str, local_file_path: str, enable_cache=False): + print(f'download_file: {storage_path} -> {local_file_path}') + + def upload_file(self, local_file_path: str, storage_path: str): + print(f'upload_file: {storage_path} -> {local_file_path}') + + def make_file_path(self, storage_path: str): + pass + + def delete_file(self, storage_path: str): + pass + + def save_data(self, data: AnyStr, storage_path: str): + pass + + def get_data(self, storage_path: str) -> AnyStr: + pass + + def mkdir(self, storage_path: str): + pass + + def file_existed(self, storage_path: str) -> bool: + pass + + def file_rename(self, old_storage_path: str, storage_path: str): + pass + + def storage_type(self): + pass diff --git a/python/ppc_common/ppc_protos/__init__.py b/python/ppc_common/ppc_protos/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/python/ppc_common/ppc_protos/generated/__init__.py b/python/ppc_common/ppc_protos/generated/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/python/ppc_common/ppc_protos/generated/ppc_model_pb2.py b/python/ppc_common/ppc_protos/generated/ppc_model_pb2.py new file mode 100644 index 00000000..ced82b9e --- /dev/null +++ b/python/ppc_common/ppc_protos/generated/ppc_model_pb2.py @@ -0,0 +1,49 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: ppc_model.proto +# Protobuf Python Version: 4.25.3 +"""Generated protocol buffer code.""" +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import symbol_database as _symbol_database +from google.protobuf.internal import builder as _builder +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0fppc_model.proto\x12\tppc.model\"|\n\x0cModelRequest\x12\x0e\n\x06sender\x18\x01 \x01(\t\x12\x10\n\x08receiver\x18\x02 \x01(\t\x12\x0f\n\x07task_id\x18\x03 \x01(\t\x12\x0b\n\x03key\x18\x04 \x01(\t\x12\x0b\n\x03seq\x18\x05 \x01(\x03\x12\x11\n\tslice_num\x18\x06 \x01(\x03\x12\x0c\n\x04\x64\x61ta\x18\x07 \x01(\x0c\"3\n\x0c\x42\x61seResponse\x12\x12\n\nerror_code\x18\x01 \x01(\x03\x12\x0f\n\x07message\x18\x02 \x01(\t\"M\n\rModelResponse\x12.\n\rbase_response\x18\x01 \x01(\x0b\x32\x17.ppc.model.BaseResponse\x12\x0c\n\x04\x64\x61ta\x18\x02 \x01(\x0c\"#\n\rPlainBoolList\x12\x12\n\nplain_list\x18\x01 \x03(\x08\"\xb1\x01\n\rBestSplitInfo\x12\x0f\n\x07tree_id\x18\x01 \x01(\x03\x12\x0f\n\x07leaf_id\x18\x02 \x01(\x03\x12\x0f\n\x07\x66\x65\x61ture\x18\x03 \x01(\x03\x12\r\n\x05value\x18\x04 \x01(\x03\x12\x12\n\nagency_idx\x18\x05 \x01(\x03\x12\x16\n\x0e\x61gency_feature\x18\x06 \x01(\x03\x12\x11\n\tbest_gain\x18\x07 \x01(\x02\x12\x0e\n\x06w_left\x18\x08 \x01(\x02\x12\x0f\n\x07w_right\x18\t \x01(\x02\"3\n\x0bModelCipher\x12\x12\n\nciphertext\x18\x01 \x01(\x0c\x12\x10\n\x08\x65xponent\x18\x02 \x01(\x0c\"M\n\nCipherList\x12\x12\n\npublic_key\x18\x01 \x01(\x0c\x12+\n\x0b\x63ipher_list\x18\x02 \x03(\x0b\x32\x16.ppc.model.ModelCipher\"=\n\x0e\x43ipher1DimList\x12+\n\x0b\x63ipher_list\x18\x01 \x03(\x0b\x32\x16.ppc.model.ModelCipher\"W\n\x0e\x43ipher2DimList\x12\x12\n\npublic_key\x18\x01 \x01(\x0c\x12\x31\n\x0e\x63ipher_1d_list\x18\x02 \x03(\x0b\x32\x19.ppc.model.Cipher1DimList\"_\n\rEncAggrLabels\x12\r\n\x05\x66ield\x18\x01 \x01(\t\x12\x12\n\ncount_list\x18\x02 \x03(\x03\x12+\n\x0b\x63ipher_list\x18\x03 \x03(\x0b\x32\x16.ppc.model.ModelCipher\"_\n\x11\x45ncAggrLabelsList\x12\x12\n\npublic_key\x18\x01 \x01(\x0c\x12\x36\n\x14\x65nc_aggr_labels_list\x18\x02 \x03(\x0b\x32\x18.ppc.model.EncAggrLabels\"/\n\x10IterationRequest\x12\r\n\x05\x65poch\x18\x01 \x01(\x03\x12\x0c\n\x04stop\x18\x02 \x01(\x08\x32Y\n\x0cModelService\x12I\n\x12MessageInteraction\x12\x17.ppc.model.ModelRequest\x1a\x18.ppc.model.ModelResponse\"\x00\x42\x08P\x01\xa2\x02\x03PPCb\x06proto3') + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'ppc_model_pb2', _globals) +if _descriptor._USE_C_DESCRIPTORS == False: + _globals['DESCRIPTOR']._options = None + _globals['DESCRIPTOR']._serialized_options = b'P\001\242\002\003PPC' + _globals['_MODELREQUEST']._serialized_start = 30 + _globals['_MODELREQUEST']._serialized_end = 154 + _globals['_BASERESPONSE']._serialized_start = 156 + _globals['_BASERESPONSE']._serialized_end = 207 + _globals['_MODELRESPONSE']._serialized_start = 209 + _globals['_MODELRESPONSE']._serialized_end = 286 + _globals['_PLAINBOOLLIST']._serialized_start = 288 + _globals['_PLAINBOOLLIST']._serialized_end = 323 + _globals['_BESTSPLITINFO']._serialized_start = 326 + _globals['_BESTSPLITINFO']._serialized_end = 503 + _globals['_MODELCIPHER']._serialized_start = 505 + _globals['_MODELCIPHER']._serialized_end = 556 + _globals['_CIPHERLIST']._serialized_start = 558 + _globals['_CIPHERLIST']._serialized_end = 635 + _globals['_CIPHER1DIMLIST']._serialized_start = 637 + _globals['_CIPHER1DIMLIST']._serialized_end = 698 + _globals['_CIPHER2DIMLIST']._serialized_start = 700 + _globals['_CIPHER2DIMLIST']._serialized_end = 787 + _globals['_ENCAGGRLABELS']._serialized_start = 789 + _globals['_ENCAGGRLABELS']._serialized_end = 884 + _globals['_ENCAGGRLABELSLIST']._serialized_start = 886 + _globals['_ENCAGGRLABELSLIST']._serialized_end = 981 + _globals['_ITERATIONREQUEST']._serialized_start = 983 + _globals['_ITERATIONREQUEST']._serialized_end = 1030 + _globals['_MODELSERVICE']._serialized_start = 1032 + _globals['_MODELSERVICE']._serialized_end = 1121 +# @@protoc_insertion_point(module_scope) diff --git a/python/ppc_common/ppc_protos/generated/ppc_model_pb2_grpc.py b/python/ppc_common/ppc_protos/generated/ppc_model_pb2_grpc.py new file mode 100644 index 00000000..e56168ae --- /dev/null +++ b/python/ppc_common/ppc_protos/generated/ppc_model_pb2_grpc.py @@ -0,0 +1,67 @@ +# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! +"""Client and server classes corresponding to protobuf-defined services.""" +import grpc + +from ppc_common.ppc_protos.generated import ppc_model_pb2 as ppc__model__pb2 + + +class ModelServiceStub(object): + """Missing associated documentation comment in .proto file.""" + + def __init__(self, channel): + """Constructor. + + Args: + channel: A grpc.Channel. + """ + self.MessageInteraction = channel.unary_unary( + '/ppc.model.ModelService/MessageInteraction', + request_serializer=ppc__model__pb2.ModelRequest.SerializeToString, + response_deserializer=ppc__model__pb2.ModelResponse.FromString, + ) + + +class ModelServiceServicer(object): + """Missing associated documentation comment in .proto file.""" + + def MessageInteraction(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + +def add_ModelServiceServicer_to_server(servicer, server): + rpc_method_handlers = { + 'MessageInteraction': grpc.unary_unary_rpc_method_handler( + servicer.MessageInteraction, + request_deserializer=ppc__model__pb2.ModelRequest.FromString, + response_serializer=ppc__model__pb2.ModelResponse.SerializeToString, + ), + } + generic_handler = grpc.method_handlers_generic_handler( + 'ppc.model.ModelService', rpc_method_handlers) + server.add_generic_rpc_handlers((generic_handler,)) + + # This class is part of an EXPERIMENTAL API. + + +class ModelService(object): + """Missing associated documentation comment in .proto file.""" + + @staticmethod + def MessageInteraction(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/ppc.model.ModelService/MessageInteraction', + ppc__model__pb2.ModelRequest.SerializeToString, + ppc__model__pb2.ModelResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) diff --git a/python/ppc_common/ppc_protos/generated/ppc_pb2.py b/python/ppc_common/ppc_protos/generated/ppc_pb2.py new file mode 100644 index 00000000..623c0434 --- /dev/null +++ b/python/ppc_common/ppc_protos/generated/ppc_pb2.py @@ -0,0 +1,32 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: ppc.proto +# Protobuf Python Version: 4.25.3 +"""Generated protocol buffer code.""" +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import symbol_database as _symbol_database +from google.protobuf.internal import builder as _builder +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\tppc.proto\x12\tppc.proto\"8\n\x0eInputStatement\x12\x10\n\x08upstream\x18\x01 \x01(\t\x12\x14\n\x0coutput_index\x18\x02 \x01(\x03\"O\n\x18JobWorkerInputsStatement\x12\x33\n\x10inputs_statement\x18\x01 \x03(\x0b\x32\x19.ppc.proto.InputStatement\"\'\n\x12JobWorkerUpstreams\x12\x11\n\tupstreams\x18\x01 \x03(\t\"#\n\x10JobWorkerOutputs\x12\x0f\n\x07outputs\x18\x01 \x03(\tb\x06proto3') + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'ppc_pb2', _globals) +if _descriptor._USE_C_DESCRIPTORS == False: + DESCRIPTOR._options = None + _globals['_INPUTSTATEMENT']._serialized_start=24 + _globals['_INPUTSTATEMENT']._serialized_end=80 + _globals['_JOBWORKERINPUTSSTATEMENT']._serialized_start=82 + _globals['_JOBWORKERINPUTSSTATEMENT']._serialized_end=161 + _globals['_JOBWORKERUPSTREAMS']._serialized_start=163 + _globals['_JOBWORKERUPSTREAMS']._serialized_end=202 + _globals['_JOBWORKEROUTPUTS']._serialized_start=204 + _globals['_JOBWORKEROUTPUTS']._serialized_end=239 +# @@protoc_insertion_point(module_scope) diff --git a/python/ppc_common/ppc_protos/ppc.proto b/python/ppc_common/ppc_protos/ppc.proto new file mode 100644 index 00000000..ca9a3a5b --- /dev/null +++ b/python/ppc_common/ppc_protos/ppc.proto @@ -0,0 +1,21 @@ +syntax = "proto3"; + +package ppc.proto; + + +message InputStatement { + string upstream = 1; + int64 output_index = 2; +} + +message JobWorkerInputsStatement { + repeated InputStatement inputs_statement = 1; +} + +message JobWorkerUpstreams { + repeated string upstreams = 1; +} + +message JobWorkerOutputs { + repeated string outputs = 1; +} diff --git a/python/ppc_common/ppc_protos/ppc_model.proto b/python/ppc_common/ppc_protos/ppc_model.proto new file mode 100644 index 00000000..228a37c2 --- /dev/null +++ b/python/ppc_common/ppc_protos/ppc_model.proto @@ -0,0 +1,56 @@ +syntax = "proto3"; + +option java_multiple_files = true; +option objc_class_prefix = "PPC"; + +package ppc.model; +message PlainBoolList{ + repeated bool plain_list = 1; +} + +message BestSplitInfo{ + int64 tree_id = 1; + int64 leaf_id = 2; + int64 feature = 3; + int64 value = 4; + int64 agency_idx = 5; + int64 agency_feature = 6; + float best_gain = 7; + float w_left = 8; + float w_right = 9; +} + +message ModelCipher { + bytes ciphertext = 1; + bytes exponent = 2; +} + +message CipherList { + bytes public_key = 1; + repeated ModelCipher cipher_list = 2; +} + +message Cipher1DimList { + repeated ModelCipher cipher_list = 1; +} + +message Cipher2DimList { + bytes public_key = 1; + repeated Cipher1DimList cipher_1d_list = 2; +} + +message EncAggrLabels { + string field = 1; + repeated int64 count_list = 2; + repeated ModelCipher cipher_list = 3; +} + +message EncAggrLabelsList { + bytes public_key = 1; + repeated EncAggrLabels enc_aggr_labels_list = 2; +} + +message IterationRequest { + int64 epoch = 1; + bool stop = 2; +} diff --git a/python/ppc_common/ppc_utils/__init__.py b/python/ppc_common/ppc_utils/__init__.py new file mode 100644 index 00000000..8d7ee87a --- /dev/null +++ b/python/ppc_common/ppc_utils/__init__.py @@ -0,0 +1 @@ +__all__ = ['exception', 'path', 'permission', 'utils', 'common_func'] diff --git a/python/ppc_common/ppc_utils/common_func.py b/python/ppc_common/ppc_utils/common_func.py new file mode 100644 index 00000000..a39a22c1 --- /dev/null +++ b/python/ppc_common/ppc_utils/common_func.py @@ -0,0 +1,33 @@ +# -*- coding: utf-8 -*- +from contextlib import contextmanager +import chardet + + +def get_config_value(key, default_value, config_value, required): + if required and config_value is None: + raise Exception(f"Invalid config for '{key}' for not set!") + value = config_value + if type(config_value) is dict: + if key in config_value: + value = config_value[key] + else: + value = default_value + if value is None: + return default_value + return value + + +def get_file_encoding(file_path): + encoding = None + with open(file_path, "rb") as fp: + header = fp.readline() + file_chardet = chardet.detect(header) + if file_chardet is None: + raise Exception(f"Unknown File Encoding, file: {file_path}") + encoding = file_chardet["encoding"] + return encoding + + +def require_non_empty(value_property, value): + if value is None or len(value) == 0: + raise Exception(f"the ${value_property} must non-empty!") diff --git a/python/ppc_common/ppc_utils/exception.py b/python/ppc_common/ppc_utils/exception.py new file mode 100644 index 00000000..c5ae1ea2 --- /dev/null +++ b/python/ppc_common/ppc_utils/exception.py @@ -0,0 +1,148 @@ +# -*- coding: utf-8 -*- +from enum import Enum, unique + + +@unique +class PpcErrorCode(Enum): + SUCCESS = {0: 'success'} + INTERNAL_ERROR = {10000: "internal error"} + + NETWORK_ERROR = {10001: 'network error'} + JOB_STATUS_ERROR = {10002: 'job status check error'} + JOB_ROLE_ERROR = {10003: 'job role check error'} + DATABASE_ERROR = {10004: 'database related operation error'} + DATASET_CSV_ERROR = {10005: 'dataset csv format error'} + DATASET_PATH_ERROR = {10006: 'dataset path permission check error'} + PARAMETER_CHECK_ERROR = {10007: 'parameter check error'} + CALL_SYNCS_SERVICE_ERROR = {10008: 'call syncs service error'} + DATA_SET_ERROR = {10009: 'dataset operation error'} + + INSUFFICIENT_AUTHORITY = {10010: 'insufficient authority'} + UNDEFINED_TYPE = {10011: 'undefined type'} + UNDEFINED_STATUS = {10012: 'undefined status'} + QUERY_USERNAME_ERROR = {10013: 'query username error'} + DATASET_NOT_FOUND = {10014: 'dataset not found'} + ALGORITHM_NOT_FOUND = {10015: 'algorithm queried not found'} + JOB_NOT_FOUND = {10016: 'job not found'} + AUTH_INFO_FOUND = {10017: 'authorization not found'} + AGENCY_NOT_FOUND = {10018: 'agency not found'} + AGENCY_MANAGEMENT_NOT_FOUND = {10019: 'agency management not found'} + FIELD_NOT_FOUND = {10020: 'dataset field not found'} + AUTH_ALREADY_EXISTED = {10021: 'authorization already existed'} + DATABASE_TYPE_ERROR = {10022: 'database type error'} + DATABASE_IP_ERROR = {10023: 'database ip not in the white list'} + DATASET_FROM_DB_RETRY_OVER_LIMIT_ERROR = { + 10024: 'access the database has exceeded the allowed limit times'} + + DATASET_PARSE_ERROR = {10300: 'parse dataset failed'} + DATASET_EXIST_ERROR = {10301: 'dataset already existed!'} + DATASET_DELETE_ERROR = {10302: 'dataset already deleted!'} + DATASET_PERMISSION_ERROR = {10303: 'dataset permission check failed!'} + DATASET_UPLOAD_ERROR = {10304: 'dataset upload error'} + + ALGORITHM_PARSE_ERROR = {10400: 'parse algorithm failed'} + ALGORITHM_EXIST_ERROR = {10401: 'algorithm already existed!'} + ALGORITHM_DELETE_ERROR = {10402: 'algorithm already deleted!'} + ALGORITHM_TYPE_ERROR = {10403: 'algorithm type is not existed!'} + ALGORITHM_COMPILE_ERROR = {10410: 'compile mpc algorithm error'} + ALGORITHM_BAD_SQL = {10411: 'bad sql'} + ALGORITHM_PPC_CONFIG_ERROR = {10412: 'parse algorithm config error'} + ALGORITHM_PPC_MODEL_ALGORITHM_NAME_ERROR = { + 10413: 'algorithm subtype not found'} + ALGORITHM_PPC_MODEL_OUTPUT_NUMBER_ERROR = {10414: 'output number error'} + ALGORITHM_PPC_MODEL_LAYERS_ERROR = { + 10415: 'layers attribute should not be set'} + ALGORITHM_MPC_SYNTAX_CHECK_ERROR = {10416: 'check ppc mpc syntax error'} + ALGORITHM_PPC_MODEL_OUTPUT_NUMBER_ERROR_TEMP = { + 10417: 'output number should be set 1'} + ALGORITHM_PPC_MODEL_PARTICIPANTS_ERROR_TEMP = { + 10418: 'participants should be greater or equal to 2'} + ALGORITHM_PPC_MODEL_TEST_DATASET_PERCENTAGE_ERROR = { + 10419: 'test_dataset_percentage should be set in (0, 0.5]'} + ALGORITHM_PPC_MODEL_EPOCHS_ERROR = { + 10420: 'epochs should be set in [1, 5]'} + ALGORITHM_PPC_MODEL_BATCH_SIZE_ERROR = { + 10421: 'batch_size should be set [1, min(128, max_train_dataset_size)]'} + ALGORITHM_PPC_MODEL_THREADS_ERROR = { + 10422: 'threads should be set in [1,8]'} + ALGORITHM_PPC_MODEL_OPTIMIZER_ERROR = {10423: 'optimizer not found'} + ALGORITHM_PPC_MODEL_LEARNING_RATE_ERROR = { + 10424: 'learning rate should be set in (0, 1)'} + ALGORITHM_PPC_MODEL_LAYERS_ERROR2 = { + 10425: 'Conv2d layer should not be the first layer in HeteroNN'} + ALGORITHM_NOT_EXIST_ERROR = {10426: 'algorithm does not exist!'} + ALGORITHM_PPC_MODEL_TREES_ERROR = { + 10427: 'num_trees should be set in [1, 300]'} + ALGORITHM_PPC_MODEL_DEPTH_ERROR = { + 10428: 'max_depth should be set in [1, 10]'} + + JOB_CREATE_ERROR = {10500: 'job create failed'} + JOB_COMPUTATION_EXISTED_ERROR = {10501: 'job computation not existed'} + JOB_AYS_MODE_CHECK_ERROR = {10502: 'patch request need static token'} + JOB_MANAGEMENT_RUN_ERROR = {10503: 'job run failed'} + JOB_CEM_ERROR = {10504: 'at least one field need to be provided'} + JOB_IS_RUNNING_ERROR = {10505: 'job is running'} + NO_PARTICAPATING_IN_JOB_ERROR = {10506: 'not participating in the job'} + JOB_DOWNLOAD_RESULT_EMPTY = {10507: '任务结果为空,无法下载'} + + HDFS_STORAGE_ERROR = {10601: 'hdfs storage error'} + + AYS_LENGTH_ERROR = {10701: 'base ot message length check error'} + AYS_ORDER_ERROR = {10702: 'search obfuscation order must > 1'} + AYS_RESULT_LENGTH_ERROR = {10703: 'message result length check error'} + AYS_FIELD_ERROR = {10704: 'search filed not found in obfuscate file'} + CALL_SCS_ERROR = {10705: 'computation node call error'} + + MERGE_FILE_CHECK_ERROR = {10801: 'merge check files failed'} + MERGE_FILE_FORMAT_ERROR = {10802: 'file format is not csv'} + FILE_SIZE_ERROR = {10803: 'cannot get file size'} + FILE_SPLIT_ERROR = {10804: 'split file failed!'} + FILE_NOT_EXIST_ERROR = {10805: 'share file not existed!'} + DUPLICATED_MERGE_FILE_REQUEST = {10806: 'duplicated merge file request'} + + XGB_PREPROCESSING_ERROR = {10901: 'xgb preprocessing failed!'} + + FILE_OBJECT_UPLOAD_CHECK_FAILED = {20000: "upload file object failed!"} + FILE_OBJECT_NOT_EXISTS = {20001: "the file not exists!"} + + TASK_EXISTS = {11000: "the task already exists!"} + TASK_NOT_FOUND = {11001: "the task not found!"} + TASK_IS_KILLED = {11002: "the task is killed!"} + + ROLE_TYPE_ERROR = {12000: "role type is illegal."} + + UNSUPPORTED_WORK_TYPE = {13000: "unsupported work type."} + + def get_code(self): + return list(self.value.keys())[0] + + def get_error_code(self): + return list(self.value.keys())[0] + + def get_msg(self): + return list(self.value.values())[0] + + def get_message(self): + return list(self.value.values())[0] + + +class PpcException(Exception): + + def __init__(self, code, message): + Exception.__init__(self) + self.code = code + self.message = message + + def to_dict(self): + return {'code': self.code, 'message': self.message} + + def get_code(self): + return self.code + + def __str__(self): + return self.message + + @classmethod + def by_ppc_error_code(cls, ppc_error_code): + cls.code = ppc_error_code.get_code() + cls.message = ppc_error_code.get_msg() diff --git a/python/ppc_common/ppc_utils/http_utils.py b/python/ppc_common/ppc_utils/http_utils.py new file mode 100644 index 00000000..8dc43a56 --- /dev/null +++ b/python/ppc_common/ppc_utils/http_utils.py @@ -0,0 +1,102 @@ +# -*- coding: utf-8 -*- +import json +import logging +from json.decoder import JSONDecodeError + +import requests +import urllib3 +from urllib3.exceptions import SecurityWarning + +from ppc_common.ppc_utils.exception import PpcException, PpcErrorCode + +log = logging.getLogger(__name__) + + +def check_response(response): + if response.status_code != 200 and response.status_code != 201: + message = response.text + raise PpcException(PpcErrorCode.NETWORK_ERROR, + f"Call request failed, response message:{message}") + + +def send_get_request(endpoint, uri, params=None, headers=None): + urllib3.disable_warnings(SecurityWarning) + if not headers: + headers = {'content-type': 'application/json'} + if uri: + url = f"http://{endpoint}{uri}" + else: + url = f"http://{endpoint}" + log.debug(f"send a get request, url: {url}, params: {params}") + response = requests.get(url=url, params=params, + headers=headers, timeout=30) + log.debug(f"response: {response.text}") + check_response(response) + response_data = json.loads(response.text) + + return response_data + + +def send_post_request(endpoint, uri, params=None, headers=None, data=None): + if not headers: + headers = {'content-type': 'application/json'} + if uri: + url = f"http://{endpoint}{uri}" + else: + url = f"http://{endpoint}" + log.debug(f"send a post request, url: {url}, params: {params}") + response = requests.post(url, data=data, json=params, headers=headers) + log.debug(f"response: {response.text}") + # check_response(response) + try: + response_data = json.loads(response.text) + except JSONDecodeError: + response_data = response.text + return response_data + + +def send_delete_request(endpoint, uri, params=None, headers=None): + if not headers: + headers = {'content-type': 'application/json'} + if uri: + url = f"http://{endpoint}{uri}" + else: + url = f"http://{endpoint}" + log.debug(f"send a delete request, url: {url}, params: {params}") + response = requests.delete(url, json=params, headers=headers) + check_response(response) + log.debug(f"response: {response.text}") + response_data = json.loads(response.text) + + return response_data + + +def send_patch_request(endpoint, uri, params=None, headers=None, data=None): + if not headers: + headers = {'content-type': 'application/json'} + url = f"http://{endpoint}{uri}" + log.debug(f"send a patch request, url: {url}, params: {params}") + response = requests.patch(url, data=data, json=params, headers=headers) + check_response(response) + log.debug(f"response: {response.text}") + response_data = json.loads(response.text) + + return response_data + + +def send_upload_request(endpoint, uri, params=None, headers=None, data=None): + if not headers: + headers = {'content-type': 'application/json'} + if uri: + url = f"http://{endpoint}{uri}" + else: + url = endpoint + log.debug(f"send a post request, url: {url}, params: {params}") + response = requests.post(url, data=data, json=params, headers=headers) + log.debug(f"response: {response.text}") + check_response(response) + try: + response_data = json.loads(response.text) + except JSONDecodeError: + response_data = response.text + return response_data diff --git a/python/ppc_common/ppc_utils/path.py b/python/ppc_common/ppc_utils/path.py new file mode 100644 index 00000000..b04daab5 --- /dev/null +++ b/python/ppc_common/ppc_utils/path.py @@ -0,0 +1,51 @@ +# coding:utf-8 +"""[path.py] + +Returns: + [type] -- [description] +""" + + +class Path(object): + ''' + fisco generator path configuration + ''' + dir = '' + + def get_name(self): + """[get some name] + + maybe it will usedful not now + + Returns: + [string] -- [name] + """ + + def get_pylint(self): + """[get some name] + + maybe it will usedful not now + + Returns: + [string] -- [name] + """ + + +def set_path(_dir): + """[set path] + + Arguments: + dir {[PATH]} -- [path] + """ + + Path.dir = _dir + + +def get_path(): + """[get path] + + Returns: + [PATH] -- [path] + """ + + return Path.dir diff --git a/python/ppc_common/ppc_utils/plot_utils.py b/python/ppc_common/ppc_utils/plot_utils.py new file mode 100644 index 00000000..3420c164 --- /dev/null +++ b/python/ppc_common/ppc_utils/plot_utils.py @@ -0,0 +1,230 @@ +import gc + +import matplotlib.pyplot as plt +import numpy as np +import pandas as pd +import seaborn as sns +from sklearn.metrics import accuracy_score +from sklearn.metrics import confusion_matrix +from sklearn.metrics import precision_recall_curve +from sklearn.metrics import roc_curve, auc + + +def plot_two_class_graph(job_context, y_scores=None, y_true=None): + y_pred_probs = job_context.y_pred_probs + y_label_probs = job_context.y_label_probs + if y_scores: + y_pred_probs = y_scores + if y_true: + y_label_probs = y_true + plt.rcParams['figure.figsize'] = (12.0, 8.0) + + # plot ROC + fpr, tpr, thresholds = roc_curve(y_label_probs, y_pred_probs, pos_label=1) + auc_value = auc(fpr, tpr) + plt.figure(f'roc-{job_context.job_id}') + plt.title('ROC Curve') # give plot a title + plt.xlabel('False Positive Rate (1 - Specificity)') + plt.ylabel('True Positive Rate (Sensitivity)') + plt.plot([0, 1], [0, 1], 'k--', lw=2) + plt.plot(fpr, tpr, label='area = {0:0.5f}' + ''.format(auc_value)) + plt.legend(loc="lower right") + plt.savefig(job_context.mpc_metric_roc_path, dpi=1000) + plt.show() + + plt.close('all') + gc.collect() + + # plot KS + plt.figure(f'ks-{job_context.job_id}') + threshold_x = np.sort(thresholds) + threshold_x[-1] = 1 + ks_value = max(abs(fpr - tpr)) + plt.title('KS Curve') + plt.xlabel('Threshold') + plt.plot(threshold_x, tpr, label='True Positive Rate') + plt.plot(threshold_x, fpr, label='False Positive Rate') + # 标记最大ks值 + x_index = np.argwhere(abs(fpr - tpr) == ks_value)[0, 0] + plt.plot((threshold_x[x_index], threshold_x[x_index]), (fpr[x_index], tpr[x_index]), + label='ks = {:.3f}'.format(ks_value), color='r', marker='o', markerfacecolor='r', markersize=5) + plt.legend(loc="lower right") + plt.savefig(job_context.mpc_metric_ks_path, dpi=1000) + plt.show() + + plt.close('all') + gc.collect() + + # plot Precision Recall + plt.figure(f'pr-{job_context.job_id}') + plt.title('Precision/Recall Curve') + plt.xlabel('Recall') + plt.ylabel('Precision') + plt.xlim(0.0, 1.0) + plt.ylim(0.0, 1.05) + precision, recall, thresholds = precision_recall_curve( + y_label_probs, y_pred_probs) + plt.plot(recall, precision) + plt.savefig(job_context.mpc_metric_pr_path, dpi=1000) + plt.show() + + plt.close('all') + gc.collect() + + # plot accuracy + plt.figure(f'accuracy-{job_context.job_id}') + thresholds = np.linspace(0, 1, num=100) # 在0~1之间生成100个阈值 + accuracies = [] + for threshold in thresholds: + predicted_labels = (y_pred_probs >= threshold).astype(int) + accuracy = accuracy_score(y_label_probs, predicted_labels) + accuracies.append(accuracy) + plt.title('Accuracy Curve') + plt.xlabel('Threshold') + plt.ylabel('Accuracy') + plt.xlim(0.0, 1.0) + plt.ylim(0.0, 1.05) + plt.plot(thresholds, accuracies) + plt.savefig(job_context.mpc_metric_accuracy_path, dpi=1000) + plt.show() + + plt.close('all') + gc.collect() + return (ks_value, auc_value) + + +def plot_multi_class_graph(job_context, n_class=None, y_label_value=None, y_pred_value=None): + if not n_class: + n_class = job_context.n_class + if not y_label_value: + y_label_value = job_context.y_label_value + if not y_pred_value: + y_pred_value = job_context.y_pred_value + y_label_probs = job_context.y_label_probs + y_pred_probs = job_context.y_pred_probs + + class_names = [x for x in range(n_class)] + plt.rcParams['figure.figsize'] = (12.0, 8.0) + plt.figure(f'roc-{job_context.job_id}') + multi_class_roc(job_context, plt, y_label_probs, y_pred_probs, class_names) + plt.figure(f'pr-{job_context.job_id}') + multi_class_precision_recall( + job_context, plt, y_label_probs, y_pred_probs, class_names) + plt.figure(f'cm-{job_context.job_id}') + multi_class_confusion_matrix( + job_context, plt, y_label_value, y_pred_value, class_names) + + +def sigmoid(x): + return 1 / (1 + np.exp(-x)) + + +def softmax(x): + x -= np.max(x, axis=1, keepdims=True) + return np.exp(x) / np.sum(np.exp(x), axis=1, keepdims=True) + + +# Converts [[0.3, 0.6, 0.1], [0.1, 0.2, 0.7], [0.8, 0.1, 0.1]] to [1, 2, 0] +def get_value_from_probs(probs): + return [np.argmax(prob) for prob in probs] + + +# Converts [1, 2, 0] to [[0, 1, 0], [0, 0, 1], [1, 0, 0]] +def get_probs_from_value(values, n_classes): + probs = np.zeros((len(values), n_classes), int) + for p, v in zip(probs, values): + p[v] = 1 + + return probs + + +# This need one-hot encoding +def multi_class_roc(job_context, plt, y_label, y_pred, class_names): + n_classes = len(class_names) + + fpr = dict() + tpr = dict() + roc_auc = dict() + for i in range(n_classes): + fpr[i], tpr[i], _ = roc_curve(y_label[:, i], y_pred[:, i]) + roc_auc[i] = auc(fpr[i], tpr[i]) + + # micro + fpr["micro"], tpr["micro"], _ = roc_curve(y_label.ravel(), y_pred.ravel()) + roc_auc["micro"] = auc(fpr["micro"], tpr["micro"]) + + # macro + # First aggregate all false positive rates + all_fpr = np.unique(np.concatenate([fpr[i] for i in range(n_classes)])) + # Then interpolate all ROC curves at this points + mean_tpr = np.zeros_like(all_fpr) + for i in range(n_classes): + mean_tpr += np.interp(all_fpr, fpr[i], tpr[i]) + # Finally average it and compute AUC + mean_tpr /= n_classes + fpr["macro"] = all_fpr + tpr["macro"] = mean_tpr + roc_auc["macro"] = auc(fpr["macro"], tpr["macro"]) + + # Plot all ROC curves + lw = 2 + plt.plot(fpr["micro"], tpr["micro"], + label='Micro-averaging (area = {0:0.5f})' + ''.format(roc_auc["micro"]), + linestyle=':', linewidth=4) + + plt.plot(fpr["macro"], tpr["macro"], + label='Macro-averaging (area = {0:0.5f})' + ''.format(roc_auc["macro"]), + linestyle=':', linewidth=4) + + for i in range(n_classes): + plt.plot(fpr[i], tpr[i], lw=lw, + label='Class {0} (area = {1:0.5f})' + ''.format(class_names[i], roc_auc[i])) + + plt.xlim([0.0, 1.0]) + plt.ylim([0.0, 1.05]) + plt.xlabel('False Positive Rate (1 - Specificity)') + plt.ylabel('True Positive Rate (Sensitivity)') + plt.title('Multi-class ROC Curve') + plt.legend(loc="lower right") + plt.plot([0, 1], [0, 1], 'k--', lw=lw) + plt.savefig(job_context.mpc_metric_roc_path, dpi=1000) + + +# This need one-hot encoding +def multi_class_precision_recall(job_context, plt, y_label, y_pred, class_names): + n_classes = len(class_names) + precision = dict() + recall = dict() + for i in range(n_classes): + precision[i], recall[i], _ = precision_recall_curve( + y_label[:, i], y_pred[:, i]) + + # Plot all ROC curves + lw = 2 + for i in range(n_classes): + plt.plot(recall[i], precision[i], lw=lw, + label='Class {0}'.format(class_names[i])) + plt.xlim([0.0, 1.0]) + plt.ylim([0.0, 1.05]) + plt.xlabel('Recall') + plt.ylabel('Precision') + plt.title('Multi-class Precision/Recall Curve') + plt.legend(loc="lower right") + plt.savefig(job_context.mpc_metric_pr_path, dpi=1000) + + +# This need value encoding +def multi_class_confusion_matrix(job_context, plt, y_label, y_pred, class_names): + cm = confusion_matrix(y_label, y_pred) + conf_matrix = pd.DataFrame(cm, index=class_names, columns=class_names) + + sns.heatmap(conf_matrix, annot=True, annot_kws={ + "size": 19}, cmap="Blues", fmt='d') + plt.ylabel('True label') + plt.xlabel('Predicted label') + plt.title('Confusion Matrix') + plt.savefig(job_context.mpc_metric_confusion_matrix_path, dpi=1000) diff --git a/python/ppc_common/ppc_utils/ppc_model_config_parser.py b/python/ppc_common/ppc_utils/ppc_model_config_parser.py new file mode 100644 index 00000000..04ea012f --- /dev/null +++ b/python/ppc_common/ppc_utils/ppc_model_config_parser.py @@ -0,0 +1,474 @@ +# coding:utf-8 +import json +import os +import unittest +from enum import unique, Enum + +from jsoncomment import JsonComment + +from ppc_common.ppc_utils import utils +from ppc_common.ppc_utils.exception import PpcException, PpcErrorCode +from ppc_common.ppc_utils.utils import check_ppc_model_algorithm_is_homo, parse_n_class + + +@unique +class ModelAlgorithmType(Enum): + HeteroLR = 1 + HomoLR = 2 + HeteroNN = 3 + HomoNN = 4 + HeteroXGB = 5 + + +@unique +class OptimizerType(Enum): + sgd = 1 + adam = 2 + + +algorithm_types = [ModelAlgorithmType.HeteroLR.name, ModelAlgorithmType.HomoLR.name, ModelAlgorithmType.HeteroNN.name, + ModelAlgorithmType.HomoNN.name, ModelAlgorithmType.HeteroXGB.name] + +optimizer_types = [OptimizerType.sgd.name, OptimizerType.adam.name] + +default_epochs = 10 +default_threads = 8 + + +FILE_PATH = os.path.abspath(__file__) +CURRENT_PATH = os.path.abspath(os.path.dirname(FILE_PATH) + os.path.sep + ".") + + +def get_dir(): + ppc_model_template_dir = f'{CURRENT_PATH}{os.sep}..{os.sep}ppc_model_template{os.sep}' + return ppc_model_template_dir + + +def parse_read_hetero_dataset_loop(participants): + loop_start = [] + loop_end = [] + start = '' + end = '' + for i in range(participants): + if i == 0 or i == participants - 1: + if i == 0: + start = f'{start}source{i}_feature_count' + end = f'{start} + source{i + 1}_feature_count' + else: + start = f'{start} + source{i}_feature_count' + end = f'{start} + source{i + 1}_feature_count' + else: + start = f'{start} + source{i}_feature_count' + end = f'{start} + source{i + 1}_feature_count' + loop_start.append(start) + loop_end.append(end) + return participants - 1, loop_start[0:participants - 1], loop_end[0:participants - 1] + + +def parse_read_homo_dataset_loop(participants): + loop_start = [] + loop_end = [] + start = '' + end = '' + for i in range(participants): + if i == 0 or i == participants - 1: + if i == 0: + start = f'{start}source{i}_record_count' + end = f'{start} + source{i + 1}_record_count' + else: + start = f'{start} + source{i}_record_count' + end = f'{start} + source{i + 1}_record_count' + else: + start = f'{start} + source{i}_record_count' + end = f'{start} + source{i + 1}_record_count' + loop_start.append(start) + loop_end.append(end) + return participants - 1, loop_start[0:participants - 1], loop_end[0:participants - 1] + + +def insert_train_record_count(layer, index, record_type): + if 'Dense' in layer: + layer_arr = layer.split('(') + else: + layer_arr = layer.split('([') + if index == 0 and 'Dense' in layer: + new_layer = f'{layer_arr[0]}({record_type}, total_feature_count, {layer_arr[1]}' + else: + if 'Dense' in layer: + new_layer = f'{layer_arr[0]}({record_type}, {layer_arr[1]}' + else: + new_layer = f'{layer_arr[0]}([{record_type}, {layer_arr[1]}' + if 'Conv2d' in new_layer: + if ', [' in new_layer: + layer_arr2 = new_layer.split(', [') + new_layer = f'{layer_arr2[0]}, [{record_type}, {layer_arr2[1]}' + if ',[' in new_layer: + layer_arr2 = new_layer.split(',[') + new_layer = f'{layer_arr2[0]},[{record_type}, {layer_arr2[1]}' + return new_layer + + +def set_nn_layers(mpc_train_algorithm, layers, record_type): + mpc_train_algorithm = f"{mpc_train_algorithm}\n" + if layers: + layers_str = 'layers = [' + for i in range(len(layers)): + new_layer = insert_train_record_count(layers[i], i, record_type) + layers_str = f"{layers_str}{new_layer},\n" + n_class = parse_n_class(layers[-1]) + mpc_train_algorithm = f"{mpc_train_algorithm}{layers_str}" + + if n_class == 1: + mpc_train_algorithm = f"{mpc_train_algorithm}ml.Output({record_type}, approx=3)]\n\n" + mpc_train_algorithm = f"{mpc_train_algorithm}test_Y = pfix.Array(test_record_count)\n" + mpc_train_algorithm = f"{mpc_train_algorithm}test_X = pfix.Matrix(test_record_count, total_feature_count)\n" + elif n_class > 1: + mpc_train_algorithm = f"{mpc_train_algorithm}ml.MultiOutput({record_type}, {n_class})]\n\n" + mpc_train_algorithm = f"{mpc_train_algorithm}total_class_count = {n_class}\n" + mpc_train_algorithm = f"{mpc_train_algorithm}test_Y = pint.Matrix(test_record_count, total_class_count)\n" + mpc_train_algorithm = f"{mpc_train_algorithm}test_X = pfix.Matrix(test_record_count, total_feature_count)\n" + else: + raise PpcException(PpcErrorCode.ALGORITHM_PPC_MODEL_OUTPUT_NUMBER_ERROR.get_code(), + PpcErrorCode.ALGORITHM_PPC_MODEL_OUTPUT_NUMBER_ERROR.get_msg()) + else: + mpc_train_algorithm = f"{mpc_train_algorithm}test_Y = pfix.Array(test_record_count)\n" + mpc_train_algorithm = f"{mpc_train_algorithm}test_X = pfix.Matrix(test_record_count, total_feature_count)\n" + mpc_train_algorithm = f"{mpc_train_algorithm}" \ + f"layers = [pDense({record_type}, total_feature_count, 128, " \ + f"activation='relu'), pDense({record_type}, 128, 1), " \ + f"ml.Output({record_type}, approx=3)]\n" + mpc_train_algorithm = f"{mpc_train_algorithm}\n" + return mpc_train_algorithm + + +def set_logreg_train_layers(mpc_algorithm): + mpc_algorithm = f"{mpc_algorithm}\n" + mpc_algorithm = f"{mpc_algorithm}layers = [pDense(train_record_count, total_feature_count, 1), ml.Output(train_record_count, approx=3)]\n\n" + mpc_algorithm = f"{mpc_algorithm}test_Y = pfix.Array(test_record_count)\n" + mpc_algorithm = f"{mpc_algorithm}test_X = pfix.Matrix(test_record_count, total_feature_count)\n" + return mpc_algorithm + + +def generate_set_logreg_predict_layers(mpc_algorithm): + mpc_algorithm = f"{mpc_algorithm}\n" + mpc_algorithm = f"{mpc_algorithm}layers = [pDense(test_record_count, total_feature_count, 1), ml.Output(test_record_count, approx=3)]\n" + return mpc_algorithm + + +def generate_homo_predict_static_template(mpc_predict_algorithm): + homo_nn_static_template = utils.read_content_from_file( + f'{get_dir()}homo_predict_static_template.mpc') + mpc_predict_algorithm = f'{mpc_predict_algorithm}\n' + mpc_predict_algorithm = f'{mpc_predict_algorithm}{homo_nn_static_template}' + return mpc_predict_algorithm + + +def set_hetero_train_static_template(model_config_dict, mpc_train_algorithm): + optimizer = model_config_dict['optimizer'] + learning_rate = model_config_dict['learning_rate'] + if optimizer == OptimizerType.sgd.name: + hetero_train_static_template = utils.read_content_from_file( + f'{get_dir()}hetero_train_sgd_static_template.mpc') + hetero_train_static_template = hetero_train_static_template.replace('gamma = MemValue(cfix(.1))', + f'gamma = MemValue(cfix({learning_rate}))') + elif optimizer == OptimizerType.adam.name: + hetero_train_static_template = utils.read_content_from_file( + f'{get_dir()}hetero_train_adam_static_template.mpc') + hetero_train_static_template = hetero_train_static_template.replace('gamma = MemValue(cfix(.001))', + f'gamma = MemValue(cfix({learning_rate}))') + mpc_train_algorithm = f'{mpc_train_algorithm}\n' + mpc_train_algorithm = f'{mpc_train_algorithm}{hetero_train_static_template}' + return mpc_train_algorithm + + +def generate_hetero_predict_static_template(mpc_predict_algorithm): + hetero_logreg_static_template = utils.read_content_from_file( + f'{get_dir()}hetero_predict_static_template.mpc') + mpc_predict_algorithm = f'{mpc_predict_algorithm}\n' + mpc_predict_algorithm = f'{mpc_predict_algorithm}{hetero_logreg_static_template}' + return mpc_predict_algorithm + + +def set_homo_train_static_template(model_config_dict, mpc_train_algorithm): + optimizer = model_config_dict['optimizer'] + learning_rate = model_config_dict['learning_rate'] + if optimizer == OptimizerType.sgd.name: + homo_train_static_template = utils.read_content_from_file( + f'{get_dir()}homo_train_sgd_static_template.mpc') + homo_train_static_template = homo_train_static_template.replace('gamma = MemValue(cfix(.1))', + f'gamma = MemValue(cfix({learning_rate}))') + elif optimizer == OptimizerType.adam.name: + homo_train_static_template = utils.read_content_from_file( + f'{get_dir()}homo_train_adam_static_template.mpc') + homo_train_static_template = homo_train_static_template.replace('gamma = MemValue(cfix(.001))', + f'gamma = MemValue(cfix({learning_rate}))') + mpc_train_algorithm = f'{mpc_train_algorithm}\n' + mpc_train_algorithm = f'{mpc_train_algorithm}{homo_train_static_template}' + return mpc_train_algorithm + + +def generate_set_common_code(is_psi, participants): + mpc_algorithm = '#This file is auto generated by ppc. DO NOT EDIT!\n\n' + if is_psi: + mpc_algorithm = f'{mpc_algorithm}#PSI_OPTION=True' + else: + mpc_algorithm = f'{mpc_algorithm}#PSI_OPTION=False' + mpc_algorithm = f'{mpc_algorithm}\n' + mpc_algorithm = f'{mpc_algorithm}from ppc import *\n' + mpc_algorithm = f'{mpc_algorithm}from Compiler import config\n' + mpc_algorithm = f'{mpc_algorithm}import sys\n' + mpc_algorithm = f'{mpc_algorithm}program.options_from_args()\n\n' + mpc_algorithm = f'{mpc_algorithm}program.use_trunc_pr = True\n' + mpc_algorithm = f'{mpc_algorithm}program.use_split(3)\n\n' + # if participants == 3: + # mpc_algorithm = f'{mpc_algorithm}program.use_trunc_pr = True\n' + # mpc_algorithm = f'{mpc_algorithm}program.use_split(3)\n\n' + for i in range(participants): + mpc_algorithm = f'{mpc_algorithm}SOURCE{i}={i}\n' + return mpc_algorithm + + +def set_hetero_feature_count(mpc_algorithm, participants): + total_feature_count_str = 'total_feature_count=' + for i in range(participants): + mpc_algorithm = f'{mpc_algorithm}source{i}_feature_count=$(source{i}_feature_count)\n' + if i == participants - 1: + total_feature_count_str = f'{total_feature_count_str}source{i}_feature_count' + else: + total_feature_count_str = f'{total_feature_count_str}source{i}_feature_count+' + mpc_algorithm = f'{mpc_algorithm}{total_feature_count_str}\n' + return mpc_algorithm + + +def set_homo_train_record_count(mpc_train_algorithm, participants): + total_record_count_str = 'total_record_count=' + for i in range(participants): + mpc_train_algorithm = f'{mpc_train_algorithm}source{i}_record_count=$(source{i}_record_count)\n' + if i == participants - 1: + total_record_count_str = f'{total_record_count_str}source{i}_record_count' + else: + total_record_count_str = f'{total_record_count_str}source{i}_record_count+' + mpc_train_algorithm = f'{mpc_train_algorithm}{total_record_count_str}\n' + mpc_train_algorithm = f'{mpc_train_algorithm}train_record_count=$(train_record_count)\n' + mpc_train_algorithm = f'{mpc_train_algorithm}test_record_count=$(test_record_count)\n' + return mpc_train_algorithm + + +def generate_set_homo_predict_record_count(mpc_predict_algorithm): + mpc_predict_algorithm = f'{mpc_predict_algorithm}total_feature_count=$(total_feature_count)\n' + mpc_predict_algorithm = f'{mpc_predict_algorithm}test_record_count=$(test_record_count)\n' + mpc_predict_algorithm = f'{mpc_predict_algorithm}test_X = pfix.Matrix(test_record_count, total_feature_count)\n' + return mpc_predict_algorithm + + +def set_hetero_train_record_count(mpc_train_algorithm): + mpc_train_algorithm = f'{mpc_train_algorithm}\n' + mpc_train_algorithm = f'{mpc_train_algorithm}total_record_count=$(total_record_count)\n' + mpc_train_algorithm = f'{mpc_train_algorithm}train_record_count=$(train_record_count)\n' + mpc_train_algorithm = f'{mpc_train_algorithm}test_record_count=$(test_record_count)\n' + mpc_train_algorithm = f'{mpc_train_algorithm}\n' + return mpc_train_algorithm + + +def generate_set_hetero_predict_record_count(mpc_predict_algorithm): + mpc_predict_algorithm = f'{mpc_predict_algorithm}\n' + mpc_predict_algorithm = f'{mpc_predict_algorithm}test_record_count=$(test_record_count)\n' + mpc_predict_algorithm = f'{mpc_predict_algorithm}test_X = pfix.Matrix(test_record_count, total_feature_count)\n' + return mpc_predict_algorithm + + +def set_homo_feature_count(mpc_train_algorithm): + mpc_train_algorithm = f'{mpc_train_algorithm}\n' + mpc_train_algorithm = f'{mpc_train_algorithm}total_feature_count=$(total_feature_count)\n' + mpc_train_algorithm = f'{mpc_train_algorithm}\n' + return mpc_train_algorithm + + +def read_hetero_train_dataset(mpc_train_algorithm, participants): + mpc_train_algorithm = f'{mpc_train_algorithm}def read_hetero_dataset():\n' + mpc_train_algorithm = f'{mpc_train_algorithm}\tprint(f"train_record_count:{{train_record_count}}")\n' + mpc_train_algorithm = f'{mpc_train_algorithm}\tprint(f"test_record_count:{{test_record_count}}")\n' + mpc_train_algorithm = f'{mpc_train_algorithm}\tdo_read_hetero_y_part(SOURCE0)\n' + for i in range(participants): + mpc_train_algorithm = f'{mpc_train_algorithm}\tdo_read_hetero_x_part(SOURCE{i}, source{i}_feature_count)\n' + return mpc_train_algorithm + + +def generate_read_hetero_predict_dataset(mpc_predict_algorithm, participants): + mpc_predict_algorithm = f'{mpc_predict_algorithm}\n' + mpc_predict_algorithm = f'{mpc_predict_algorithm}def read_hetero_test_dataset():\n' + for i in range(participants): + mpc_predict_algorithm = f'{mpc_predict_algorithm}\tdo_read_hetero_x_part(SOURCE{i}, source{i}_feature_count)\n' + return mpc_predict_algorithm + + +def read_homo_dataset(mpc_train_algorithm, participants): + mpc_train_algorithm = f'{mpc_train_algorithm}def read_homo_dataset():\n' + mpc_train_algorithm = f'{mpc_train_algorithm}\tprint(f"total_feature_count:{{total_feature_count}}")\n' + mpc_train_algorithm = f'{mpc_train_algorithm}\tprint(f"train_record_count:{{train_record_count}}")\n' + mpc_train_algorithm = f'{mpc_train_algorithm}\tprint(f"test_record_count:{{test_record_count}}")\n' + for i in range(participants): + mpc_train_algorithm = f'{mpc_train_algorithm}\tdo_read_homo_dataset(SOURCE{i}, source{i}_record_count)\n' + + return mpc_train_algorithm + + +def set_parameters(model_config_dict, mpc_train_algorithm): + mpc_train_algorithm = f'{mpc_train_algorithm}\n' + epochs = model_config_dict['epochs'] + batch_size = model_config_dict['batch_size'] + threads = model_config_dict['threads'] + if epochs <= 0: + mpc_train_algorithm = f'{mpc_train_algorithm}epochs={default_epochs}\n' + else: + mpc_train_algorithm = f'{mpc_train_algorithm}epochs={epochs}\n' + if int(batch_size) <= 0: + mpc_train_algorithm = f'{mpc_train_algorithm}batch_size=train_record_count\n' + else: + mpc_train_algorithm = f'{mpc_train_algorithm}user_batch_size={batch_size}\n' + mpc_train_algorithm = f'{mpc_train_algorithm}batch_size=min(user_batch_size, min(128, train_record_count))\n' + if threads <= 0: + mpc_train_algorithm = f'{mpc_train_algorithm}threads={default_threads}\n' + else: + mpc_train_algorithm = f'{mpc_train_algorithm}threads={threads}\n' + return mpc_train_algorithm + + +def generate_mpc_train_algorithm(model_config_dict, algorithm_name, is_psi): + participants = model_config_dict['participants'] + mpc_train_algorithm = generate_set_common_code(is_psi, participants) + if algorithm_name == ModelAlgorithmType.HeteroLR.name or algorithm_name == ModelAlgorithmType.HeteroNN.name: + mpc_train_algorithm = set_hetero_feature_count( + mpc_train_algorithm, participants) + mpc_train_algorithm = set_hetero_train_record_count( + mpc_train_algorithm) + mpc_train_algorithm = read_hetero_train_dataset( + mpc_train_algorithm, participants) + mpc_train_algorithm = set_parameters( + model_config_dict, mpc_train_algorithm) + if algorithm_name == ModelAlgorithmType.HeteroLR.name: + if 'layers' in model_config_dict.keys(): + raise PpcException(PpcErrorCode.ALGORITHM_PPC_MODEL_LAYERS_ERROR.get_code(), + PpcErrorCode.ALGORITHM_PPC_MODEL_LAYERS_ERROR.get_msg()) + mpc_train_algorithm = set_logreg_train_layers(mpc_train_algorithm) + mpc_train_algorithm = set_hetero_train_static_template( + model_config_dict, mpc_train_algorithm) + else: + layers = [] + if 'layers' in model_config_dict.keys(): + layers = model_config_dict['layers'] + if layers and 'Conv2d' in layers[0]: + raise PpcException(PpcErrorCode.ALGORITHM_PPC_MODEL_LAYERS_ERROR2.get_code(), + PpcErrorCode.ALGORITHM_PPC_MODEL_LAYERS_ERROR2.get_msg()) + mpc_train_algorithm = set_nn_layers( + mpc_train_algorithm, layers, 'train_record_count') + mpc_train_algorithm = set_hetero_train_static_template( + model_config_dict, mpc_train_algorithm) + elif algorithm_name == ModelAlgorithmType.HomoLR.name or algorithm_name == ModelAlgorithmType.HomoNN.name: + mpc_train_algorithm = set_homo_train_record_count( + mpc_train_algorithm, participants) + mpc_train_algorithm = set_parameters( + model_config_dict, mpc_train_algorithm) + mpc_train_algorithm = set_homo_feature_count(mpc_train_algorithm) + mpc_train_algorithm = read_homo_dataset( + mpc_train_algorithm, participants) + if algorithm_name == ModelAlgorithmType.HomoLR.name: + if 'layers' in model_config_dict.keys(): + raise PpcException(PpcErrorCode.ALGORITHM_PPC_MODEL_LAYERS_ERROR.get_code(), + PpcErrorCode.ALGORITHM_PPC_MODEL_LAYERS_ERROR.get_msg()) + mpc_train_algorithm = set_logreg_train_layers(mpc_train_algorithm) + mpc_train_algorithm = set_homo_train_static_template( + model_config_dict, mpc_train_algorithm) + else: + layers = [] + if 'layers' in model_config_dict.keys(): + layers = model_config_dict['layers'] + mpc_train_algorithm = set_nn_layers( + mpc_train_algorithm, layers, 'train_record_count') + mpc_train_algorithm = set_homo_train_static_template( + model_config_dict, mpc_train_algorithm) + + return mpc_train_algorithm + + +def generate_mpc_predict_algorithm(algorithm_name, layers, participants, is_psi): + mpc_predict_algorithm = generate_set_common_code(is_psi, participants) + if algorithm_name == ModelAlgorithmType.HeteroLR.name or algorithm_name == ModelAlgorithmType.HeteroNN.name: + mpc_predict_algorithm = set_hetero_feature_count( + mpc_predict_algorithm, participants) + mpc_predict_algorithm = generate_set_hetero_predict_record_count( + mpc_predict_algorithm) + mpc_predict_algorithm = generate_read_hetero_predict_dataset( + mpc_predict_algorithm, participants) + if algorithm_name == ModelAlgorithmType.HeteroLR.name: + mpc_predict_algorithm = generate_set_logreg_predict_layers( + mpc_predict_algorithm) + else: + mpc_predict_algorithm = set_nn_layers( + mpc_predict_algorithm, layers, 'test_record_count') + mpc_predict_algorithm = generate_hetero_predict_static_template( + mpc_predict_algorithm) + + elif algorithm_name == ModelAlgorithmType.HomoLR.name or algorithm_name == ModelAlgorithmType.HomoNN.name: + mpc_predict_algorithm = generate_set_homo_predict_record_count( + mpc_predict_algorithm) + if algorithm_name == ModelAlgorithmType.HomoLR.name: + mpc_predict_algorithm = generate_set_logreg_predict_layers( + mpc_predict_algorithm) + else: + mpc_predict_algorithm = set_nn_layers( + mpc_predict_algorithm, layers, 'test_record_count') + mpc_predict_algorithm = generate_homo_predict_static_template( + mpc_predict_algorithm) + + return mpc_predict_algorithm + + # try: + # test_dataset_percentage = float(model_config_dict['test_dataset_percentage']) + # model_config_dict['test_dataset_percentage'] = test_dataset_percentage + # if not 0 < test_dataset_percentage <= 0.5: + # raise PpcException(PpcErrorCode.ALGORITHM_PPC_MODEL_TEST_DATASET_PERCENTAGE_ERROR.get_code(), + # PpcErrorCode.ALGORITHM_PPC_MODEL_TEST_DATASET_PERCENTAGE_ERROR.get_msg()) + # except BaseException as e: + # raise PpcException(PpcErrorCode.ALGORITHM_PPC_MODEL_TEST_DATASET_PERCENTAGE_ERROR.get_code(), + # PpcErrorCode.ALGORITHM_PPC_MODEL_TEST_DATASET_PERCENTAGE_ERROR.get_msg()) + + # try: + # learning_rate = float(model_config_dict['learning_rate']) + # model_config_dict['learning_rate'] = learning_rate + # if not 0 < learning_rate <= 1: + # raise PpcException(PpcErrorCode.ALGORITHM_PPC_MODEL_LEARNING_RATE_ERROR.get_code(), + # PpcErrorCode.ALGORITHM_PPC_MODEL_LEARNING_RATE_ERROR.get_msg()) + # except BaseException as e: + # raise PpcException(PpcErrorCode.ALGORITHM_PPC_MODEL_LEARNING_RATE_ERROR.get_code(), + # PpcErrorCode.ALGORITHM_PPC_MODEL_LEARNING_RATE_ERROR.get_msg()) + + # try: + # num_trees = int(model_config_dict['num_trees']) + # model_config_dict['num_trees'] = num_trees + # if not 0 < num_trees <= 300: + # raise PpcException(PpcErrorCode.ALGORITHM_PPC_MODEL_TREES_ERROR.get_code(), + # PpcErrorCode.ALGORITHM_PPC_MODEL_TREES_ERROR.get_msg()) + # except BaseException as e: + # raise PpcException(PpcErrorCode.ALGORITHM_PPC_MODEL_TREES_ERROR.get_code(), + # PpcErrorCode.ALGORITHM_PPC_MODEL_TREES_ERROR.get_msg()) + + # try: + # max_depth = int(model_config_dict['max_depth']) + # model_config_dict['max_depth'] = max_depth + # if not 0 < max_depth <= 10: + # raise PpcException(PpcErrorCode.ALGORITHM_PPC_MODEL_DEPTH_ERROR.get_code(), + # PpcErrorCode.ALGORITHM_PPC_MODEL_DEPTH_ERROR.get_msg()) + # except BaseException as e: + # raise PpcException(PpcErrorCode.ALGORITHM_PPC_MODEL_DEPTH_ERROR.get_code(), + # PpcErrorCode.ALGORITHM_PPC_MODEL_DEPTH_ERROR.get_msg()) + + # try: + # threads = int(model_config_dict['threads']) + # model_config_dict['threads'] = threads + # if not (0 < threads <= 8): + # raise PpcException(PpcErrorCode.ALGORITHM_PPC_MODEL_THREADS_ERROR.get_code(), + # PpcErrorCode.ALGORITHM_PPC_MODEL_THREADS_ERROR.get_msg()) + # except BaseException as e: + # raise PpcException(PpcErrorCode.ALGORITHM_PPC_MODEL_THREADS_ERROR.get_code(), + # PpcErrorCode.ALGORITHM_PPC_MODEL_THREADS_ERROR.get_msg()) diff --git a/python/ppc_common/ppc_utils/ppc_model_config_parser_proxy.py b/python/ppc_common/ppc_utils/ppc_model_config_parser_proxy.py new file mode 100644 index 00000000..b5aa49e9 --- /dev/null +++ b/python/ppc_common/ppc_utils/ppc_model_config_parser_proxy.py @@ -0,0 +1,491 @@ +# coding:utf-8 +import os +import unittest +from enum import unique, Enum + +from ppc_common.ppc_utils import utils +from ppc_common.ppc_utils.exception import PpcException, PpcErrorCode +from ppc_common.ppc_utils.utils import check_ppc_model_algorithm_is_homo, parse_n_class, PPCModleType + + +@unique +class ModelAlgorithmType(Enum): + HeteroLR = 1 + HomoLR = 2 + HeteroNN = 3 + HomoNN = 4 + + +@unique +class OptimizerType(Enum): + sgd = 1 + adam = 2 + + +algorithm_types = [ModelAlgorithmType.HeteroLR.name, ModelAlgorithmType.HomoLR.name, ModelAlgorithmType.HeteroNN.name, + ModelAlgorithmType.HomoNN.name] + +optimizer_types = [OptimizerType.sgd.name, OptimizerType.adam.name] + +default_epochs = 10 +default_threads = 8 + +FILE_PATH = os.path.abspath(__file__) +CURRENT_PATH = os.path.abspath(os.path.dirname(FILE_PATH) + os.path.sep + ".") + + +def get_dir(): + ppc_model_template_dir = f'{CURRENT_PATH}{os.sep}..{os.sep}ppc_model_template{os.sep}' + return ppc_model_template_dir + + +def parse_read_hetero_dataset_loop(participants): + loop_start = [] + loop_end = [] + start = '' + end = '' + for i in range(participants): + if i == 0 or i == participants - 1: + if i == 0: + start = f'{start}source{i}_feature_count' + end = f'{start} + source{i + 1}_feature_count' + else: + start = f'{start} + source{i}_feature_count' + end = f'{start} + source{i + 1}_feature_count' + else: + start = f'{start} + source{i}_feature_count' + end = f'{start} + source{i + 1}_feature_count' + loop_start.append(start) + loop_end.append(end) + return participants - 1, loop_start[0:participants - 1], loop_end[0:participants - 1] + + +def parse_read_homo_dataset_loop(participants): + loop_start = [] + loop_end = [] + start = '' + end = '' + for i in range(participants): + if i == 0 or i == participants - 1: + if i == 0: + start = f'{start}source{i}_record_count' + end = f'{start} + source{i + 1}_record_count' + else: + start = f'{start} + source{i}_record_count' + end = f'{start} + source{i + 1}_record_count' + else: + start = f'{start} + source{i}_record_count' + end = f'{start} + source{i + 1}_record_count' + loop_start.append(start) + loop_end.append(end) + return participants - 1, loop_start[0:participants - 1], loop_end[0:participants - 1] + + +def insert_train_record_count(layer, index, record_type): + if 'Dense' in layer: + layer_arr = layer.split('(') + else: + layer_arr = layer.split('([') + if index == 0 and 'Dense' in layer: + new_layer = f'{layer_arr[0]}({record_type}, total_feature_count, {layer_arr[1]}' + else: + if 'Dense' in layer: + new_layer = f'{layer_arr[0]}({record_type}, {layer_arr[1]}' + else: + new_layer = f'{layer_arr[0]}([{record_type}, {layer_arr[1]}' + if 'Conv2d' in new_layer: + if ', [' in new_layer: + layer_arr2 = new_layer.split(', [') + new_layer = f'{layer_arr2[0]}, [{record_type}, {layer_arr2[1]}' + if ',[' in new_layer: + layer_arr2 = new_layer.split(',[') + new_layer = f'{layer_arr2[0]},[{record_type}, {layer_arr2[1]}' + return new_layer + + +def set_nn_layers(mpc_algorithm, layers, record_type, ppc_model_type=None, model_algorithm_type=None, participants=None): + mpc_algorithm = f"{mpc_algorithm}\n" + if layers: + layers_str = 'layers = [' + for i in range(len(layers)): + new_layer = insert_train_record_count(layers[i], i, record_type) + layers_str = f"{layers_str}{new_layer},\n" + n_class = parse_n_class(layers[-1]) + if ppc_model_type == PPCModleType.Train: + mpc_algorithm = set_nn_train_output(mpc_algorithm, n_class) + else: + mpc_algorithm = set_nn_predict_output(mpc_algorithm, n_class) + mpc_algorithm = f"{mpc_algorithm}{layers_str}" + if n_class == 1: + mpc_algorithm = f"{mpc_algorithm}ml.Output({record_type}, approx=3)]\n\n" + if ppc_model_type == PPCModleType.Train: + mpc_algorithm = f"{mpc_algorithm}train_Y = layers[-1].Y\n" + mpc_algorithm = f"{mpc_algorithm}train_X = layers[0].X\n" + mpc_algorithm = f"{mpc_algorithm}test_Y = pint.Array(test_record_count)\n" + mpc_algorithm = f"{mpc_algorithm}test_X = pfix.Matrix(test_record_count, total_feature_count)\n" + elif n_class > 1: + mpc_algorithm = f"{mpc_algorithm}ml.MultiOutput({record_type}, {n_class})]\n\n" + if ppc_model_type == PPCModleType.Train: + mpc_algorithm = f"{mpc_algorithm}total_class_count = {n_class}\n" + mpc_algorithm = f"{mpc_algorithm}train_Y = layers[-1].Y\n" + mpc_algorithm = f"{mpc_algorithm}train_X = layers[0].X\n" + mpc_algorithm = f"{mpc_algorithm}test_Y = pint.Matrix(test_record_count, total_class_count)\n" + mpc_algorithm = f"{mpc_algorithm}test_X = pfix.Matrix(test_record_count, total_feature_count)\n" + else: + raise PpcException(PpcErrorCode.ALGORITHM_PPC_MODEL_OUTPUT_NUMBER_ERROR.get_code(), + PpcErrorCode.ALGORITHM_PPC_MODEL_OUTPUT_NUMBER_ERROR.get_msg()) + + if ppc_model_type == PPCModleType.Train and model_algorithm_type == ModelAlgorithmType.HeteroNN: + mpc_algorithm = read_hetero_train_dataset( + mpc_algorithm, participants, n_class) + if ppc_model_type == PPCModleType.Train and model_algorithm_type == ModelAlgorithmType.HomoNN: + mpc_algorithm = read_homo_train_dataset( + mpc_algorithm, participants, n_class) + else: + mpc_algorithm = set_nn_train_output(mpc_algorithm, 1) + mpc_algorithm = f"{mpc_algorithm}" \ + f"layers = [pDense({record_type}, total_feature_count, 128, " \ + f"activation='relu'), pDense({record_type}, 128, 1), " \ + f"ml.Output({record_type}, approx=3)]\n" + if ppc_model_type == PPCModleType.Train: + mpc_algorithm = f"{mpc_algorithm}train_Y = layers[-1].Y\n" + mpc_algorithm = f"{mpc_algorithm}train_X = layers[0].X\n" + mpc_algorithm = f"{mpc_algorithm}test_Y = pint.Array(test_record_count)\n" + mpc_algorithm = f"{mpc_algorithm}test_X = pfix.Matrix(test_record_count, total_feature_count)\n" + mpc_algorithm = f"{mpc_algorithm}\n" + mpc_algorithm = read_homo_train_dataset(mpc_algorithm, participants) + + return mpc_algorithm + + +def set_logreg_train_layers(mpc_algorithm): + mpc_algorithm = f"{mpc_algorithm}\n" + mpc_algorithm = f"{mpc_algorithm}layers = [pDense(train_record_count, total_feature_count, 1), ml.Output(train_record_count, approx=3)]\n\n" + mpc_algorithm = f"{mpc_algorithm}train_Y = layers[-1].Y\n" + mpc_algorithm = f"{mpc_algorithm}train_X = layers[0].X\n" + mpc_algorithm = f"{mpc_algorithm}test_Y = pint.Array(test_record_count)\n" + mpc_algorithm = f"{mpc_algorithm}test_X = pfix.Matrix(test_record_count, total_feature_count)\n" + return mpc_algorithm + + +def generate_set_logreg_predict_layers(mpc_algorithm): + mpc_algorithm = f"{mpc_algorithm}\n" + mpc_algorithm = f"{mpc_algorithm}layers = [pDense(test_record_count, total_feature_count, 1), ml.Output(test_record_count, approx=3)]\n\n" + mpc_algorithm = f"{mpc_algorithm}result_columns = 1\n" + mpc_algorithm = f"{mpc_algorithm}result_matrix = Matrix(test_record_count, result_columns, pfix)\n\n" + return mpc_algorithm + + +def generate_homo_predict_static_template(mpc_predict_algorithm): + homo_nn_static_template = utils.read_content_from_file( + f'{get_dir()}homo_predict_static_template_proxy.mpc') + mpc_predict_algorithm = f'{mpc_predict_algorithm}\n' + mpc_predict_algorithm = f'{mpc_predict_algorithm}{homo_nn_static_template}' + return mpc_predict_algorithm + + +def set_hetero_train_static_template(model_config_dict, mpc_train_algorithm): + optimizer = model_config_dict['optimizer'] + learning_rate = model_config_dict['learning_rate'] + if optimizer == OptimizerType.sgd.name: + hetero_train_static_template = utils.read_content_from_file( + f'{get_dir()}hetero_train_sgd_static_template_proxy.mpc') + hetero_train_static_template = hetero_train_static_template.replace('gamma = MemValue(cfix(.1))', + f'gamma = MemValue(cfix({learning_rate}))') + elif optimizer == OptimizerType.adam.name: + hetero_train_static_template = utils.read_content_from_file( + f'{get_dir()}hetero_train_adam_static_template_proxy.mpc') + hetero_train_static_template = hetero_train_static_template.replace('gamma = MemValue(cfix(.001))', + f'gamma = MemValue(cfix({learning_rate}))') + mpc_train_algorithm = f'{mpc_train_algorithm}\n' + mpc_train_algorithm = f'{mpc_train_algorithm}{hetero_train_static_template}' + return mpc_train_algorithm + + +def generate_hetero_predict_static_template(mpc_predict_algorithm): + hetero_logreg_static_template = utils.read_content_from_file( + f'{get_dir()}hetero_predict_static_template_proxy.mpc') + mpc_predict_algorithm = f'{mpc_predict_algorithm}\n' + mpc_predict_algorithm = f'{mpc_predict_algorithm}{hetero_logreg_static_template}' + return mpc_predict_algorithm + + +def set_homo_train_static_template(model_config_dict, mpc_train_algorithm): + optimizer = model_config_dict['optimizer'] + learning_rate = model_config_dict['learning_rate'] + if optimizer == OptimizerType.sgd.name: + homo_train_static_template = utils.read_content_from_file( + f'{get_dir()}homo_train_sgd_static_template_proxy.mpc') + homo_train_static_template = homo_train_static_template.replace('gamma = MemValue(cfix(.1))', + f'gamma = MemValue(cfix({learning_rate}))') + elif optimizer == OptimizerType.adam.name: + homo_train_static_template = utils.read_content_from_file( + f'{get_dir()}homo_train_adam_static_template_proxy.mpc') + homo_train_static_template = homo_train_static_template.replace('gamma = MemValue(cfix(.001))', + f'gamma = MemValue(cfix({learning_rate}))') + mpc_train_algorithm = f'{mpc_train_algorithm}\n' + mpc_train_algorithm = f'{mpc_train_algorithm}{homo_train_static_template}' + return mpc_train_algorithm + + +def generate_set_common_code(is_psi, participants): + mpc_algorithm = '#This file is auto generated by ppc. DO NOT EDIT!\n\n' + if is_psi: + mpc_algorithm = f'{mpc_algorithm}#PSI_OPTION=True' + else: + mpc_algorithm = f'{mpc_algorithm}#PSI_OPTION=False' + mpc_algorithm = f'{mpc_algorithm}\n' + mpc_algorithm = f'{mpc_algorithm}from ppc import *\n' + mpc_algorithm = f'{mpc_algorithm}from Compiler import config\n' + mpc_algorithm = f'{mpc_algorithm}import sys\n' + mpc_algorithm = f'{mpc_algorithm}program.options_from_args()\n\n' + # if participants == 3: + # mpc_algorithm = f'{mpc_algorithm}program.use_trunc_pr = True\n' + # mpc_algorithm = f'{mpc_algorithm}program.use_split(3)\n\n' + for i in range(participants): + mpc_algorithm = f'{mpc_algorithm}SOURCE{i}={i}\n' + return mpc_algorithm + + +def set_hetero_feature_count(mpc_algorithm, participants): + total_feature_count_str = 'total_feature_count=' + for i in range(participants): + mpc_algorithm = f'{mpc_algorithm}source{i}_feature_count=$(source{i}_feature_count)\n' + if i == participants - 1: + total_feature_count_str = f'{total_feature_count_str}source{i}_feature_count' + else: + total_feature_count_str = f'{total_feature_count_str}source{i}_feature_count+' + mpc_algorithm = f'{mpc_algorithm}{total_feature_count_str}\n' + return mpc_algorithm + + +def set_homo_train_record_count(mpc_train_algorithm, participants): + total_record_count_str = 'total_record_count=' + for i in range(participants): + mpc_train_algorithm = f'{mpc_train_algorithm}source{i}_record_count=$(source{i}_record_count)\n' + if i == participants - 1: + total_record_count_str = f'{total_record_count_str}source{i}_record_count' + else: + total_record_count_str = f'{total_record_count_str}source{i}_record_count+' + mpc_train_algorithm = f'{mpc_train_algorithm}{total_record_count_str}\n' + mpc_train_algorithm = f'{mpc_train_algorithm}train_record_count=$(train_record_count)\n' + mpc_train_algorithm = f'{mpc_train_algorithm}test_record_count=$(test_record_count)\n' + mpc_train_algorithm = f'{mpc_train_algorithm}total_feature_count=$(total_feature_count)\n' + return mpc_train_algorithm + + +def generate_set_homo_predict_record_count(mpc_predict_algorithm): + mpc_predict_algorithm = f'{mpc_predict_algorithm}total_feature_count=$(total_feature_count)\n' + mpc_predict_algorithm = f'{mpc_predict_algorithm}test_record_count=$(test_record_count)\n' + mpc_predict_algorithm = f'{mpc_predict_algorithm}test_X = pfix.Matrix(test_record_count, total_feature_count)\n\n' + mpc_predict_algorithm = f'{mpc_predict_algorithm}file_offset = 0\n' + mpc_predict_algorithm = f'{mpc_predict_algorithm}file_offset = test_X.read_from_file(file_offset)\n' + return mpc_predict_algorithm + + +def set_hetero_train_record_count(mpc_train_algorithm): + mpc_train_algorithm = f'{mpc_train_algorithm}\n' + mpc_train_algorithm = f'{mpc_train_algorithm}total_record_count=$(total_record_count)\n' + mpc_train_algorithm = f'{mpc_train_algorithm}train_record_count=$(train_record_count)\n' + mpc_train_algorithm = f'{mpc_train_algorithm}test_record_count=$(test_record_count)\n' + mpc_train_algorithm = f'{mpc_train_algorithm}\n' + return mpc_train_algorithm + + +def generate_set_hetero_predict_record_count(mpc_predict_algorithm): + mpc_predict_algorithm = f'{mpc_predict_algorithm}\n' + mpc_predict_algorithm = f'{mpc_predict_algorithm}test_record_count=$(test_record_count)\n' + mpc_predict_algorithm = f'{mpc_predict_algorithm}test_X = pfix.Matrix(test_record_count, total_feature_count)\n' + return mpc_predict_algorithm + + +def read_hetero_train_dataset(mpc_train_algorithm, participants, n_class=1): + mpc_train_algorithm = f'{mpc_train_algorithm}\n' + mpc_train_algorithm = f'{mpc_train_algorithm}file_offset = 0\n' + for i in range(participants): + if i == 0: + if n_class == 1: + mpc_train_algorithm = f'{mpc_train_algorithm}source0_record_y = Array(total_record_count, pint)\n' + elif n_class > 1: + mpc_train_algorithm = f'{mpc_train_algorithm}source0_record_y = Matrix(total_record_count, total_class_count, pint)\n' + mpc_train_algorithm = f'{mpc_train_algorithm}source0_record_x = Matrix(total_record_count, source0_feature_count, pfix)\n' + mpc_train_algorithm = f'{mpc_train_algorithm}file_offset = source0_record_y.read_from_file(file_offset)\n' + mpc_train_algorithm = f'{mpc_train_algorithm}file_offset = source0_record_x.read_from_file(file_offset)\n\n' + else: + mpc_train_algorithm = f'{mpc_train_algorithm}source{i}_record_x = Matrix(total_record_count, source{i}_feature_count, pfix)\n' + mpc_train_algorithm = f'{mpc_train_algorithm}file_offset = source{i}_record_x.read_from_file(file_offset)\n\n' + + mpc_train_algorithm = f'{mpc_train_algorithm}def read_hetero_dataset():\n' + mpc_train_algorithm = f'{mpc_train_algorithm}\tprint(f"train_record_count:{{train_record_count}}")\n' + mpc_train_algorithm = f'{mpc_train_algorithm}\tprint(f"test_record_count:{{test_record_count}}")\n' + mpc_train_algorithm = f'{mpc_train_algorithm}\tdo_read_hetero_y_part()\n' + for i in range(participants): + mpc_train_algorithm = f'{mpc_train_algorithm}\tdo_read_hetero_x_part(source{i}_record_x, source{i}_feature_count)\n' + mpc_train_algorithm = f'{mpc_train_algorithm}\n' + return mpc_train_algorithm + + +def generate_read_hetero_predict_dataset(mpc_predict_algorithm, participants): + mpc_predict_algorithm = f'{mpc_predict_algorithm}\n' + mpc_predict_algorithm = f'{mpc_predict_algorithm}file_offset = 0\n' + for i in range(participants): + mpc_predict_algorithm = f'{mpc_predict_algorithm}source{i}_record_x = Matrix(test_record_count, source{i}_feature_count, pfix)\n' + mpc_predict_algorithm = f'{mpc_predict_algorithm}file_offset = source{i}_record_x.read_from_file(file_offset)\n\n' + + mpc_predict_algorithm = f'{mpc_predict_algorithm}\n' + mpc_predict_algorithm = f'{mpc_predict_algorithm}def read_hetero_test_dataset():\n' + for i in range(participants): + mpc_predict_algorithm = f'{mpc_predict_algorithm}\tdo_read_hetero_x_part(source{i}_record_x, source{i}_feature_count)\n' + return mpc_predict_algorithm + + +def read_homo_train_dataset(mpc_train_algorithm, participants, n_class=1): + mpc_train_algorithm = f'{mpc_train_algorithm}\n' + mpc_train_algorithm = f'{mpc_train_algorithm}file_offset = 0\n' + for i in range(participants): + if n_class == 1: + mpc_train_algorithm = f'{mpc_train_algorithm}source{i}_record_y = Array(source{i}_record_count, pint)\n' + elif n_class > 1: + mpc_train_algorithm = f'{mpc_train_algorithm}source{i}_record_y = Matrix(source{i}_record_count, total_class_count, pint)\n' + mpc_train_algorithm = f'{mpc_train_algorithm}source{i}_record_x = Matrix(source{i}_record_count, total_feature_count, pfix)\n' + mpc_train_algorithm = f'{mpc_train_algorithm}file_offset = source{i}_record_y.read_from_file(file_offset)\n' + mpc_train_algorithm = f'{mpc_train_algorithm}file_offset = source{i}_record_x.read_from_file(file_offset)\n\n' + + mpc_train_algorithm = f'{mpc_train_algorithm}def read_homo_dataset():\n' + mpc_train_algorithm = f'{mpc_train_algorithm}\tprint(f"total_feature_count:{{total_feature_count}}")\n' + mpc_train_algorithm = f'{mpc_train_algorithm}\tprint(f"train_record_count:{{train_record_count}}")\n' + mpc_train_algorithm = f'{mpc_train_algorithm}\tprint(f"test_record_count:{{test_record_count}}")\n' + for i in range(participants): + mpc_train_algorithm = f'{mpc_train_algorithm}\tdo_read_homo_dataset(source{i}_record_y, source{i}_record_x, source{i}_record_count)\n' + mpc_train_algorithm = f'{mpc_train_algorithm}\n' + return mpc_train_algorithm + + +def set_parameters(model_config_dict, mpc_train_algorithm): + mpc_train_algorithm = f'{mpc_train_algorithm}\n' + epochs = model_config_dict['epochs'] + batch_size = model_config_dict['batch_size'] + threads = model_config_dict['threads'] + if epochs <= 0: + mpc_train_algorithm = f'{mpc_train_algorithm}epochs={default_epochs}\n' + else: + mpc_train_algorithm = f'{mpc_train_algorithm}epochs={epochs}\n' + if int(batch_size) <= 0: + mpc_train_algorithm = f'{mpc_train_algorithm}batch_size=train_record_count\n' + else: + mpc_train_algorithm = f'{mpc_train_algorithm}user_batch_size={batch_size}\n' + mpc_train_algorithm = f'{mpc_train_algorithm}batch_size=min(user_batch_size, min(128, train_record_count))\n' + if threads <= 0: + mpc_train_algorithm = f'{mpc_train_algorithm}threads={default_threads}\n' + else: + mpc_train_algorithm = f'{mpc_train_algorithm}threads={threads}\n' + return mpc_train_algorithm + + +def set_lr_train_output(mpc_train_algorithm): + mpc_train_algorithm = f'{mpc_train_algorithm}result_columns = 2\n' + mpc_train_algorithm = f'{mpc_train_algorithm}result_matrix = Matrix(test_record_count, result_columns, pfix)\n\n' + return mpc_train_algorithm + + +def set_nn_train_output(mpc_train_algorithm, n_class): + mpc_train_algorithm = f'{mpc_train_algorithm}result_columns = {2*n_class}\n' + mpc_train_algorithm = f'{mpc_train_algorithm}result_matrix = Matrix(test_record_count, result_columns, pfix)\n\n' + return mpc_train_algorithm + + +def set_nn_predict_output(mpc_train_algorithm, n_class): + mpc_train_algorithm = f'{mpc_train_algorithm}result_columns = {n_class}\n' + mpc_train_algorithm = f'{mpc_train_algorithm}result_matrix = Matrix(test_record_count, result_columns, pfix)\n\n' + return mpc_train_algorithm + + +def generate_mpc_train_algorithm(model_config_dict, algorithm_name, is_psi): + participants = model_config_dict['participants'] + mpc_train_algorithm = generate_set_common_code(is_psi, participants) + if algorithm_name == ModelAlgorithmType.HeteroLR.name or algorithm_name == ModelAlgorithmType.HeteroNN.name: + mpc_train_algorithm = set_hetero_feature_count( + mpc_train_algorithm, participants) + mpc_train_algorithm = set_hetero_train_record_count( + mpc_train_algorithm) + mpc_train_algorithm = set_parameters( + model_config_dict, mpc_train_algorithm) + if algorithm_name == ModelAlgorithmType.HeteroLR.name: + if 'layers' in model_config_dict.keys(): + raise PpcException(PpcErrorCode.ALGORITHM_PPC_MODEL_LAYERS_ERROR.get_code(), + PpcErrorCode.ALGORITHM_PPC_MODEL_LAYERS_ERROR.get_msg()) + mpc_train_algorithm = read_hetero_train_dataset( + mpc_train_algorithm, participants) + mpc_train_algorithm = set_lr_train_output(mpc_train_algorithm) + mpc_train_algorithm = set_logreg_train_layers(mpc_train_algorithm) + mpc_train_algorithm = set_hetero_train_static_template( + model_config_dict, mpc_train_algorithm) + else: + layers = [] + if 'layers' in model_config_dict.keys(): + layers = model_config_dict['layers'] + if layers and 'Conv2d' in layers[0]: + raise PpcException(PpcErrorCode.ALGORITHM_PPC_MODEL_LAYERS_ERROR2.get_code(), + PpcErrorCode.ALGORITHM_PPC_MODEL_LAYERS_ERROR2.get_msg()) + mpc_train_algorithm = set_nn_layers( + mpc_train_algorithm, layers, 'train_record_count', PPCModleType.Train, ModelAlgorithmType.HeteroNN, participants) + mpc_train_algorithm = set_hetero_train_static_template( + model_config_dict, mpc_train_algorithm) + elif algorithm_name == ModelAlgorithmType.HomoLR.name or algorithm_name == ModelAlgorithmType.HomoNN.name: + mpc_train_algorithm = set_homo_train_record_count( + mpc_train_algorithm, participants) + mpc_train_algorithm = set_parameters( + model_config_dict, mpc_train_algorithm) + if algorithm_name == ModelAlgorithmType.HomoLR.name: + if 'layers' in model_config_dict.keys(): + raise PpcException(PpcErrorCode.ALGORITHM_PPC_MODEL_LAYERS_ERROR.get_code(), + PpcErrorCode.ALGORITHM_PPC_MODEL_LAYERS_ERROR.get_msg()) + mpc_train_algorithm = read_homo_train_dataset( + mpc_train_algorithm, participants) + mpc_train_algorithm = set_lr_train_output(mpc_train_algorithm) + mpc_train_algorithm = set_logreg_train_layers(mpc_train_algorithm) + mpc_train_algorithm = set_homo_train_static_template( + model_config_dict, mpc_train_algorithm) + else: + layers = [] + if 'layers' in model_config_dict.keys(): + layers = model_config_dict['layers'] + mpc_train_algorithm = set_nn_layers( + mpc_train_algorithm, layers, 'train_record_count', PPCModleType.Train, ModelAlgorithmType.HomoNN, participants) + mpc_train_algorithm = set_homo_train_static_template( + model_config_dict, mpc_train_algorithm) + + return mpc_train_algorithm + + +def generate_mpc_predict_algorithm(algorithm_name, layers, participants, is_psi): + mpc_predict_algorithm = generate_set_common_code(is_psi, participants) + if algorithm_name == ModelAlgorithmType.HeteroLR.name or algorithm_name == ModelAlgorithmType.HeteroNN.name: + mpc_predict_algorithm = set_hetero_feature_count( + mpc_predict_algorithm, participants) + mpc_predict_algorithm = generate_set_hetero_predict_record_count( + mpc_predict_algorithm) + mpc_predict_algorithm = generate_read_hetero_predict_dataset( + mpc_predict_algorithm, participants) + if algorithm_name == ModelAlgorithmType.HeteroLR.name: + mpc_predict_algorithm = generate_set_logreg_predict_layers( + mpc_predict_algorithm) + else: + mpc_predict_algorithm = set_nn_layers( + mpc_predict_algorithm, layers, 'test_record_count') + mpc_predict_algorithm = generate_hetero_predict_static_template( + mpc_predict_algorithm) + + elif algorithm_name == ModelAlgorithmType.HomoLR.name or algorithm_name == ModelAlgorithmType.HomoNN.name: + mpc_predict_algorithm = generate_set_homo_predict_record_count( + mpc_predict_algorithm) + if algorithm_name == ModelAlgorithmType.HomoLR.name: + mpc_predict_algorithm = generate_set_logreg_predict_layers( + mpc_predict_algorithm) + else: + mpc_predict_algorithm = set_nn_layers(mpc_predict_algorithm, layers, 'test_record_count', + PPCModleType.Predict, participants) + mpc_predict_algorithm = generate_homo_predict_static_template( + mpc_predict_algorithm) + + return mpc_predict_algorithm diff --git a/python/ppc_common/ppc_utils/tests/thread_safe_list_test.py b/python/ppc_common/ppc_utils/tests/thread_safe_list_test.py new file mode 100644 index 00000000..74028266 --- /dev/null +++ b/python/ppc_common/ppc_utils/tests/thread_safe_list_test.py @@ -0,0 +1,48 @@ +# -*- coding: utf-8 -*- +import unittest +import threading +from ppc_common.ppc_utils.thread_safe_list import ThreadSafeList + + +if __name__ == '__main__': + unittest.main() + +thread_safe_list = ThreadSafeList() + + +def test(object, thread_name, ut_obj): + try: + print(f"### thread: {thread_name}") + # append + thread_safe_list.append(object) + # contains + ut_obj.assertTrue(thread_safe_list.contains(object)) + # remove + thread_safe_list.remove(object) + ut_obj.assertTrue(thread_safe_list.contains(object) is False) + print(f"### result: {thread_safe_list.get()}") + # get element + copied_list = thread_safe_list.get() + if len(copied_list) >= 1: + thread_safe_list.get_element(len(copied_list) - 1) + thread_safe_list.get_element(len(copied_list)) + except Exception as e: + print(f"### Exception: {e}") + + +class TestThreadSafeList(unittest.TestCase): + def test_multi_thread(self): + loops = 5 + for j in range(loops): + thread_list = [] + thread_num = 20 + for i in range(thread_num): + thread_name = "t" + str(i) + "_" + str(j) + object = "job_" + str(j) + "_" + str(i) + t = threading.Thread(target=test, name=thread_name, args=(object, + thread_name, self)) + thread_list.append(t) + for t in thread_list: + t.start() + for t in thread_list: + t.join() diff --git a/python/ppc_common/ppc_utils/tests/utils_test.py b/python/ppc_common/ppc_utils/tests/utils_test.py new file mode 100644 index 00000000..42c11b4b --- /dev/null +++ b/python/ppc_common/ppc_utils/tests/utils_test.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +import unittest +from ppc_common.ppc_utils import utils +import os +import time + + +class FileOperationWrapper: + def __init__(self, file_chunk_dir, merged_file_path): + self.file_chunk_dir = file_chunk_dir + self.merged_file_path = merged_file_path + chunk_list = os.listdir(self.file_chunk_dir) + self.file_chunk_list = [] + for chunk in chunk_list: + self.file_chunk_list.append(os.path.join(file_chunk_dir, chunk)) + + +class TestFileOperations(unittest.TestCase): + def test_merge_and_calculate_hash_for_files(self): + chunk_file_dir = "/data/app/files/ppcs-modeladm/dataset" + # chunk_file_dir = "bak/object/train_test.csv" + wrapper = FileOperationWrapper(chunk_file_dir, "dataset1") + start_t = time.time() + print( + f"#### begin merge file for {len(wrapper.file_chunk_list)} chunks") + utils.merge_files(file_list=wrapper.file_chunk_list, + output_file=wrapper.merged_file_path) + print( + f"#### success merge file for {len(wrapper.file_chunk_list)} chunks success, time cost: {time.time() - start_t}") + + print( + f"#### calculate hash for {wrapper.merged_file_path}, size: {os.stat(wrapper.merged_file_path).st_size}") + start_t = time.time() + utils.calculate_md5(wrapper.merged_file_path) + print( + f"#### calculate hash for {wrapper.merged_file_path} success, size: {os.stat(wrapper.merged_file_path).st_size}, timecost: {time.time() - start_t}") + + +if __name__ == '__main__': + unittest.main() diff --git a/python/ppc_common/ppc_utils/thread_safe_list.py b/python/ppc_common/ppc_utils/thread_safe_list.py new file mode 100644 index 00000000..d34437f4 --- /dev/null +++ b/python/ppc_common/ppc_utils/thread_safe_list.py @@ -0,0 +1,56 @@ +# -*- coding: utf-8 -*- + +import threading + + +class ThreadSafeList: + def __init__(self): + self.processing_list = [] + self.lock = threading.Lock() + + def append(self, object): + try: + self.lock.acquire() + self.processing_list.append(object) + except Exception as e: + raise e + finally: + self.lock.release() + + def remove(self, object): + try: + self.lock.acquire() + self.processing_list.remove(object) + except Exception as e: + raise e + finally: + self.lock.release() + + def contains(self, object): + try: + self.lock.acquire() + return object in self.processing_list + except Exception as e: + raise e + finally: + self.lock.release() + + def get(self): + try: + copyed_list = [] + self.lock.acquire() + copyed_list.append(self.processing_list) + return copyed_list + except Exception as e: + raise e + finally: + self.lock.release() + + def get_element(self, i): + try: + self.lock.acquire() + return self.processing_list[i] + except Exception as e: + raise e + finally: + self.lock.release() diff --git a/python/ppc_common/ppc_utils/utils.py b/python/ppc_common/ppc_utils/utils.py new file mode 100644 index 00000000..5c38ee20 --- /dev/null +++ b/python/ppc_common/ppc_utils/utils.py @@ -0,0 +1,402 @@ +import base64 +import hashlib +import io +import json +import logging +import os +import re +import shutil +import subprocess +import time +from enum import Enum, unique + +import jwt +from gmssl import func, sm2, sm3 +from google.protobuf.descriptor import FieldDescriptor +from jsoncomment import JsonComment +from pysmx.SM3 import SM3 + +from ppc_common.ppc_utils.exception import PpcException, PpcErrorCode + +log = logging.getLogger(__name__) + +MAX_SUPPORTED_PARTIES = 5 + +SERVER_RUNNING_STATUS = 0 +DEFAULT_DATASET_RECORD_COUNT = 5 +DEFAULT_PAGE_OFFSET = 0 +DEFAULT_PAGE_SIZE = 5 +MIN_PARTICIPATE_NUMBER = 2 +TWO_PARTY_PSI_PARTICIPATE_NUMBER = 2 +MIN_MULTI_PARTY_PSI_PARTICIPATE_NUMBER = 3 +MPC_MAX_SOURCE_COUNT = 50 +MPC_MAX_FIELD_COUNT = 50 + +BASE_RESPONSE = {'errorCode': PpcErrorCode.SUCCESS.get_code( +), 'message': PpcErrorCode.SUCCESS.get_msg()} +LOG_NAME = 'ppcs-modeladm-scheduler.log' +LOG_CHARACTER_NUMBER = 100000 +CSV_SEP = ',' +BLANK_SEP = ' ' +NORMALIZED_NAMES = 'field{}' + +PPC_RESULT_FIELDS_FLAG = 'result_fields' +PPC_RESULT_VALUES_FLAG = 'result_values' + +ADMIN_USER = 'admin' + +MPC_RECORD_PLACE_HOLDER = '$(ppc_max_record_count)' +MPC_START_PLACE_HOLDER = '${ph_start}' +MPC_END_PLACE_HOLDER = '${ph_end}' + +HOMO_MODEL_ALGORITHM = 'homo' +MPC_TOTAL_RECORD_COUNT_PLACE_HOLDER = '$(total_record_count)' +MPC_TRAIN_RECORD_COUNT_PLACE_HOLDER = '$(train_record_count)' +MPC_TEST_RECORD_COUNT_PLACE_HOLDER = '$(test_record_count)' +MPC_TOTAL_FEATURE_COUNT_PLACE_HOLDER = '$(total_feature_count)' + +XGB_TREE_PERFIX = "xgb_tree" +MPC_TRAIN_METRIC_ROC_FILE = "mpc_metric_roc.svg" +MPC_TRAIN_METRIC_KS_FILE = "mpc_metric_ks.svg" +MPC_TRAIN_METRIC_PR_FILE = "mpc_metric_pr.svg" +MPC_TRAIN_METRIC_ACCURACY_FILE = "mpc_metric_accuracy.svg" +MPC_TRAIN_METRIC_KS_TABLE = "mpc_metric_ks.csv" +MPC_TRAIN_SET_METRIC_ROC_FILE = "mpc_train_metric_roc.svg" +MPC_TRAIN_SET_METRIC_KS_FILE = "mpc_train_metric_ks.svg" +MPC_TRAIN_SET_METRIC_PR_FILE = "mpc_train_metric_pr.svg" +MPC_TRAIN_SET_METRIC_ACCURACY_FILE = "mpc_train_metric_accuracy.svg" +MPC_TRAIN_SET_METRIC_KS_TABLE = "mpc_train_metric_ks.csv" +MPC_TRAIN_METRIC_CONFUSION_MATRIX_FILE = "mpc_metric_confusion_matrix.svg" +METRICS_OVER_ITERATION_FILE = "metrics_over_iterations.svg" + +# the ks-auc table, e.g.: +# |总样本|正样本| KS | AUC | +# 训练集| 500 | 100 | 0.4161 | 0.7685 | +# 验证集| 154 | 37 | 0.2897 | 0.6376 | +MPC_XGB_EVALUATION_TABLE = "mpc_xgb_evaluation_table.csv" + +# the feature-importance table, e.g.: +# |特征 | score | weight | score_rank| topk | +# | x1 | 0.08 | 1000 | 1 | | +# | x2 | 0.07 | 900 | 2 | | +XGB_FEATURE_IMPORTANCE_TABLE = "xgb_result_feature_importance_table.csv" + +# png, jpeg, pdf etc. ref: https://graphviz.org/docs/outputs/ +WORKFLOW_VIEW_FORMAT = 'svg' + +WORKFLOW_VIEW_NAME = 'workflow_view' + +PROXY_PSI_CIPHER_SUITE = "HMAC_BASED_PRIVATE_SET_INTERSECTION" +PROXY_MPC_CIPHER_SUITE = "SHA256_WITH_REPLICATED_SECRET_SHARING" +PROXY_PSI_MPC_CIPHER_SUITE = PROXY_PSI_CIPHER_SUITE + "-" + PROXY_MPC_CIPHER_SUITE +PPC_ALL_AUTH_FLAG = "PPC_ALGO_ALL" + +CEM_CIPHER_LEN = 288 + + +@unique +class PPCModleType(Enum): + Train = 1 + Predict = 2 + + +@unique +class CryptoType(Enum): + ECDSA = 1 + GM = 2 + + +@unique +class HashType(Enum): + BYTES = 1 + HEXSTR = 2 + + +class AlgorithmType(Enum): + Train = "Train", + Predict = "Predict" + + +def json_loads(json_config): + try: + json_comment = JsonComment(json) + return json_comment.loads(json_config) + except BaseException: + raise PpcException(PpcErrorCode.ALGORITHM_PPC_CONFIG_ERROR.get_code(), + PpcErrorCode.ALGORITHM_PPC_CONFIG_ERROR.get_msg()) + + +def parse_n_class(layer_str): + if layer_str == '[]': + return 1 + else: + return int(re.findall(r"\d+\.?\d*", layer_str)[-1]) + + +def check_ppc_model_algorithm_is_homo(algorithm_name): + return algorithm_name[0:4].lower() == HOMO_MODEL_ALGORITHM + + +def get_log_file_path(app_dir): + return os.sep.join([app_dir, "logs", LOG_NAME]) + + +def get_log_temp_file_path(app_dir, job_id): + return os.sep.join([app_dir, "logs", f"{job_id}.log"]) + + +def df_to_dict(df, orient='split'): + data_json_str = df.to_json(orient=orient, force_ascii=False) + data_dict = json.loads(data_json_str) + del data_dict['index'] + return data_dict + + +def file_exists(_file): + if os.path.exists(_file) and os.path.isfile(_file): + return True + return False + + +def decode_jwt(token): + """ + decode jwt + :param token: + :return: + """ + result = {"data": None, "error": None} + try: + payload = jwt.decode(token.split(" ")[1], options={ + "verify_signature": False}) + result["data"] = payload + except (IndexError, jwt.DecodeError): + result["error"] = "JWT token is decoded fail" + return result + + +def make_timestamp(): + return int(round(time.time() * 1000)) + + +def encode(data_bytes): + return base64.b64encode(data_bytes) + + +def decode(data_str): + return base64.b64decode(data_str) + + +def pb_to_str(data_pb): + return encode(data_pb.SerializeToString()).decode("utf-8") + + +def str_to_pb(data_pb, data_str): + data_pb.ParseFromString(decode(data_str)) + return data_pb + + +def pb_to_bytes(data_pb): + return data_pb.SerializeToString() + + +def bytes_to_pb(data_pb, data_bytes): + return data_pb.ParseFromString(data_bytes) + + +def str_to_base64str(data_str): + message_bytes = data_str.encode('utf-8') + base64_bytes = base64.b64encode(message_bytes) + base64_message = base64_bytes.decode('utf-8') + return base64_message + + +def base64str_to_str(base64_str): + base64_bytes = base64_str.encode('utf-8') + message_bytes = base64.b64decode(base64_bytes) + message = message_bytes.decode('utf-8') + return message + + +def bytes_to_base64str(data_bytes): + base64_bytes = base64.b64encode(data_bytes) + base64_message = base64_bytes.decode('utf-8') + return base64_message + + +def make_response(code, message, data=None): + return {'errorCode': code, 'message': message, 'data': data} + + +def base64str_to_bytes(base64_str): + base64_bytes = base64_str.encode('utf-8') + message_bytes = base64.b64decode(base64_bytes) + return message_bytes + + +def make_hash_from_file_path(file_path, crypto_type): + file_data = read_content_from_file_by_binary(file_path) + return make_hash(file_data, crypto_type, HashType.HEXSTR) + + +def read_chunks(file, size=io.DEFAULT_BUFFER_SIZE): + while True: + chunk = bytes(file.read(size), 'utf-8') + if not chunk: + break + yield chunk + + +def make_hash_from_file_path_by_chunks(file_path, crypto_type, block_size=1 << 10): + m = SM3() + if crypto_type == CryptoType.ECDSA: + m = hashlib.sha3_256() + dataset_size = 0 + with open(file_path, 'r', encoding='utf-8') as f: + for block in read_chunks(f, size=block_size): + dataset_size += len(block) + m.update(block) + return m.hexdigest(), dataset_size + + +def read_content_from_file_by_binary(file_path): + with open(file_path, 'rb') as file: + content = file.read() + return content + + +def make_hash(data, crypto_type, hash_type=None): + if crypto_type == CryptoType.ECDSA: + m = hashlib.sha3_256() + m.update(data) + if hash_type == HashType.HEXSTR: + return m.hexdigest() + if hash_type == HashType.BYTES: + return m.digest() + if crypto_type == CryptoType.GM: + return sm3.sm3_hash(func.bytes_to_list(data)) + + +def pb2dict(obj): + """ + Takes a ProtoBuf Message obj and convertes it to a dict. + """ + adict = {} + if not obj.IsInitialized(): + return None + for field in obj.DESCRIPTOR.fields: + if not getattr(obj, field.name): + continue + if not field.label == FieldDescriptor.LABEL_REPEATED: + if not field.type == FieldDescriptor.TYPE_MESSAGE: + adict[field.name] = getattr(obj, field.name) + else: + value = pb2dict(getattr(obj, field.name)) + if value: + adict[field.name] = value + else: + if field.type == FieldDescriptor.TYPE_MESSAGE: + adict[field.name] = \ + [pb2dict(v) for v in getattr(obj, field.name)] + else: + adict[field.name] = [v for v in getattr(obj, field.name)] + return adict + + +def write_content_to_file(content, file_path): + with open(file_path, 'w', encoding="utf-8") as file: + file.write(content) + + +def write_content_to_file_by_append(content, file_path): + with open(file_path, 'a', encoding="utf-8") as file: + file.write(content) + + +def read_content_from_file(file_path): + with open(file_path, 'r', encoding='utf-8') as file: + content = file.read() + return content + + +def make_job_event_message(job_id, job_priority, initiator_agency_id, receiver_agency_id, job_algorithm_id, + job_dataset): + message = '{}|{}|{}|{}|{}'.format(job_id, job_priority, initiator_agency_id, receiver_agency_id, job_algorithm_id, + job_dataset) + return message.encode('utf-8') + + +def exec_bash_command(cmd): + """replace commands.get_status_output + + Arguments: + cmd {[string]} + """ + + get_cmd = subprocess.Popen( + cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + ret = get_cmd.communicate() + out = ret[0] + err = ret[1] + output = '' + if out is not None: + output = output + out.decode('utf-8') + if err is not None: + output = output + err.decode('utf-8') + + return get_cmd.returncode, output + + +def delete_file(path): + """[delete data_dir] + + Arguments: + path {[get_dir]} -- [description] + """ + + if os.path.isfile(path): + os.remove(path) + elif os.path.isdir(path): + shutil.rmtree(path) + else: + raise (Exception(' path not exisited ! path => %s', path)) + + +def make_dir(_dir): + if not os.path.exists(_dir): + os.mkdir(_dir) + + +def load_credential_from_file(filepath): + real_path = os.path.join(os.path.dirname(__file__), filepath) + with open(real_path, 'rb') as f: + return f.read() + + +def merge_files(file_list, output_file): + try: + with open(output_file, 'wb') as outfile: + for file_name in file_list: + with open(file_name, 'rb') as f: + outfile.write(f.read()) + except Exception as pe: + log.info(f"merge files failed: {pe}") + raise PpcException(-1, f"merge files failed for: {pe}") + + +def md5sum(data_content): + md5_hash = hashlib.md5() + data = data_content if type( + data_content) is bytes else bytes(data_content, "utf-8") + md5_hash.update(data) + return md5_hash.hexdigest() + + +def calculate_md5(file_path, granularity=2 * 1024 * 1024): + md5_hash = hashlib.md5() + + with open(file_path, 'rb') as file: + # 逐块读取文件内容,以提高性能 + for chunk in iter(lambda: file.read(granularity), b''): + md5_hash.update(chunk) + + return md5_hash.hexdigest() diff --git a/python/ppc_model/__init__.py b/python/ppc_model/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/python/ppc_model/common/__init__.py b/python/ppc_model/common/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/python/ppc_model/common/base_context.py b/python/ppc_model/common/base_context.py new file mode 100644 index 00000000..ec905b06 --- /dev/null +++ b/python/ppc_model/common/base_context.py @@ -0,0 +1,178 @@ +import os +from ppc_common.ppc_utils import utils + + +class BaseContext: + PSI_RESULT_FILE = "psi_result.csv" + MODEL_PREPARE_FILE = "model_prepare.csv" + PREPROCESSING_RESULT_FILE = "preprocessing_result.csv" + EVAL_COLUMN_FILE = "model_eval_column.csv" + WOE_IV_FILE = 'woe_iv.csv' + IV_SELECTED_FILE = 'iv_selected.csv' + SELECTED_COL_FILE = "xgb_result_column_info_selected.csv" + + # TODO: rename xgb filename + FEATURE_BIN_FILE = "feature_bin.json" + # MODEL_DATA_FILE = "model_data.json" + MODEL_DATA_FILE = utils.XGB_TREE_PERFIX + '.json' + TEST_MODEL_RESULT_FILE = "model_result.csv" + # TEST_MODEL_OUTPUT_FILE = "model_output.csv" + TEST_MODEL_OUTPUT_FILE = "test_model_output.csv" + TRAIN_MODEL_RESULT_FILE = "train_model_result.csv" + # TRAIN_MODEL_OUTPUT_FILE = "train_model_output.csv" + TRAIN_MODEL_OUTPUT_FILE = "train_model_output.csv" + + MODEL_FILE = "model.kpl" + MODEL_ENC_FILE = "model_enc.kpl" + + def __init__(self, job_id: str, job_temp_dir: str, user: str): + self.job_id = job_id + self.user = user + self.workspace = os.path.join(job_temp_dir, self.job_id) + if not os.path.exists(self.workspace): + os.makedirs(self.workspace) + self.psi_result_path = os.path.join( + self.workspace, self.PSI_RESULT_FILE) + self.model_prepare_file = os.path.join( + self.workspace, self.MODEL_PREPARE_FILE) + self.preprocessing_result_file = os.path.join( + self.workspace, self.PREPROCESSING_RESULT_FILE) + self.eval_column_file = os.path.join( + self.workspace, self.EVAL_COLUMN_FILE) + self.woe_iv_file = os.path.join(self.workspace, self.WOE_IV_FILE) + self.iv_selected_file = os.path.join( + self.workspace, self.IV_SELECTED_FILE) + self.selected_col_file = os.path.join( + self.workspace, self.SELECTED_COL_FILE) + + self.train_metric_roc_file = os.path.join( + self.workspace, utils.MPC_TRAIN_SET_METRIC_ROC_FILE) + self.train_metric_ks_file = os.path.join( + self.workspace, utils.MPC_TRAIN_SET_METRIC_KS_FILE) + self.train_metric_pr_file = os.path.join( + self.workspace, utils.MPC_TRAIN_SET_METRIC_PR_FILE) + self.train_metric_acc_file = os.path.join( + self.workspace, utils.MPC_TRAIN_SET_METRIC_ACCURACY_FILE) + self.test_metric_roc_file = os.path.join( + self.workspace, utils.MPC_TRAIN_METRIC_ROC_FILE) + self.test_metric_ks_file = os.path.join( + self.workspace, utils.MPC_TRAIN_METRIC_KS_FILE) + self.test_metric_pr_file = os.path.join( + self.workspace, utils.MPC_TRAIN_METRIC_PR_FILE) + self.test_metric_acc_file = os.path.join( + self.workspace, utils.MPC_TRAIN_METRIC_ACCURACY_FILE) + self.train_metric_ks_table = os.path.join( + self.workspace, utils.MPC_TRAIN_SET_METRIC_KS_TABLE) + self.test_metric_ks_table = os.path.join( + self.workspace, utils.MPC_TRAIN_METRIC_KS_TABLE) + self.model_tree_prefix = os.path.join( + self.workspace, utils.XGB_TREE_PERFIX) + self.metrics_iteration_file = os.path.join( + self.workspace, utils.METRICS_OVER_ITERATION_FILE) + + self.model_file = os.path.join( + self.workspace, self.MODEL_FILE) + self.model_enc_file = os.path.join( + self.workspace, self.MODEL_ENC_FILE) + self.summary_evaluation_file = os.path.join( + self.workspace, utils.MPC_XGB_EVALUATION_TABLE) + self.feature_importance_file = os.path.join( + self.workspace, utils.XGB_FEATURE_IMPORTANCE_TABLE) + self.feature_bin_file = os.path.join( + self.workspace, self.FEATURE_BIN_FILE) + self.model_data_file = os.path.join( + self.workspace, self.MODEL_DATA_FILE) + self.test_model_result_file = os.path.join( + self.workspace, self.TEST_MODEL_RESULT_FILE) + self.test_model_output_file = os.path.join( + self.workspace, self.TEST_MODEL_OUTPUT_FILE) + self.train_model_result_file = os.path.join( + self.workspace, self.TRAIN_MODEL_RESULT_FILE) + self.train_model_output_file = os.path.join( + self.workspace, self.TRAIN_MODEL_OUTPUT_FILE) + + # the remote path + self.remote_base_dir = os.path.join( + self.user, "share", "jobs", "model") + self.remote_selected_col_file = os.path.join(self.remote_base_dir, + self.job_id, self.SELECTED_COL_FILE) + self.remote_preprocessing_file = os.path.join(self.remote_base_dir, + self.job_id, self.PREPROCESSING_RESULT_FILE) + + self.remote_woe_iv_file = os.path.join(self.remote_base_dir, + self.job_id, self.WOE_IV_FILE) + self.remote_eval_column_file = os.path.join(self.remote_base_dir, + self.job_id, self.EVAL_COLUMN_FILE) + self.remote_model_prepare_file = os.path.join( + self.remote_base_dir, self.job_id, self.MODEL_PREPARE_FILE) + self.remote_summary_evaluation_file = os.path.join(self.remote_base_dir, + self.job_id, utils.MPC_XGB_EVALUATION_TABLE) + self.remote_feature_importance_file = os.path.join(self.remote_base_dir, + self.job_id, utils.XGB_FEATURE_IMPORTANCE_TABLE) + self.remote_feature_bin_file = os.path.join(self.remote_base_dir, + self.job_id, self.FEATURE_BIN_FILE) + self.remote_model_data_file = os.path.join(self.remote_base_dir, + self.job_id, self.MODEL_DATA_FILE) + self.remote_test_model_output_file = os.path.join(self.remote_base_dir, + self.job_id, self.TEST_MODEL_OUTPUT_FILE) + self.remote_train_model_output_file = os.path.join(self.remote_base_dir, + self.job_id, self.TRAIN_MODEL_OUTPUT_FILE) + + self.remote_train_metric_roc_file = os.path.join(self.remote_base_dir, + self.job_id, utils.MPC_TRAIN_SET_METRIC_ROC_FILE) + self.remote_train_metric_ks_file = os.path.join(self.remote_base_dir, + self.job_id, utils.MPC_TRAIN_SET_METRIC_KS_FILE) + self.remote_train_metric_pr_file = os.path.join(self.remote_base_dir, + self.job_id, utils.MPC_TRAIN_SET_METRIC_PR_FILE) + self.remote_train_metric_acc_file = os.path.join(self.remote_base_dir, + self.job_id, utils.MPC_TRAIN_SET_METRIC_ACCURACY_FILE) + self.remote_test_metric_roc_file = os.path.join(self.remote_base_dir, + self.job_id, utils.MPC_TRAIN_METRIC_ROC_FILE) + self.remote_test_metric_ks_file = os.path.join(self.remote_base_dir, + self.job_id, utils.MPC_TRAIN_METRIC_KS_FILE) + self.remote_test_metric_pr_file = os.path.join(self.remote_base_dir, + self.job_id, utils.MPC_TRAIN_METRIC_PR_FILE) + self.remote_test_metric_acc_file = os.path.join(self.remote_base_dir, + self.job_id, utils.MPC_TRAIN_METRIC_ACCURACY_FILE) + self.remote_train_metric_ks_table = os.path.join(self.remote_base_dir, + self.job_id, utils.MPC_TRAIN_SET_METRIC_KS_TABLE) + self.remote_test_metric_ks_table = os.path.join(self.remote_base_dir, + self.job_id, utils.MPC_TRAIN_METRIC_KS_TABLE) + self.remote_model_tree_prefix = os.path.join(self.remote_base_dir, + self.job_id, utils.XGB_TREE_PERFIX) + self.remote_metrics_iteration_file = os.path.join(self.remote_base_dir, + self.job_id, utils.METRICS_OVER_ITERATION_FILE) + + self.remote_model_file = os.path.join(self.remote_base_dir, + self.job_id, self.MODEL_FILE) + self.remote_model_enc_file = os.path.join(self.remote_base_dir, + self.job_id, self.MODEL_ENC_FILE) + + self.remote_log_path = os.path.join(self.remote_base_dir, + self.job_id, f"{job_id}.log") + self.remote_log_size_path = f"{self.remote_log_path}.size" + # self.get_key_pair() + self.load_key('aes_key.bin') + + def get_remote_file_path(self, file_path): + return os.path.join(self.remote_base_dir, + self.job_id, file_path) + + def get_local_file_path(self, file_path): + return os.path.join(self.workspace, file_path) + + @staticmethod + def load_file(storage_client, remote_path, local_path, logger): + if not os.path.exists(local_path): + logger.info(f"Download file from: {remote_path} to {local_path}") + storage_client.download_file(remote_path, local_path) + + def get_key_pair(self): + with open('public_key.pem', 'rb') as f: + self.public_pem = f.read() + with open('private_key.pem', 'rb') as f: + self.private_pem = f.read() + + def load_key(self, filename): + with open(filename, 'rb') as file: + self.key = file.read() diff --git a/python/ppc_model/common/context.py b/python/ppc_model/common/context.py new file mode 100644 index 00000000..b14fda4b --- /dev/null +++ b/python/ppc_model/common/context.py @@ -0,0 +1,14 @@ + +from ppc_model.common.base_context import BaseContext +from ppc_model.common.initializer import Initializer +from ppc_model.common.protocol import TaskRole + + +class Context(BaseContext): + + def __init__(self, job_id: str, task_id: str, user: str, components: Initializer, role: TaskRole = None): + super().__init__(job_id, components.config_data['JOB_TEMP_DIR'], user) + self.my_agency_id = components.config_data['AGENCY_ID'] + self.task_id = task_id + self.components = components + self.role = role diff --git a/python/ppc_model/common/global_context.py b/python/ppc_model/common/global_context.py new file mode 100644 index 00000000..186fe3f0 --- /dev/null +++ b/python/ppc_model/common/global_context.py @@ -0,0 +1,10 @@ +import os + +from ppc_model.common.initializer import Initializer + +dirName, _ = os.path.split(os.path.abspath(__file__)) +# config_path = '{}/../application.yml'.format(dirName) +config_path = "application.yml" + +components = Initializer( + log_config_path='logging.conf', config_path=config_path) diff --git a/python/ppc_model/common/initializer.py b/python/ppc_model/common/initializer.py new file mode 100644 index 00000000..310ca778 --- /dev/null +++ b/python/ppc_model/common/initializer.py @@ -0,0 +1,120 @@ +import logging +import logging.config +import os +import threading + +import yaml + +from ppc_common.deps_services import storage_loader +from ppc_common.ppc_utils import common_func +from ppc_common.ppc_async_executor.thread_event_manager import ThreadEventManager +from wedpr_python_gateway_sdk.transport.impl.transport_loader import TransportLoader +from ppc_model.network.wedpr_model_transport import ModelRouter +from ppc_common.deps_services.mysql_storage import MySQLStorage +from ppc_common.ppc_config.sql_storage_config_loader import SQLStorageConfigLoader +from ppc_model.network.wedpr_model_transport import ModelTransport +from ppc_model.task.task_manager import TaskManager +from ppc_model.task.task_manager import TaskPersistent +from ppc_model.log.log_retriever import LogRetriever + + +class Initializer: + MODEL_SERVICE_NAME = "MODEL" + + def __init__(self, log_config_path, config_path, plot_lock=None): + self.log_config_path = log_config_path + logging.config.fileConfig(self.log_config_path) + self.config_path = config_path + self.config_data = None + # 只用于测试 + self.mock_logger = None + self.public_key_length = 2048 + self.homo_algorithm = 0 + self.init_config() + self.job_cache_dir = common_func.get_config_value( + "JOB_TEMP_DIR", "/tmp", self.config_data, False) + self.thread_event_manager = ThreadEventManager() + + task_persistent = TaskPersistent(self.logger(), MySQLStorage( + storage_config=SQLStorageConfigLoader.load(self.config_data))) + + self.storage_client = storage_loader.load( + self.config_data, self.logger()) + log_path = common_func.get_config_value( + "LOG_PATH", "logs/wedpr-model.log", self.config_data, False) + self.log_retriever = LogRetriever( + self.logger(), self.job_cache_dir, self.storage_client, log_path) + self.task_manager = TaskManager( + logger=self.logger(), + task_persistent=task_persistent, + log_retriever=self.log_retriever, + thread_event_manager=self.thread_event_manager, + task_timeout_h=self.config_data['TASK_TIMEOUT_H'] + ) + # default send msg timeout + self.MODEL_COMPONENT = "WEDPR_MODEL" + self.send_msg_timeout_ms = 5000 + self.pop_msg_timeout_ms = 60000 + # for UT + self.transport = None + self.model_router = None + # matplotlib 线程不安全,并行任务绘图增加全局锁 + self.plot_lock = plot_lock + if plot_lock is None: + self.plot_lock = threading.Lock() + + def init_config(self): + with open(self.config_path, 'rb') as f: + self.config_data = yaml.safe_load(f.read()) + self.public_key_length = self.config_data['PUBLIC_KEY_LENGTH'] + storage_type = common_func.get_config_value( + "STORAGE_TYPE", "HDFS", self.config_data, False) + if 'HOMO_ALGORITHM' in self.config_data: + self.homo_algorithm = self.config_data['HOMO_ALGORITHM'] + + def init_all(self): + agency_id = common_func.get_config_value( + "AGENCY_ID", None, self.config_data, True) + self.init_transport(task_manager=self.task_manager, + self_agency_id=agency_id, + component_type=self.MODEL_COMPONENT, + send_msg_timeout_ms=self.send_msg_timeout_ms, + pop_msg_timeout_ms=self.pop_msg_timeout_ms) + + def init_transport(self, task_manager: TaskManager, + self_agency_id: str, + component_type: str, + send_msg_timeout_ms: int, + pop_msg_timeout_ms: int): + # create the transport + transport_config = TransportLoader.build_config(**self.config_data) + listen_port = self.config_data["HTTP_PORT"] + access_entrypoint = f"{transport_config.get_self_endpoint().host()}:{listen_port}" + if not access_entrypoint.startswith("http://"): + access_entrypoint = f"http://{access_entrypoint}" + # register the access_entrypoint information + transport_config.register_service_info( + Initializer.MODEL_SERVICE_NAME, access_entrypoint) + transport = TransportLoader.load(transport_config) + self.logger( + f"Create transport success, config: {transport.get_config().desc()}, access_entrypoint: {access_entrypoint}") + # the configuration used to distinguish different wedpr-privacy-zone + transport.register_component(self.config_data['WEDPR_ZONE']) + # start the transport + transport.start() + self.logger().info( + f"Start transport success, config: {transport.get_config().desc()}") + self.transport = ModelTransport(transport=transport, + self_agency_id=self_agency_id, + task_manager=task_manager, + component_type=component_type, + send_msg_timeout_ms=send_msg_timeout_ms, + pop_msg_timeout_ms=pop_msg_timeout_ms) + self.model_router = ModelRouter(logger=self.logger(), + transport=self.transport) + + def logger(self, name=None): + if self.mock_logger is None: + return logging.getLogger(name) + else: + return self.mock_logger diff --git a/python/ppc_model/common/mock/__init__.py b/python/ppc_model/common/mock/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/python/ppc_model/common/mock/mock_model_transport.py b/python/ppc_model/common/mock/mock_model_transport.py new file mode 100644 index 00000000..e4f97521 --- /dev/null +++ b/python/ppc_model/common/mock/mock_model_transport.py @@ -0,0 +1,45 @@ +# -*- coding: utf-8 -*- +from ppc_model.network.wedpr_model_transport_api import ModelTransportApi +from ppc_model.network.wedpr_model_transport_api import ModelRouterApi + + +class MockModelTransportApi(ModelTransportApi): + def __init__(self, agency_name): + self.agency_name = agency_name + self.msg_queue = {} + + @staticmethod + def get_topic(task_id: str, task_type: str, dst_agency: str): + return f"{dst_agency}_{task_id}{task_type}" + + def push_by_nodeid(self, task_id: str, task_type: str, dst_node: str, payload: bytes, seq: int = 0): + self.msg_queue.update({MockModelTransportApi.get_topic( + task_id, task_type, self.agency_name): payload}) + + def pop(self, task_id: str, task_type: str, dst_inst: str): + topic = MockModelTransportApi.get_topic(task_id, task_type, dst_inst) + if topic in self.msg_queue.keys(): + payload = self.msg_queue.get(topic) + self.msg_queue.pop(topic) + return payload + raise Exception(f"Not receive the message of topic:" + f" {self.get_topic(task_id, task_type, dst_inst)} " + f"even after the task has been killed!") + + +class MockModelRouterApi(ModelRouterApi): + def __init__(self, participant_id_list): + self.participant_id_list = participant_id_list + self.transports = {} + for participant in self.participant_id_list: + self.transports.update( + {participant, MockModelTransportApi(participant)}) + + def push(self, task_id: str, task_type: str, dst_agency: str, payload: bytes, seq: int = 0): + transport = self.transports.get(dst_agency) + dst_nodeid = f"{dst_agency}_node" + transport.push_by_nodeid(task_id, task_type, dst_nodeid, payload, seq) + + def pop(self, task_id: str, task_type: str, from_inst: str) -> bytes: + transport = self.transports.get(from_inst) + return transport.pop(task_id, task_type, from_inst) diff --git a/python/ppc_model/common/model_result.py b/python/ppc_model/common/model_result.py new file mode 100644 index 00000000..bc68c308 --- /dev/null +++ b/python/ppc_model/common/model_result.py @@ -0,0 +1,191 @@ +import os +import shutil +import pandas as pd +import time +from enum import Enum +import base64 +from ppc_common.ppc_utils import utils +from ppc_common.ppc_utils.utils import AlgorithmType +from ppc_model.common.context import Context +from ppc_model.common.protocol import TaskRole +from ppc_model.network.wedpr_model_transport import ModelRouter +from ppc_model.common.base_context import BaseContext + + +class ResultFileHandling: + + def __init__(self, ctx: Context) -> None: + self.ctx = ctx + self.log = ctx.components.logger() + + if ctx.algorithm_type == AlgorithmType.Train.name: + self._process_fe_result() + + # 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( + self.ctx.preprocessing_result_file, index_col=0) + if os.path.exists(self.ctx.iv_selected_file): + column_info_iv_fm = pd.read_csv( + self.ctx.iv_selected_file, index_col=0) + merged_df = self.union_column_info( + column_info_fm, column_info_iv_fm) + else: + merged_df = column_info_fm + + merged_df.fillna("None", inplace=True) + merged_df.to_csv(self.ctx.selected_col_file, + sep=utils.CSV_SEP, header=True, index_label='id') + # 存储column_info到hdfs给前端展示 + self._upload_file(self.ctx.components.storage_client, + self.ctx.selected_col_file, + self.ctx.remote_selected_col_file, + self.ctx.user) + + @staticmethod + def union_column_info(column_info1: pd.DataFrame, column_info2: pd.DataFrame): + """ + union the column_info1 with the column_info2. + + Args: + column_info1 (DataFrame): The column_info1 to be merged. + column_info2 (DataFrame): The column_info2 to be merged. + + Returns: + column_info_merge (DataFrame): The union column_info. + """ + # 将column_info1和column_info2按照left_index=True, right_index=True的方式进行合并 如果列有缺失则赋值为None 行的顺序按照column_info1 + column_info_conbine = column_info1.merge( + column_info2, how='outer', left_index=True, right_index=True, sort=False) + col1_index_list = column_info1.index.to_list() + col2_index_list = column_info2.index.to_list() + merged_list = col1_index_list + \ + [item for item in col2_index_list if item not in col1_index_list] + column_info_conbine = column_info_conbine.reindex(merged_list) + return column_info_conbine + + @staticmethod + def _upload_file(storage_client, local_file, + remote_file, owner=None, + group=None): + if storage_client is not None: + storage_client.upload_file(local_file, remote_file, owner, group) + + @staticmethod + def _download_file(storage_client, local_file, remote_file): + if storage_client is not None and not os.path.exists(local_file): + storage_client.download_file(remote_file, local_file) + + @staticmethod + def make_graph_data(components, ctx: BaseContext, graph_file_name): + graph_format = 'svg+xml' + # download with cache + remote_file_path = ctx.get_remote_file_path(graph_file_name) + + local_file_path = ctx.get_local_file_path(graph_file_name) + components.storage_client.download_file( + remote_file_path, local_file_path, True) + file_bytes = None + with open(local_file_path, 'r') as file: + file_content = file.read() + file_bytes = file_content.encode('utf-8') + encoded_data = "" + if file_bytes is not None: + encoded_data = base64.b64encode(file_bytes).decode('ascii') + time.sleep(0.1) + return f"data:image/{graph_format};base64,{encoded_data}" + + def get_remote_path(components, ctx: BaseContext, csv_file_name): + remote_file_path = ctx.get_remote_file_path(csv_file_name) + if components.storage_client.get_home_path() is None: + return remote_file_path + return os.path.join(components.storage_client.get_home_path(), remote_file_path) + + @staticmethod + def make_csv_data(components, ctx: BaseContext, csv_file_name): + import pandas as pd + from io import StringIO + remote_file_path = ctx.get_remote_file_path(csv_file_name) + local_file_path = ctx.get_local_file_path(csv_file_name) + components.storage_client.download_file( + remote_file_path, local_file_path, True) + file_bytes = None + with open(local_file_path, 'r') as file: + file_content = file.read() + file_bytes = file_content.encode('utf-8') + csv_data = "" + if file_bytes is not None: + csv_data = pd.read_csv(StringIO(file_bytes.decode())).astype('str') + return csv_data + + def _remove_workspace(self): + if os.path.exists(self.ctx.workspace): + shutil.rmtree(self.ctx.workspace) + self.log.info( + f'job {self.ctx.job_id}: {self.ctx.workspace} has been removed.') + else: + self.log.info( + f'job {self.ctx.job_id}: {self.ctx.workspace} does not exist.') + + def _sync_result_files(self): + for key, value in self.ctx.sync_file_list.items(): + self.sync_result_file( + self.ctx, self.ctx.model_router, value[0], value[1], key, self.ctx.user) + + @staticmethod + def sync_result_file(ctx, model_router: ModelRouter, local_file, remote_file, key_file, user): + if ctx.role == TaskRole.ACTIVE_PARTY: + with open(local_file, 'rb') as f: + byte_data = f.read() + for partner_index in range(1, len(ctx.participant_id_list)): + if ctx.participant_id_list[partner_index] in ctx.result_receiver_id_list: + SendMessage._send_byte_data(model_router, ctx, f'{CommonMessage.SYNC_FILE.value}_{key_file}', + byte_data, partner_index) + else: + if ctx.components.config_data['AGENCY_ID'] in ctx.result_receiver_id_list: + byte_data = SendMessage._receive_byte_data(model_router, ctx, + f'{CommonMessage.SYNC_FILE.value}_{key_file}', 0) + with open(local_file, 'wb') as f: + f.write(byte_data) + ResultFileHandling._upload_file( + ctx.components.storage_client, + local_file, remote_file, user) + + +class CommonMessage(Enum): + SYNC_FILE = "SYNC_FILE" + EVAL_SET_FILE = "EVAL_SET_FILE" + + +class SendMessage: + + @staticmethod + def _send_byte_data(model_router: ModelRouter, ctx, key_type, byte_data, partner_index): + log = ctx.components.logger() + start_time = time.time() + partner_id = ctx.participant_id_list[partner_index] + model_router.push(task_id=ctx.task_id, task_type=key_type, + dst_agency=partner_id, payload=byte_data) + log.info( + f"task {ctx.task_id}: Sending {key_type} to {partner_id} finished, " + f"data_size: {len(byte_data) / 1024}KB, time_costs: {time.time() - start_time}s") + + @staticmethod + def _receive_byte_data(model_router: ModelRouter, ctx, key_type, partner_index): + log = ctx.components.logger() + start_time = time.time() + partner_id = ctx.participant_id_list[partner_index] + byte_data = model_router.pop( + task_id=ctx.task_id, task_type=key_type, from_inst=partner_id) + log.info( + f"task {ctx.task_id}: Received {key_type} from {partner_id} finished, " + f"data_size: {len(byte_data) / 1024}KB, time_costs: {time.time() - start_time}s") + return byte_data diff --git a/python/ppc_model/common/model_setting.py b/python/ppc_model/common/model_setting.py new file mode 100644 index 00000000..d325b73a --- /dev/null +++ b/python/ppc_model/common/model_setting.py @@ -0,0 +1,130 @@ +# -*- coding: utf-8 -*- +from ppc_common.ppc_utils import common_func + + +class PreprocessingSetting: + def __init__(self, model_dict): + self.use_psi = common_func.get_config_value( + "use_psi", False, model_dict, False) + self.fillna = common_func.get_config_value( + "fillna", False, model_dict, False) + self.na_select = float(common_func.get_config_value( + "na_select", 1.0, model_dict, False)) + self.filloutlier = common_func.get_config_value( + "filloutlier", False, model_dict, False) + self.normalized = common_func.get_config_value( + "normalized", False, model_dict, False) + self.standardized = common_func.get_config_value( + "standardized", False, model_dict, False) + self.categorical = common_func.get_config_value( + "categorical", '', model_dict, False) + self.psi_select_col = common_func.get_config_value( + "psi_select_col", '', model_dict, False) + self.psi_select_base = common_func.get_config_value( + "psi_select_base", '', model_dict, False) + self.psi_select_base = float(common_func.get_config_value( + "psi_select_thresh", 0.3, model_dict, False)) + self.psi_select_bins = int(common_func.get_config_value( + "psi_select_bins", 4, model_dict, False)) + self.corr_select = float(common_func.get_config_value( + "corr_select", 0, model_dict, False)) + self.use_goss = common_func.get_config_value( + "use_goss", False, model_dict, False) + + +class FeatureEngineeringEngineSetting: + def __init__(self, model_dict): + self.use_iv = common_func.get_config_value( + "use_iv", False, model_dict, False) + self.group_num = int(common_func.get_config_value( + "group_num", 4, model_dict, False)) + self.iv_thresh = float(common_func.get_config_value( + "iv_thresh", 0.1, model_dict, False)) + + +class CommonModelSetting: + def __init__(self, model_dict): + self.learning_rate = float(common_func.get_config_value( + "learning_rate", 0.1, model_dict, False)) + + self.eval_set_column = common_func.get_config_value( + "eval_set_column", "", model_dict, False) + self.train_set_value = common_func.get_config_value( + "train_set_value", "", model_dict, False) + self.eval_set_value = common_func.get_config_value( + "eval_set_value", "", model_dict, False) + self.verbose_eval = int(common_func.get_config_value( + "verbose_eval", 1, model_dict, False)) + self.silent = common_func.get_config_value( + "silent", False, model_dict, False) + self.train_features = common_func.get_config_value( + "train_features", "", model_dict, False) + random_state_str = common_func.get_config_value( + "random_state", "", model_dict, False) + if len(random_state_str) > 0: + self.random_state = int(random_state_str) + self.n_jobs = int(common_func.get_config_value( + "n_jobs", 0, model_dict, False)) + + +class SecureLGBMSetting(CommonModelSetting): + def __init__(self, model_dict): + super().__init__(model_dict) + self.test_size = float(common_func.get_config_value( + "test_dataset_percentage", 0.3, model_dict, False)) + self.num_trees = int(common_func.get_config_value( + "num_trees", 6, model_dict, False)) + self.max_depth = int(common_func.get_config_value( + "max_depth", 3, model_dict, False)) + self.max_bin = int(common_func.get_config_value( + "max_bin", 4, model_dict, False)) + + self.subsample = float(common_func.get_config_value( + "subsample", 1, model_dict, False)) + self.colsample_bytree = float(common_func.get_config_value( + "colsample_bytree", 1, model_dict, False)) + self.colsample_bylevel = float(common_func.get_config_value( + "colsample_bylevel", 1, model_dict, False)) + self.reg_alpha = float(common_func.get_config_value( + "reg_alpha", 0, model_dict, False)) + self.reg_lambda = float(common_func.get_config_value( + "reg_lambda", 1, model_dict, False)) + self.gamma = float(common_func.get_config_value( + "gamma", 0, model_dict, False)) + self.min_child_weight = float(common_func.get_config_value( + "min_child_weight", 0.0, model_dict, False)) + self.min_child_samples = int(common_func.get_config_value( + "min_child_samples", 10, model_dict, False)) + self.seed = int(common_func.get_config_value( + "seed", 2024, model_dict, False)) + self.early_stopping_rounds = int(common_func.get_config_value( + "early_stopping_rounds", 5, model_dict, False)) + self.eval_metric = common_func.get_config_value( + "eval_metric", "auc", model_dict, False) + self.threads = int(common_func.get_config_value( + "threads", 8, model_dict, False)) + self.one_hot = common_func.get_config_value( + "one_hot", 0, model_dict, False) + + +class SecureLRSetting(CommonModelSetting): + def __init__(self, model_dict): + super().__init__(model_dict) + self.feature_rate = float(common_func.get_config_value( + "feature_rate", 1.0, model_dict, False)) + self.batch_size = int(common_func.get_config_value( + "batch_size", 16, model_dict, False)) + self.epochs = int(common_func.get_config_value( + "epochs", 3, model_dict, False)) + + +class ModelSetting(PreprocessingSetting, FeatureEngineeringEngineSetting, SecureLGBMSetting, SecureLRSetting): + def __init__(self, model_dict): + # init PreprocessingSetting + super().__init__(model_dict) + # init FeatureEngineeringEngineSetting + FeatureEngineeringEngineSetting.__init__(self, model_dict) + # init SecureLGBMSetting + SecureLGBMSetting.__init__(self, model_dict) + # init SecureLRSetting + SecureLRSetting.__init__(self, model_dict) diff --git a/python/ppc_model/common/protocol.py b/python/ppc_model/common/protocol.py new file mode 100644 index 00000000..cd6a2b9e --- /dev/null +++ b/python/ppc_model/common/protocol.py @@ -0,0 +1,94 @@ +from enum import Enum + +from ppc_common.ppc_protos.generated.ppc_model_pb2 import Cipher1DimList, Cipher2DimList +from ppc_common.ppc_protos.generated.ppc_model_pb2 import CipherList, ModelCipher +from ppc_common.ppc_utils import utils + + +class TaskRole(Enum): + ACTIVE_PARTY = "ACTIVE_PARTY" + PASSIVE_PARTY = "PASSIVE_PARTY" + + +class ModelTask(Enum): + PREPROCESSING = "PREPROCESSING" + FEATURE_ENGINEERING = "FEATURE_ENGINEERING" + XGB_TRAINING = "XGB_TRAINING" + XGB_PREDICTING = "XGB_PREDICTING" + LR_TRAINING = "LR_TRAINING" + LR_PREDICTING = "LR_PREDICTING" + + +class TaskStatus(Enum): + NotFound = "NotFound" + PENDING = "PENDING" + RUNNING = "RUNNING" + FAILURE = "FAILURE" + KILLED = "KILLED" + SUCCESS = "SUCCESS" + + +class RpcType(Enum): + HTTP = "HTTP" + GRPC = "GRPC" + + +class PheMessage: + + @staticmethod + def packing_data(codec, public_key, cipher_list): + enc_data_pb = CipherList() + enc_data_pb.public_key = codec.encode_enc_key(public_key) + + for cipher in cipher_list: + model_cipher = ModelCipher() + model_cipher.ciphertext, model_cipher.exponent = codec.encode_cipher( + cipher) + enc_data_pb.cipher_list.append(model_cipher) + + return utils.pb_to_bytes(enc_data_pb) + + @staticmethod + def unpacking_data(codec, data): + enc_data_pb = CipherList() + utils.bytes_to_pb(enc_data_pb, data) + public_key = codec.decode_enc_key(enc_data_pb.public_key) + enc_data = [codec.decode_cipher(public_key, + cipher.ciphertext, + cipher.exponent + ) for cipher in enc_data_pb.cipher_list] + return public_key, enc_data + + @staticmethod + def packing_2dim_data(codec, public_key, cipher_2d_list): + enc_data_pb = Cipher2DimList() + enc_data_pb.public_key = codec.encode_enc_key(public_key) + + for cipher_list in cipher_2d_list: + enc_1d_pb = Cipher1DimList() + for cipher in cipher_list: + model_cipher = ModelCipher() + model_cipher.ciphertext, model_cipher.exponent = \ + codec.encode_cipher(cipher, be_secure=False) + enc_1d_pb.cipher_list.append(model_cipher) + enc_data_pb.cipher_1d_list.append(enc_1d_pb) + + return utils.pb_to_bytes(enc_data_pb) + + @staticmethod + def unpacking_2dim_data(codec, data): + enc_data_pb = Cipher2DimList() + utils.bytes_to_pb(enc_data_pb, data) + public_key = codec.decode_enc_key(enc_data_pb.public_key) + enc_data = [] + for enc_1d_pb in enc_data_pb.cipher_1d_list: + enc_1d_data = [codec.decode_cipher(public_key, + cipher.ciphertext, + cipher.exponent + ) for cipher in enc_1d_pb.cipher_list] + enc_data.append(enc_1d_data) + return public_key, enc_data + + +LOG_START_FLAG_FORMATTER = "$$$StartModelJob:{job_id}" +LOG_END_FLAG_FORMATTER = "$$$EndModelJob:{job_id}" diff --git a/python/ppc_model/conf/application-sample.yml b/python/ppc_model/conf/application-sample.yml new file mode 100644 index 00000000..3c69234c --- /dev/null +++ b/python/ppc_model/conf/application-sample.yml @@ -0,0 +1,39 @@ +HOST: "0.0.0.0" +HTTP_PORT: 43471 + +WEDPR_ZONE: 'wedpr1' +AGENCY_ID: 'WeBank' + +PUBLIC_KEY_LENGTH: 2048 + +MAX_MESSAGE_LENGTH_MB: 100 +TASK_TIMEOUT_H: 1800 + +DB_TYPE: "mysql" +SQLALCHEMY_DATABASE_URI: "mysql://[*user_ppcsmodeladm]:[*pass_ppcsmodeladm]@[@4346-TDSQL_VIP]:[@4346-TDSQL_PORT]/ppcsmodeladm?autocommit=true&charset=utf8mb4" + +# interagency services +HDFS_URL: "http://127.0.0.1:50070" +# HDFS, +STORAGE_TYPE: "HDFS" +HDFS_USER: "root" +HDFS_HOME: "/user/ppc/model/webank" +HDFS_ENABLE_AUTH: False +# the hdfs auth principal +HDFS_AUTH_PRINCIPAL: "root@NODE.DC1.CONSUL" +# the auth password +HDFS_AUTH_PASSWORD: "" +# the host name override +HDFS_HOSTNAME_OVERRIDE: "wedpr-0001" + +JOB_TEMP_DIR: ".cache/job" + +# the transport config +transport_threadpool_size: 4 +transport_node_id: "MODEL_WeBank_NODE" +transport_gateway_targets: "ipv4:127.0.0.1:40600,127.0.0.1:40601" +transport_host_ip: "127.0.0.1" +transport_listen_port: 6500 + +# the log retriever config +LOG_PATH: "logs/wedpr-model.log" \ No newline at end of file diff --git a/python/ppc_model/conf/logging.conf b/python/ppc_model/conf/logging.conf new file mode 100644 index 00000000..e600039c --- /dev/null +++ b/python/ppc_model/conf/logging.conf @@ -0,0 +1,40 @@ +[loggers] +keys=root,wsgi + +[logger_root] +level=INFO +handlers=fileHandler + +[logger_wsgi] +level = INFO +handlers = accessHandler +qualname = wsgi +propagate = 0 + +[handlers] +keys=fileHandler,accessHandler + +[handler_accessHandler] +class=handlers.TimedRotatingFileHandler +args=('logs/appmonitor.log', 'D', 1, 30, 'utf-8') +level=INFO +formatter=simpleFormatter + +[handler_fileHandler] +class=handlers.TimedRotatingFileHandler +args=('logs/wedpr-model.log', 'D', 1, 30, 'utf-8') +level=INFO +formatter=simpleFormatter + +[handler_consoleHandler] +class=StreamHandler +args=(sys.stdout,) +level=INFO +formatter=simpleFormatter + +[formatters] +keys=simpleFormatter + +[formatter_simpleFormatter] +format=[%(levelname)s][%(asctime)s %(msecs)03d][%(process)d][%(filename)s:%(lineno)d] %(message)s +datefmt=%Y-%m-%d %H:%M:%S diff --git a/python/ppc_model/conf/wedpr_sdk_log_config.ini b/python/ppc_model/conf/wedpr_sdk_log_config.ini new file mode 100644 index 00000000..448b4833 --- /dev/null +++ b/python/ppc_model/conf/wedpr_sdk_log_config.ini @@ -0,0 +1,17 @@ +[log] +enable = true +log_path = ./log +; info debug trace +level = info +; MB +max_log_file_size = 200 +; LineID, TimeStamp, ProcessID, ThreadName, ThreadID and Message +;format = %Severity%|ppcs-gateway|system-id|%TimeStamp%|%ThreadName%-%ThreadID%|%Message% +format = %Severity%|%TimeStamp%|%Message% +enable_rotate_by_hour = true +; if archive_path is empty, the archive function will be disabled +; archive_path = ./log/ +;compress_archive_file = true +; ; 0 = no limit, in MB +; max_archive_size = 0 +; min_free_space = 0 diff --git a/python/ppc_model/datasets/__init__.py b/python/ppc_model/datasets/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/python/ppc_model/datasets/data_reduction/__init__.py b/python/ppc_model/datasets/data_reduction/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/python/ppc_model/datasets/data_reduction/feature_selection.py b/python/ppc_model/datasets/data_reduction/feature_selection.py new file mode 100644 index 00000000..cfeec89b --- /dev/null +++ b/python/ppc_model/datasets/data_reduction/feature_selection.py @@ -0,0 +1,30 @@ +import numpy as np + + +class FeatureSelection: + + @staticmethod + def feature_selecting(feature_name: list, train_feats: list, fr: float): + if train_feats is not None and len(train_feats) > 0: + feature_select = FeatureSelection._get_train_feature( + feature_name, train_feats) + elif fr > 0 and fr < 1: + feature_select = FeatureSelection._get_feature_rate( + feature_name, fr) + else: + feature_select = list(range(len(feature_name))) + return feature_select + + @staticmethod + def _get_train_feature(feature_name: list, train_feats: list): + feature_select = [] + for i, feature in enumerate(feature_name): + if feature in train_feats: + feature_select.append(i) + return feature_select + + @staticmethod + def _get_feature_rate(feature_name: list, fr: float): + feature_select = sorted(np.random.choice( + range(len(feature_name)), size=int(len(feature_name) * fr), replace=False)) + return feature_select diff --git a/python/ppc_model/datasets/data_reduction/sampling.py b/python/ppc_model/datasets/data_reduction/sampling.py new file mode 100644 index 00000000..0866e3dd --- /dev/null +++ b/python/ppc_model/datasets/data_reduction/sampling.py @@ -0,0 +1,86 @@ +import numpy as np + + +class Sampling: + + @staticmethod + def sample_selecting( + g_list: np.ndarray, + h_list: np.ndarray, + subsample: float = 0, + use_goss: bool = False, + top_rate: float = 0.2, + other_rate: float = 0.1 + ): + if use_goss: + instance, used_glist, used_hlist = Sampling._get_goss_sampling( + g_list, h_list, top_rate, other_rate) + elif subsample > 0 and subsample < 1: + instance, used_glist, used_hlist = Sampling._get_subsample_sampling( + g_list, h_list, subsample) + else: + instance, used_glist, used_hlist = Sampling._get_sampling( + g_list, h_list) + + return instance, used_glist, used_hlist + + def _get_goss_sampling(g_list, h_list, top_rate, other_rate): + + n = len(g_list) + instance, used_glist, used_hlist = Sampling._goss_sampleing( + n, top_rate, other_rate, g_list, h_list) + + return instance, used_glist, used_hlist + + def _get_subsample_sampling(g_list, h_list, subsample): + + rand_size = int(len(g_list) * subsample) + rand_idx = np.array(sorted( + np.random.choice(list(range(len(g_list))), size=rand_size, replace=False))) + used_glist = np.array(g_list)[(rand_idx)] + used_hlist = np.array(h_list)[(rand_idx)] + + # used_idx = {} + # for i in range(rand_size): + # used_idx[rand_idx[i]] = i + # curr_instance = np.array(list(used_idx.keys())) + + return rand_idx, used_glist, used_hlist + + def _get_sampling(g_list, h_list): + + used_glist, used_hlist = g_list, h_list + instance = np.array(list(range(len(g_list)))) + + return instance, used_glist, used_hlist + + @staticmethod + def _goss_sampleing(n, a, b, g_list, h_list): + top_size = int(n * a) + rand_size = int(n * b) + abs_g = np.abs(g_list) + + top_idx = np.argsort(abs_g)[-top_size:] + rand_idx = np.random.choice(np.argsort( + abs_g)[:-top_size], size=rand_size, replace=False) + used_idx = np.append(top_idx, rand_idx) + + fact = (1 - a) / b + rand_glist = np.array(g_list)[(rand_idx)] * fact + used_glist = np.append(np.array(g_list)[(top_idx)], rand_glist) + rand_hlist = np.array(h_list)[(rand_idx)] * fact + used_hlist = np.append(np.array(h_list)[(top_idx)], rand_hlist) + + return Sampling._sort_instance(used_idx, used_glist, used_hlist) + + @staticmethod + def _sort_instance(instance, g_list, h_list): + # 获取排序索引 + sorted_indices = np.argsort(instance) + + # 对所有数组进行排序 + sorted_idx = instance[sorted_indices] + sorted_glist = g_list[sorted_indices] + sorted_hlist = h_list[sorted_indices] + + return sorted_idx, sorted_glist, sorted_hlist diff --git a/python/ppc_model/datasets/data_reduction/test/__init__.py b/python/ppc_model/datasets/data_reduction/test/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/python/ppc_model/datasets/data_reduction/test/test_data_reduction.py b/python/ppc_model/datasets/data_reduction/test/test_data_reduction.py new file mode 100644 index 00000000..689be74f --- /dev/null +++ b/python/ppc_model/datasets/data_reduction/test/test_data_reduction.py @@ -0,0 +1,61 @@ +import unittest +import numpy as np + +from ppc_model.datasets.data_reduction.feature_selection import FeatureSelection +from ppc_model.datasets.data_reduction.sampling import Sampling + + +class TestFeatureSelection(unittest.TestCase): + + feature_name = [f'x{i+1}' for i in range(30)] + + def test_fr_feature_select(self): + + feature_select = FeatureSelection.feature_selecting( + self.feature_name, [], 0.8) + self.assertEqual(len(feature_select), len(self.feature_name) * 0.8) + + def test_customized_feature_select(self): + + train_feats = ['x1', 'x3', 'x15', 'x27', 'x33'] + feature_select = FeatureSelection.feature_selecting( + self.feature_name, train_feats, 0.8) + self.assertEqual(len(feature_select), len( + set(self.feature_name).intersection(set(train_feats)))) + self.assertEqual(sorted([f'x{i+1}' for i in feature_select]), + sorted(set(self.feature_name).intersection(set(train_feats)))) + + def test_feature_select(self): + + feature_select = FeatureSelection.feature_selecting( + self.feature_name, [], 0) + self.assertEqual(len(feature_select), len(self.feature_name)) + self.assertEqual(feature_select, list(range(len(self.feature_name)))) + + +class TestSampling(unittest.TestCase): + + g_list = [np.random.rand() for i in range(500)] + h_list = [np.random.rand() for i in range(500)] + + def test_goss_sampling(self): + instance, used_glist, used_hlist = Sampling.sample_selecting( + self.g_list, self.h_list, use_goss=True) + self.assertEqual(len(instance), int( + len(self.g_list) * 0.2) + int(len(self.g_list) * 0.1)) + assert max(self.g_list) in used_glist + assert np.argmax(self.g_list) in instance + + def test_subsample_sampling(self): + instance, used_glist, used_hlist = Sampling.sample_selecting( + self.g_list, self.h_list, subsample=0.6) + self.assertEqual(len(instance), int(len(self.g_list) * 0.6)) + + def test_sampling(self): + instance, used_glist, used_hlist = Sampling.sample_selecting( + self.g_list, self.h_list) + self.assertEqual(len(instance), len(self.g_list)) + + +if __name__ == "__main__": + unittest.main() diff --git a/python/ppc_model/datasets/dataset.py b/python/ppc_model/datasets/dataset.py new file mode 100644 index 00000000..4b486d95 --- /dev/null +++ b/python/ppc_model/datasets/dataset.py @@ -0,0 +1,247 @@ +import os +import numpy as np +import pandas as pd +from sklearn.model_selection import train_test_split + +from ppc_common.ppc_utils.exception import PpcException, PpcErrorCode +from ppc_common.ppc_utils.utils import AlgorithmType +from ppc_model.common.protocol import TaskRole +from ppc_model.common.model_result import ResultFileHandling, CommonMessage, SendMessage +from ppc_model.secure_lgbm.secure_lgbm_context import SecureLGBMContext +from ppc_model.common.base_context import BaseContext + + +class SecureDataset: + def __init__(self, ctx: SecureLGBMContext, model_data=None, delimiter: str = ' '): + + self.eval_column_file = ctx.eval_column_file + self.iv_selected_file = ctx.iv_selected_file + self.selected_col_file = ctx.selected_col_file + self.is_label_holder = ctx.is_label_holder + self.algorithm_type = ctx.algorithm_type + self.test_size = ctx.model_params.test_size + self.random_state = ctx.model_params.random_state + self.eval_set_column = ctx.model_params.eval_set_column + self.train_set_value = ctx.model_params.train_set_value + self.eval_set_value = ctx.model_params.eval_set_value + + self.ctx = ctx + self.train_X = None + self.test_X = None + self.train_y = None + self.test_y = None + self.train_idx = None + self.test_idx = None + self.feature_name = None + + if model_data is None: + # try to download the model_prepare_file + BaseContext.load_file(ctx.components.storage_client, + ctx.remote_model_prepare_file, + ctx.model_prepare_file, ctx.components.logger()) + self.model_data = pd.read_csv( + ctx.model_prepare_file, header=0, delimiter=delimiter) + else: + self.model_data = model_data + + self._construct_dataset() + + @staticmethod + def read_dataset(file_path, has_label: bool, delimiter: str = ' '): + df = pd.read_csv(file_path, header=0, delimiter=delimiter) + + if 'id' in df.columns: + df.drop('id', axis=1, inplace=True) + + field_list = df.columns.tolist() + + if has_label: + return field_list, df.iloc[:, 0].values, df.iloc[:, 1:].values + else: + return field_list, None, df.iloc[:, :].values + + @staticmethod + def simulate_dataset(data_size: int = 1000, feature_dim: int = 100, has_label: bool = True): + X = np.random.rand(data_size, feature_dim) + if has_label: + y = np.random.randint(2, size=data_size) + return SecureDataset.assembling_dataset(X, y) + return SecureDataset.assembling_dataset(X) + + @staticmethod + def assembling_dataset(X: np.ndarray, y: np.ndarray = None): + # 创建自定义列名 + num_features = X.shape[1] + column_names = [f'x{i+1}' for i in range(num_features)] + + # 创建数据框并使用自定义列名 + df = pd.DataFrame(X, columns=column_names) + + # 添加 id 列和 y 列 + df.insert(0, 'id', range(1, len(df) + 1)) + if y is not None: + df.insert(1, 'y', y) + + return df + + @staticmethod + def hetero_split_dataset(df: pd.DataFrame, split_point: int = None): + # 获取特征列名 + column_names = df.columns.tolist() + if 'id' in column_names: + column_names.remove('id') + if 'y' in column_names: + column_names.remove('y') + + # 计算切分点 + if not split_point: + split_point = (df.shape[1] - 2) // 2 + + # 划分特征列 + columns_with_y = ['id', 'y'] + column_names[:split_point] + columns_without_y = ['id'] + column_names[split_point:] + + # 创建两个数据集 + df_with_y = df[columns_with_y] + df_without_y = df[columns_without_y] + + return df_with_y, df_without_y + + def _random_split_dataset(self): + + train_data, test_data = train_test_split( + self.model_data, test_size=self.test_size, random_state=self.random_state) + + return train_data, test_data + + def _customized_split_dataset(self): + if self.ctx.role == TaskRole.ACTIVE_PARTY: + for partner_index in range(1, len(self.ctx.participant_id_list)): + byte_data = SendMessage._receive_byte_data(self.ctx.model_router, self.ctx, + f'{CommonMessage.EVAL_SET_FILE.value}', partner_index) + if not os.path.exists(self.eval_column_file) and byte_data != bytes(): + with open(self.eval_column_file, 'wb') as f: + f.write(byte_data) + with open(self.eval_column_file, 'rb') as f: + byte_data = f.read() + for partner_index in range(1, len(self.ctx.participant_id_list)): + SendMessage._send_byte_data(self.ctx.model_router, self.ctx, f'{CommonMessage.EVAL_SET_FILE.value}', + byte_data, partner_index) + else: + if not os.path.exists(self.eval_column_file): + byte_data = bytes() + else: + with open(self.eval_column_file, 'rb') as f: + byte_data = f.read() + SendMessage._send_byte_data(self.ctx.model_router, self.ctx, f'{CommonMessage.EVAL_SET_FILE.value}', + byte_data, 0) + byte_data = SendMessage._receive_byte_data(self.ctx.model_router, self.ctx, + f'{CommonMessage.EVAL_SET_FILE.value}', 0) + if not os.path.exists(self.eval_column_file): + with open(self.eval_column_file, 'wb') as f: + f.write(byte_data) + + eval_set_df = pd.read_csv(self.eval_column_file, header=0) + train_data = self.model_data[eval_set_df[self.eval_set_column] + == self.train_set_value] + test_data = self.model_data[eval_set_df[self.eval_set_column] + == self.eval_set_value] + + return train_data, test_data + + def _construct_model_dataset(self, train_data, test_data): + + self.train_idx = train_data['id'].values + self.test_idx = test_data['id'].values + + if self.is_label_holder and 'y' in train_data.columns: + self.train_y = train_data['y'].values + self.test_y = test_data['y'].values + self.train_X = train_data.drop(columns=['id', 'y']).values + self.test_X = test_data.drop(columns=['id', 'y']).values + self.feature_name = train_data.drop( + columns=['id', 'y']).columns.tolist() + else: + self.train_X = train_data.drop(columns=['id']).values + self.test_X = test_data.drop(columns=['id']).values + self.feature_name = train_data.drop( + columns=['id']).columns.tolist() + + def _construct_predict_dataset(self, test_data): + self.test_idx = test_data['id'].values + if self.is_label_holder and 'y' in test_data.columns: + self.test_y = test_data['y'].values + self.test_X = test_data.drop(columns=['id', 'y']).values + self.feature_name = test_data.drop( + columns=['id', 'y']).columns.tolist() + else: + self.test_X = test_data.drop(columns=['id']).values + self.feature_name = test_data.drop(columns=['id']).columns.tolist() + + def _dataset_fe_selected(self, file_path, feature_name): + iv_selected = pd.read_csv(file_path, header=0) + selected_list = iv_selected[feature_name][iv_selected['iv_selected'] == 1].tolist( + ) + + drop_columns = [] + for column in self.model_data.columns: + if column == 'id' or column == 'y': + continue + if column not in selected_list: + drop_columns.append(column) + + if len(drop_columns) > 0: + self.model_data = self.model_data.drop(columns=drop_columns) + + def _construct_dataset(self): + if self.algorithm_type == AlgorithmType.Predict.name: + my_fields = [] + for item in self.ctx.model_predict_algorithm['participant_agency_list']: + if item["agency"] == self.ctx.components.config_data['AGENCY_ID']: + my_fields = item["fields"] + if 'y' in self.model_data.columns and 'y' not in my_fields: + my_fields = ['y'] + my_fields + if 'id' in self.model_data.columns and 'id' not in my_fields: + my_fields = ['id'] + my_fields + self.model_data = self.model_data[my_fields] + + if os.path.exists(self.iv_selected_file): + self._dataset_fe_selected(self.iv_selected_file, 'feature') + + if self.algorithm_type == AlgorithmType.Predict.name \ + and not os.path.exists(self.selected_col_file): + try: + ResultFileHandling._download_file(self.ctx.components.storage_client, + self.selected_col_file, self.ctx.remote_selected_col_file) + self._dataset_fe_selected(self.selected_col_file, 'id') + except: + pass + + if 'id' not in self.model_data.columns: + if self.ctx.dataset_file_path is None: + import glob + pattern = os.path.join(self.ctx.workspace, 'd-*') + dataset_file_path = glob.glob(pattern)[0] + else: + dataset_file_path = self.ctx.dataset_file_path + dataset_id = pd.read_csv( + dataset_file_path, header=0, usecols=['id']) + if os.path.exists(self.ctx.psi_result_path): + psi_data = pd.read_csv(self.ctx.psi_result_path, header=0) + dataset_id = pd.merge(dataset_id, psi_data, on=[ + 'id']).sort_values(by='id', ascending=True) + self.model_data = pd.concat([dataset_id, self.model_data], axis=1) + + if self.algorithm_type == AlgorithmType.Train.name: + if self.eval_set_column: + train_data, test_data = self._customized_split_dataset() + else: + train_data, test_data = self._random_split_dataset() + self._construct_model_dataset(train_data, test_data) + + elif self.algorithm_type == AlgorithmType.Predict.name: + test_data = self.model_data + self._construct_predict_dataset(test_data) + else: + raise PpcException(PpcErrorCode.ALGORITHM_TYPE_ERROR.get_code(), + PpcErrorCode.ALGORITHM_TYPE_ERROR.get_message()) diff --git a/python/ppc_model/datasets/feature_binning/__init__.py b/python/ppc_model/datasets/feature_binning/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/python/ppc_model/datasets/feature_binning/feature_binning.py b/python/ppc_model/datasets/feature_binning/feature_binning.py new file mode 100644 index 00000000..9baa230c --- /dev/null +++ b/python/ppc_model/datasets/feature_binning/feature_binning.py @@ -0,0 +1,131 @@ +import numpy as np +import pandas as pd + +from ppc_common.ppc_utils.utils import AlgorithmType +from ppc_model.common.context import Context + + +class FeatureBinning: + def __init__(self, ctx: Context): + self.ctx = ctx + self.params = ctx.model_params + self.data = None + self.data_bin = None + self.data_split = None + + @staticmethod + def binning_continuous_feature(feature: np.ndarray, max_bin: int, is_equal_freq: bool = True): + try: + if is_equal_freq: + # 等频分箱,不替换缺失值 + Xk_bin, Xk_split = pd.qcut( + feature, q=max_bin, retbins=True, labels=False) + else: + # 等距分箱,不替换缺失值 + Xk_bin, Xk_split = pd.cut( + feature, max_bin, retbins=True, labels=False) + # 将缺失值标记为 -1 + Xk_bin[np.isnan(feature)] = -1 + except ValueError: + unique_values = sorted(set(feature[~np.isnan(feature)])) + if len(unique_values) > 1000: + raise Exception( + 'Features with more than 1000 groups are not supported.') + if len(unique_values) == 2 and 0 in unique_values and 1 in unique_values: + Xk_bin = feature + Xk_split = [min(unique_values) - 0.01, 0.5, max(unique_values)] + elif len(unique_values) > max_bin: + Xk_bin, Xk_split = pd.cut( + feature, max_bin, labels=False, retbins=True) + else: + # 创建映射字典 + mapping_dict = {value: i for i, + value in enumerate(unique_values)} + # 使用map函数进行重新编号 + Xk_bin = pd.DataFrame(feature)[0].map(mapping_dict).values + Xk_split = [min(unique_values) - 0.01] + list(unique_values) + Xk_bin[np.isnan(feature)] = -1 + + return Xk_bin, Xk_split + + @staticmethod + def binning_categorical_feature(feature: np.ndarray): + unique_values = sorted(set(feature[~np.isnan(feature)])) + if len(unique_values) > 1000: + raise Exception( + 'Features with more than 1000 groups are not supported.') + mapping_dict = {value: i for i, value in enumerate(unique_values)} + # 使用map函数进行重新编号 + Xk_bin = pd.DataFrame(feature)[0].map(mapping_dict).values + Xk_split = [min(unique_values) - 0.01] + list(unique_values) + Xk_bin[np.isnan(feature)] = -1 + + return Xk_bin, Xk_split + + def data_binning(self, data: np.ndarray, data_split=None): + + self.data = data + self.data_split = data_split + + if self.ctx.algorithm_type == AlgorithmType.Train.name and self.data_split is None: + self._generate_data_binning() + else: + self._reuse_data_binning(data_split) + + return self.data_bin, self.data_split + + def _generate_data_binning(self): + + n = self.data.shape[0] + d = self.data.shape[1] + + X_bin = np.zeros((d, n), dtype='int16') + X_split = [] + + for idx, feature in enumerate(self.data.T): + if idx in self.params.my_categorical_idx: + Xk_bin, Xk_split = FeatureBinning.binning_categorical_feature( + feature) + else: + Xk_bin, Xk_split = FeatureBinning.binning_continuous_feature( + feature, self.params.max_bin) + + X_bin[idx] = Xk_bin + if isinstance(Xk_split, np.ndarray): + Xk_split = Xk_split.tolist() + X_split.append(Xk_split) + + self.data_bin = X_bin.T + self.data_split = X_split + + def _reuse_data_binning(self, data_split): + + self.data_split = data_split + + n = self.data.shape[0] + d = self.data.shape[1] + + test_X_bin = np.zeros((d, n), dtype='int16') + + for k in range(d): + bin_min = min(self.data[:, k]) - 1 + bin_max = max(self.data[:, k]) + 1 + if np.isnan(bin_min): + bin_min = min(self.data_split[k]) + if np.isnan(bin_max): + bin_max = max(self.data_split[k]) + + bin_min = min(bin_min, min(self.data_split[k])) - 1 + bin_max = max(bin_max, max(self.data_split[k])) + 1 + + if len(self.data_split[k]) > 2: + bins = np.concatenate( + ([bin_min], self.data_split[k][1:-1], [bin_max]), axis=0) + else: + bins = np.concatenate(([bin_min], [bin_max]), axis=0) + test_Xk_bin = pd.cut(self.data[:, k], bins, labels=False) + test_Xk_bin[np.isnan(test_Xk_bin)] = -1 + + test_X_bin[k] = test_Xk_bin + + self.data_bin = test_X_bin.T diff --git a/python/ppc_model/datasets/feature_binning/test/__init__.py b/python/ppc_model/datasets/feature_binning/test/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/python/ppc_model/datasets/feature_binning/test/test_feature_binning.py b/python/ppc_model/datasets/feature_binning/test/test_feature_binning.py new file mode 100644 index 00000000..88bb637c --- /dev/null +++ b/python/ppc_model/datasets/feature_binning/test/test_feature_binning.py @@ -0,0 +1,104 @@ +import unittest + +from ppc_model.common.initializer import Initializer +from ppc_common.ppc_mock.mock_objects import MockLogger +from ppc_model.datasets.dataset import SecureDataset +from ppc_model.datasets.feature_binning.feature_binning import FeatureBinning +from ppc_model.secure_lgbm.secure_lgbm_context import SecureLGBMContext + + +data_size = 1000 +feature_dim = 100 +has_label = True + + +class TestFeatureBinning(unittest.TestCase): + + components = Initializer(log_config_path='', config_path='') + components.config_data = {'JOB_TEMP_DIR': '/tmp'} + components.mock_logger = MockLogger() + + def test_train_feature_binning(self): + + # 构造主动方参数配置 + args = { + 'job_id': 'j-123', + 'task_id': '1', + 'is_label_holder': True, + 'result_receiver_id_list': [], + 'participant_id_list': [], + 'model_predict_algorithm': None, + 'algorithm_type': 'Train', + 'algorithm_subtype': None, + 'model_dict': { + 'objective': 'regression', + 'max_bin': 10, + 'n_estimators': 6, + 'max_depth': 3, + 'use_goss': 1 + } + } + + task_info = SecureLGBMContext(args['task_id'], args, self.components) + model_data = SecureDataset.simulate_dataset( + data_size, feature_dim, has_label) + secure_dataset = SecureDataset(task_info, model_data) + print(secure_dataset.train_idx.shape) + print(secure_dataset.train_X.shape) + print(secure_dataset.train_y.shape) + print(secure_dataset.test_idx.shape) + print(secure_dataset.test_X.shape) + print(secure_dataset.test_y.shape) + + feat_bin = FeatureBinning(task_info) + data_bin, data_split = feat_bin.data_binning(secure_dataset.train_X) + + self.assertEqual(data_bin.shape, secure_dataset.train_X.shape) + # print(data_bin) + # print(data_split) + + def test_test_feature_binning(self): + + # 构造主动方参数配置 + args = { + 'job_id': 'j-123', + 'task_id': '1', + 'is_label_holder': True, + 'result_receiver_id_list': [], + 'participant_id_list': [], + 'model_predict_algorithm': None, + 'algorithm_type': 'Train', + 'algorithm_subtype': None, + 'model_dict': { + 'objective': 'regression', + 'categorical_feature': [], + 'max_bin': 10, + 'n_estimators': 6, + 'max_depth': 3, + 'use_goss': 1 + } + } + + task_info = SecureLGBMContext(args['task_id'], args, self.components) + model_data = SecureDataset.simulate_dataset( + data_size, feature_dim, has_label) + secure_dataset = SecureDataset(task_info, model_data) + print(secure_dataset.train_idx.shape) + print(secure_dataset.train_X.shape) + print(secure_dataset.train_y.shape) + print(secure_dataset.test_idx.shape) + print(secure_dataset.test_X.shape) + print(secure_dataset.test_y.shape) + + feat_bin = FeatureBinning(task_info) + data_split = None + data_bin, data_split = feat_bin.data_binning( + secure_dataset.train_X, data_split) + + self.assertEqual(data_bin.shape, secure_dataset.train_X.shape) + # print(data_bin) + # print(data_split) + + +if __name__ == "__main__": + unittest.main() diff --git a/python/ppc_model/datasets/test/__init__.py b/python/ppc_model/datasets/test/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/python/ppc_model/datasets/test/test_dataset.py b/python/ppc_model/datasets/test/test_dataset.py new file mode 100644 index 00000000..a4f1ec7b --- /dev/null +++ b/python/ppc_model/datasets/test/test_dataset.py @@ -0,0 +1,215 @@ +import unittest +import numpy as np +import pandas as pd +from sklearn.model_selection import train_test_split +from sklearn.datasets import load_breast_cancer + +from ppc_model.common.initializer import Initializer +from ppc_common.ppc_mock.mock_objects import MockLogger +from ppc_model.secure_lgbm.secure_lgbm_context import SecureLGBMContext +from ppc_model.datasets.dataset import SecureDataset + + +class TestSecureDataset(unittest.TestCase): + cancer = load_breast_cancer() + X = cancer.data + y = cancer.target + + df = SecureDataset.assembling_dataset(X, y) + assert (df.columns == ['id', 'y'] + [f'x{i + 1}' for i in range(30)]).all() + + # 模拟生成主动方和被动方数据集 + df_with_y, df_without_y = SecureDataset.hetero_split_dataset(df) + assert (df_with_y.columns == ['id', 'y'] + + [f'x{i + 1}' for i in range(15)]).all() + assert (df_without_y.columns == ['id'] + + [f'x{i + 16}' for i in range(15)]).all() + + # 模拟自定义分组 + import os + + eval_column_file = './model_eval_column.csv' + if not os.path.exists(eval_column_file): + # 创建一个包含569行,2列的数据,其中415个为'INS',154个为'OOS' + group_set = np.concatenate([['INS'] * 415, ['OOS'] * 154]) + np.random.shuffle(group_set) + eval_set_df = pd.DataFrame( + {'id': np.arange(1, 570), 'group': group_set}) + eval_set_df.to_csv(eval_column_file, index=None) + + df_with_y_file = './df_with_y.csv' + if not os.path.exists(df_with_y_file): + df_with_y.to_csv(df_with_y_file, index=None, sep=' ') + + df_without_y_file = './df_without_y.csv' + if not os.path.exists(df_without_y_file): + df_without_y.to_csv(df_without_y_file, index=None, sep=' ') + + iv_selected_file = './iv_selected.csv' + if not os.path.exists(iv_selected_file): + iv_selected = pd.DataFrame( + {'feature': [f'x{i + 1}' for i in range(30)], + 'iv_selected': np.random.binomial(n=1, p=0.5, size=30)}) + iv_selected.to_csv(iv_selected_file, index=None) + + components = Initializer(log_config_path='', config_path='') + components.config_data = {'JOB_TEMP_DIR': '/tmp', 'MAX_THREAD_WORKERS': 10} + components.mock_logger = MockLogger() + + def test_random_split_dataset(self): + + # 构造主动方参数配置 + args = { + 'job_id': 'j-123', + 'task_id': '1', + 'is_label_holder': True, + 'result_receiver_id_list': [], + 'participant_id_list': [], + 'model_predict_algorithm': None, + 'algorithm_type': 'Train', + 'algorithm_subtype': None, + 'model_dict': { + 'random_state': 2024 + } + } + task_info = SecureLGBMContext(args['task_id'], args, self.components) + print(task_info.model_params.get_all_params()) + + # 模拟构造主动方数据集 + dataset_with_y = SecureDataset(task_info, self.df_with_y) + assert (dataset_with_y.train_idx == + train_test_split(np.array(range(1, 570)), test_size=0.3, random_state=2024)[0]).all() + self.assertEqual(dataset_with_y.train_X.shape, (398, 15)) + self.assertEqual(dataset_with_y.test_X.shape, (171, 15)) + self.assertEqual(dataset_with_y.train_y.shape, (398,)) + self.assertEqual(dataset_with_y.test_y.shape, (171,)) + + # 构造被动方参数配置 + args = { + 'job_id': 'j-123', + 'task_id': '1', + 'is_label_holder': False, + 'result_receiver_id_list': [], + 'participant_id_list': [], + 'model_predict_algorithm': None, + 'algorithm_type': 'Train', + 'algorithm_subtype': None, + 'model_dict': { + 'random_state': 2024 + } + } + task_info = SecureLGBMContext(args['task_id'], args, self.components) + print(task_info.model_params.get_all_params()) + + # 模拟构造被动方数据集 + dataset_without_y = SecureDataset(task_info, self.df_without_y) + assert (dataset_without_y.train_idx == dataset_with_y.train_idx).all() + self.assertEqual(dataset_without_y.train_X.shape, (398, 15)) + self.assertEqual(dataset_without_y.test_X.shape, (171, 15)) + self.assertEqual(dataset_without_y.train_y, None) + self.assertEqual(dataset_without_y.test_y, None) + + def test_customized_split_dataset(self): + + # 构造主动方参数配置 + args = { + 'job_id': 'j-123', + 'task_id': '1', + 'is_label_holder': True, + 'result_receiver_id_list': [], + 'participant_id_list': [], + 'model_predict_algorithm': None, + 'algorithm_type': 'Train', + 'algorithm_subtype': None, + 'model_dict': { + 'eval_set_column': 'group', + 'train_set_value': 'INS', + 'eval_set_value': 'OOS' + } + } + task_info = SecureLGBMContext(args['task_id'], args, self.components) + print(task_info.model_params.get_all_params()) + + # 模拟构造主动方数据集 + task_info.eval_column_file = self.eval_column_file + task_info.model_prepare_file = self.df_with_y_file + eval_set_df = pd.read_csv(task_info.eval_column_file, header=0) + + dataset_with_y = SecureDataset(task_info) + assert (dataset_with_y.train_idx == + eval_set_df['id'][eval_set_df['group'] == 'INS']).all() + self.assertEqual(dataset_with_y.train_X.shape, (415, 15)) + self.assertEqual(dataset_with_y.test_X.shape, (154, 15)) + self.assertEqual(dataset_with_y.train_y.shape, (415,)) + self.assertEqual(dataset_with_y.test_y.shape, (154,)) + + def test_predict_dataset(self): + + # 构造主动方参数配置 + args = { + 'job_id': 'j-123', + 'task_id': '1', + 'is_label_holder': True, + 'result_receiver_id_list': [], + 'participant_id_list': [], + 'model_predict_algorithm': None, + 'algorithm_type': 'Predict', + 'algorithm_subtype': None, + 'model_dict': {} + } + task_info = SecureLGBMContext(args['task_id'], args, self.components) + print(task_info.model_params.get_all_params()) + + # 模拟构造主动方数据集 + task_info.model_prepare_file = self.df_with_y_file + dataset_with_y = SecureDataset(task_info) + + self.assertEqual(dataset_with_y.train_X, None) + self.assertEqual(dataset_with_y.test_X.shape, (569, 15)) + self.assertEqual(dataset_with_y.train_y, None) + self.assertEqual(dataset_with_y.test_y.shape, (569,)) + + def test_iv_selected_dataset(self): + + # 构造主动方参数配置 + args = { + 'job_id': 'j-123', + 'task_id': '1', + 'is_label_holder': True, + 'result_receiver_id_list': [], + 'participant_id_list': [], + 'model_predict_algorithm': None, + 'algorithm_type': 'Predict', + 'algorithm_subtype': None, + 'model_dict': {} + } + task_info = SecureLGBMContext(args['task_id'], args, self.components) + print(task_info.model_params.get_all_params()) + + # 模拟构造主动方数据集 + task_info.model_prepare_file = self.df_with_y_file + task_info.iv_selected_file = './iv_selected.csv' + dataset_with_y = SecureDataset(task_info) + + self.assertEqual(dataset_with_y.train_X, None) + self.assertEqual(dataset_with_y.test_X.shape, (569, 9)) + self.assertEqual(dataset_with_y.train_y, None) + self.assertEqual(dataset_with_y.test_y.shape, (569,)) + + def test_read_dataset(self): + np.random.seed(0) + origin_data = np.random.randint(0, 100, size=(100, 10)) + columns = ['id'] + [f"x{i}" for i in range(2, 11)] + df = pd.DataFrame(origin_data, columns=columns) + csv_file = '/tmp/data_x1_to_x10.csv' + df.to_csv(csv_file, index=False) + field_list, label, feature = SecureDataset.read_dataset( + csv_file, False, delimiter=',') + self.assertEqual(['id'] + field_list, columns) + field_list, label, feature = SecureDataset.read_dataset( + csv_file, True, delimiter=',') + self.assertEqual(['id'] + field_list, columns) + + +if __name__ == "__main__": + unittest.main() diff --git a/python/ppc_model/db/__init__.py b/python/ppc_model/db/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/python/ppc_model/db/job_worker_record.py b/python/ppc_model/db/job_worker_record.py new file mode 100644 index 00000000..c3d4b0d9 --- /dev/null +++ b/python/ppc_model/db/job_worker_record.py @@ -0,0 +1,34 @@ +# -*- coding: utf-8 -*- +from datetime import datetime +from ppc_common.db_models import db + + +class JobWorkerRecord(db.Model): + """ + CREATE TABLE if not exists wedpr_job_worker_table ( + worker_id VARCHAR(100), + job_id VARCHAR(255), + type VARCHAR(255), + status VARCHAR(255), + args LONGTEXT, + upstreams TEXT, + inputs_statement TEXT, + outputs TEXT, + create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (worker_id), + INDEX job_id_idx (job_id) + )ENGINE='InnoDB' DEFAULT CHARSET='utf8mb4' COLLATE='utf8mb4_bin' ROW_FORMAT=DYNAMIC; + """ + __tablename__ = 'wedpr_job_worker_table' + worker_id = db.Column(db.String(100), primary_key=True) + job_id = db.Column(db.String(255), index=True) + type = db.Column(db.String(255)) + status = db.Column(db.String(255)) + upstreams = db.Column(db.Text) + inputs_statement = db.Column(db.Text) + args = db.Column(db.Text) + outputs = db.Column(db.Text) + exec_result = db.Column(db.Text) + create_time = db.Column(db.DateTime, default=datetime.now) + update_time = db.Column(db.DateTime, onupdate=datetime.now) diff --git a/python/ppc_model/feature_engineering/__init__.py b/python/ppc_model/feature_engineering/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/python/ppc_model/feature_engineering/feature_engineering_context.py b/python/ppc_model/feature_engineering/feature_engineering_context.py new file mode 100644 index 00000000..c4504942 --- /dev/null +++ b/python/ppc_model/feature_engineering/feature_engineering_context.py @@ -0,0 +1,50 @@ +from enum import Enum + +import numpy as np + +from ppc_common.ppc_crypto.phe_factory import PheCipherFactory +from ppc_model.common.context import Context +from ppc_model.common.initializer import Initializer +from ppc_model.common.protocol import TaskRole +from ppc_model.common.model_setting import ModelSetting + + +class FeMessage(Enum): + ENC_LABELS = "ENC_LABELS" + AGGR_LABELS = "AGGR_LABELS" + WOE_FILE = "WOE_FILE" + IV_SELECTED_FILE = "IV_SELECTED_FILE" + + +class FeatureEngineeringContext(Context): + + def __init__(self, + task_id, + args, + components: Initializer, + role: TaskRole, + feature: np.ndarray, + feature_name_list: list, + label: np.ndarray = None): + super().__init__(job_id=args['job_id'], + task_id=task_id, + components=components, + role=role, + user=args['user']) + self.feature_name_list = feature_name_list + self.participant_id_list = args['participant_id_list'] + self.result_receiver_id_list = args['result_receiver_id_list'] + self.model_dict = args['model_dict'] + self.feature = feature + self.label = label + self.phe = PheCipherFactory.build_phe( + components.homo_algorithm, components.public_key_length) + self.codec = PheCipherFactory.build_codec(components.homo_algorithm) + self.model_setting = ModelSetting(self.model_dict) + self._parse_model_dict() + + def _parse_model_dict(self): + self.use_iv = self.model_setting.use_iv + self.iv_thresh = self.model_setting.iv_thresh + self.categorical = self.model_setting.categorical + self.group_num = self.model_setting.group_num diff --git a/python/ppc_model/feature_engineering/feature_engineering_engine.py b/python/ppc_model/feature_engineering/feature_engineering_engine.py new file mode 100644 index 00000000..8b67fd68 --- /dev/null +++ b/python/ppc_model/feature_engineering/feature_engineering_engine.py @@ -0,0 +1,49 @@ +from ppc_model.common.base_context import BaseContext +from ppc_model.common.global_context import components +from ppc_model.common.protocol import ModelTask, TaskRole +from ppc_model.datasets.dataset import SecureDataset +from ppc_model.feature_engineering.feature_engineering_context import FeatureEngineeringContext +from ppc_model.feature_engineering.vertical.active_party import VerticalFeatureEngineeringActiveParty +from ppc_model.feature_engineering.vertical.passive_party import VerticalFeatureEngineeringPassiveParty +from ppc_model.interface.task_engine import TaskEngine + + +class FeatureEngineeringEngine(TaskEngine): + task_type = ModelTask.FEATURE_ENGINEERING + + @staticmethod + def run(task_id, args): + base_ctx = BaseContext( + job_id=args['job_id'], user=args["user"], job_temp_dir=components.config_data['JOB_TEMP_DIR']) + # try to download the model_prepare_file + BaseContext.load_file(components.storage_client, + remote_path=base_ctx.remote_model_prepare_file, + local_path=base_ctx.model_prepare_file, logger=components.logger()) + + if args['is_label_holder']: + field_list, label, feature = SecureDataset.read_dataset( + base_ctx.model_prepare_file, True) + context = FeatureEngineeringContext( + task_id=task_id, + args=args, + components=components, + role=TaskRole.ACTIVE_PARTY, + feature=feature, + feature_name_list=field_list[1:], + label=label + ) + vfe = VerticalFeatureEngineeringActiveParty(context) + else: + field_list, _, feature = SecureDataset.read_dataset( + base_ctx.model_prepare_file, False) + context = FeatureEngineeringContext( + task_id=task_id, + args=args, + components=components, + role=TaskRole.PASSIVE_PARTY, + feature=feature, + feature_name_list=field_list, + label=None + ) + vfe = VerticalFeatureEngineeringPassiveParty(context) + vfe.fit() diff --git a/python/ppc_model/feature_engineering/test/__init__.py b/python/ppc_model/feature_engineering/test/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/python/ppc_model/feature_engineering/test/feature_engineering_unittest.py b/python/ppc_model/feature_engineering/test/feature_engineering_unittest.py new file mode 100644 index 00000000..09340a8b --- /dev/null +++ b/python/ppc_model/feature_engineering/test/feature_engineering_unittest.py @@ -0,0 +1,136 @@ +import multiprocessing +import threading +import traceback +import unittest + +import numpy as np + +from ppc_common.ppc_async_executor.thread_event_manager import ThreadEventManager +from ppc_common.ppc_mock.mock_objects import MockLogger, MockStorageClient +from ppc_model.common.initializer import Initializer +from ppc_model.common.mock.mock_model_transport import MockModelRouterApi +from ppc_model.common.protocol import TaskRole +from ppc_model.feature_engineering.feature_engineering_context import FeatureEngineeringContext +from ppc_model.feature_engineering.vertical.active_party import VerticalFeatureEngineeringActiveParty +from ppc_model.feature_engineering.vertical.passive_party import VerticalFeatureEngineeringPassiveParty + +ACTIVE_PARTY = 'ACTIVE_PARTY' + +PASSIVE_PARTY = 'PASSIVE_PARTY' + + +def construct_dataset(num_samples, num_features): + np.random.seed(0) + # 生成标签列 + labels = np.random.choice([0, 1], size=num_samples) + # 生成特征列 + features = np.random.rand(num_samples, num_features) + return labels, features + + +def mock_args(num_features, iv_thresh): + job_id = '0x12345678' + active_fields = ['a' + str(i) for i in range(num_features)] + passive_fields = ['b' + str(i) for i in range(num_features)] + + model_config_dict = { + 'use_iv': True, + 'iv_thresh': iv_thresh, + 'categorical': '0', + 'group_num': 100, + + } + + args_a = { + 'job_id': job_id, + 'task_id': job_id, + 'feature_name_list': active_fields, + 'participant_id_list': [ACTIVE_PARTY, PASSIVE_PARTY], + 'result_receiver_id_list': [ACTIVE_PARTY, PASSIVE_PARTY], + 'model_dict': model_config_dict, + } + + args_b = { + 'job_id': job_id, + 'task_id': job_id, + 'feature_name_list': passive_fields, + 'participant_id_list': [ACTIVE_PARTY, PASSIVE_PARTY], + 'result_receiver_id_list': [ACTIVE_PARTY, PASSIVE_PARTY], + 'model_dict': model_config_dict, + } + return args_a, args_b + + +class TestFeatureEngineering(unittest.TestCase): + + def setUp(self): + participants = [PASSIVE_PARTY, ACTIVE_PARTY] + self._active_transport = MockModelRouterApi(participants) + self._passive_transport = MockModelRouterApi(participants) + + def test_fit(self): + num_samples = 100000 + num_features = 100 + iv_thresh = 0.05 + labels, features = construct_dataset(num_samples, num_features) + args_a, args_b = mock_args(num_features, iv_thresh) + + active_components = Initializer(log_config_path='', config_path='') + active_components.homo_algorithm = 0 + active_components.transport = self._active_transport + active_components.config_data = {'JOB_TEMP_DIR': '/tmp'} + active_components.mock_logger = MockLogger() + active_components.storage_client = MockStorageClient() + active_context = FeatureEngineeringContext( + task_id=args_a['task_id'], + args=args_a, + components=active_components, + role=TaskRole.ACTIVE_PARTY, + feature=features, + feature_name_list=args_a['feature_name_list'], + label=labels + ) + active_vfe = VerticalFeatureEngineeringActiveParty(active_context) + + passive_components = Initializer(log_config_path='', config_path='') + passive_components.homo_algorithm = 0 + passive_components.transport = self._passive_transport + passive_components.config_data = {'JOB_TEMP_DIR': '/tmp'} + passive_components.mock_logger = MockLogger() + passive_components.storage_client = MockStorageClient() + passive_context = FeatureEngineeringContext( + task_id=args_b['task_id'], + args=args_b, + components=passive_components, + role=TaskRole.PASSIVE_PARTY, + feature=features, + feature_name_list=args_b['feature_name_list'], + label=None + ) + passive_vfe = VerticalFeatureEngineeringPassiveParty(passive_context) + + def active_worker(): + try: + active_vfe.fit() + except Exception as e: + active_components.logger().info(traceback.format_exc()) + + def passive_worker(): + try: + passive_vfe.fit() + except Exception as e: + active_components.logger().info(traceback.format_exc()) + + thread_fe_active = threading.Thread(target=active_worker, args=()) + thread_fe_active.start() + + thread_fe_passive = threading.Thread(target=passive_worker, args=()) + thread_fe_passive.start() + + thread_fe_active.join() + thread_fe_passive.join() + + +if __name__ == '__main__': + multiprocessing.set_start_method('spawn') + unittest.main() diff --git a/python/ppc_model/feature_engineering/vertical/__init__.py b/python/ppc_model/feature_engineering/vertical/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/python/ppc_model/feature_engineering/vertical/active_party.py b/python/ppc_model/feature_engineering/vertical/active_party.py new file mode 100644 index 00000000..de1ebed8 --- /dev/null +++ b/python/ppc_model/feature_engineering/vertical/active_party.py @@ -0,0 +1,197 @@ +import multiprocessing +import os +import time + +import pandas as pd + +from ppc_common.ppc_protos.generated.ppc_model_pb2 import EncAggrLabelsList +from ppc_common.ppc_utils import utils +from ppc_model.common.protocol import PheMessage +from ppc_model.feature_engineering.feature_engineering_context import FeatureEngineeringContext, FeMessage +from ppc_model.feature_engineering.vertical.utils import is_continuous_feature, calculate_woe_iv, \ + calculate_woe_iv_with_pos_event +from ppc_model.interface.model_base import VerticalModel + + +class VerticalFeatureEngineeringActiveParty(VerticalModel): + + def __init__(self, ctx: FeatureEngineeringContext): + super().__init__(ctx) + # 记录woe和iv详情 + self.woe_iv_df = pd.DataFrame(columns=['feature', 'bins', 'count', 'pos_event', 'pos_event_rate', + 'neg_event', 'neg_event_rate', 'woe', 'iv', 'iv_total']) + # 记录特征筛选情况 + self.iv_selected_df = pd.DataFrame(columns=['feature', 'iv_selected']) + + def fit(self, *args, **kwargs) -> None: + log = self.ctx.components.logger() + task_id = self.ctx.task_id + start_time = time.time() + if self.ctx.use_iv: + log.info(f"Start feature engineering, task_id: {task_id}, shape: {self.ctx.feature.shape}, " + f"feature_name_list: {self.ctx.feature_name_list}") + + if len(self.ctx.feature_name_list) != 0: + # 明文计算己方特征的woe/iv + self._compute_self_woe_iv() + + # 密态交互计算合作方特征的woe/iv + log.info(f"Start enc labels, task_id: {task_id}") + enc_start_time = time.time() + enc_labels = self.ctx.phe.encrypt_batch_parallel(self.ctx.label) + log.info( + f"Enc labels finished, task_id: {task_id}, count: {len(enc_labels)}, " + f"time_costs: {time.time() - enc_start_time}s") + + for i in range(1, len(self.ctx.participant_id_list)): + self._compute_partner_woe_iv(enc_labels, i) + + # 处理计算结果 + self._save_and_sync_fe_results() + + log.info( + f"Feature engineering finished, task_id: {task_id}, time_costs: {time.time() - start_time}s, " + f"iv_selected: {self.iv_selected_df}") + + def _compute_self_woe_iv(self): + log = self.ctx.components.logger() + start_time = time.time() + for i in range(self.ctx.feature.shape[1]): + field = self.ctx.feature_name_list[i] + is_continuous = is_continuous_feature(self.ctx.categorical, field) + grouped, iv_total = calculate_woe_iv(self.ctx.feature[:, i], + self.ctx.label, + self.ctx.group_num, + is_continuous) + for index, row in grouped.iterrows(): + self.woe_iv_df = pd.concat([self.woe_iv_df, pd.DataFrame({ + 'feature': field, + 'bins': index, + 'count': [row['count']], + 'pos_event': [row['pos_event']], + 'pos_event_rate': [row['pos_event_rate']], + 'neg_event': [row['neg_event']], + 'neg_event_rate': [row['neg_event_rate']], + 'woe': [row['woe']], + 'iv': [row['iv']], + 'iv_total': [row['iv_total']] + })], ignore_index=True) + + self.iv_selected_df.loc[len(self.iv_selected_df)] = {'feature': field, + 'iv_selected': int(iv_total >= self.ctx.iv_thresh)} + log.info( + f"_compute_self_woe_iv, feature: {field}, iv_total: {iv_total}, iv_thres: {self.ctx.iv_thresh}") + log.info( + f"Computing self woe/iv finished, task_id: {self.ctx.task_id}, time_costs: {time.time() - start_time}s, iv_thres: {self.ctx.iv_thresh}") + + def _compute_partner_woe_iv(self, enc_labels, partner_index): + log = self.ctx.components.logger() + start_time = time.time() + + partner_id = self.ctx.participant_id_list[partner_index] + self._send_enc_labels(enc_labels, partner_id) + enc_aggr_labels = self._get_all_enc_aggr_labels(partner_id) + + # results = [] + # with ProcessPoolExecutor(max_workers=max(1, os.cpu_count() - 1)) as executor: + # futures = [executor.submit( + # self._process_one_feature, + # self.ctx.phe, + # field, + # count_list, + # enc_aggr_labels) for field, count_list, enc_aggr_labels in enc_aggr_labels] + # for future in as_completed(futures): + # results.append(future.result()) + + pool = multiprocessing.Pool() + tasks = [(self.ctx.phe, field, count_list, enc_aggr_labels) for field, count_list, enc_aggr_labels in + enc_aggr_labels] + results = pool.starmap(self._process_one_feature, tasks) + pool.close() + pool.join() + + for field, field_woe_iv_df, iv_total in results: + # 记录新字段的woe和iv + self.woe_iv_df = pd.concat( + [self.woe_iv_df, field_woe_iv_df], ignore_index=True) + self.iv_selected_df.loc[len(self.iv_selected_df)] = {'feature': field, + 'iv_selected': int(iv_total >= self.ctx.iv_thresh)} + log.info( + f"Computing {partner_id}'s woe/iv finished, task_id: {self.ctx.task_id}, " + f"time_costs: {time.time() - start_time}s") + + @staticmethod + def _process_one_feature(phe, field, count_list, enc_aggr_labels): + pos_event = phe.decrypt_batch(enc_aggr_labels) + field_woe_iv_df = pd.DataFrame({'bins': range(len(count_list)), 'count': count_list, + 'pos_event': pos_event, 'feature': field}) + field_woe_iv_df, iv_total = calculate_woe_iv_with_pos_event( + field_woe_iv_df) + return field, field_woe_iv_df, iv_total + + def _get_all_enc_aggr_labels(self, partner_id): + log = self.ctx.components.logger() + start_time = time.time() + data = self.ctx.model_router.pop(task_id=self.ctx.task_id, + task_type=FeMessage.AGGR_LABELS.value, from_inst=partner_id) + enc_aggr_labels_list_pb = EncAggrLabelsList() + utils.bytes_to_pb(enc_aggr_labels_list_pb, data) + public_key = self.ctx.codec.decode_enc_key( + enc_aggr_labels_list_pb.public_key) + + res = [] + for enc_aggr_labels_pb in enc_aggr_labels_list_pb.enc_aggr_labels_list: + enc_aggr_labels = [self.ctx.codec.decode_cipher(public_key, + cipher.ciphertext, + cipher.exponent + ) for cipher in enc_aggr_labels_pb.cipher_list] + field = enc_aggr_labels_pb.field + res.append( + (field, list(enc_aggr_labels_pb.count_list), enc_aggr_labels)) + + log.info( + f"All enc aggr labels received, task_id: {self.ctx.task_id}, feature_num: {len(res)}, " + f"size: {len(data) / 1024}KB, time_costs: {time.time() - start_time}s") + return res + + def _send_enc_labels(self, enc_labels, receiver): + log = self.ctx.components.logger() + start_time = time.time() + + data = PheMessage.packing_data( + self.ctx.codec, self.ctx.phe.public_key, enc_labels) + self.ctx.model_router.push(task_id=self.ctx.task_id, + task_type=FeMessage.ENC_LABELS.value, + dst_agency=receiver, + payload=data) + log.info( + f"Sending enc labels to {receiver} finished, task_id: {self.ctx.task_id}, label_num: {len(enc_labels)}, " + f"size: {len(data) / 1024}KB, time_costs: {time.time() - start_time}s") + + def _save_and_sync_fe_results(self): + log = self.ctx.components.logger() + task_id = self.ctx.task_id + self.woe_iv_df.to_csv(self.ctx.woe_iv_file, + sep=',', header=True, index=None) + self.iv_selected_df.to_csv( + self.ctx.iv_selected_file, sep=',', header=True, index=None) + self.ctx.components.storage_client.upload_file(self.ctx.woe_iv_file, + self.ctx.remote_woe_iv_file, + self.ctx.user) + log.info(f"Saving fe results finished, task_id: {task_id}") + with open(self.ctx.woe_iv_file, 'rb') as f: + woe_iv = f.read() + with open(self.ctx.iv_selected_file, 'rb') as f: + iv_selected = f.read() + for i in range(1, len(self.ctx.participant_id_list)): + partner_id = self.ctx.participant_id_list[i] + if partner_id in self.ctx.result_receiver_id_list: + self.ctx.model_router.push(task_id=self.ctx.task_id, + task_type=FeMessage.WOE_FILE.value, + dst_agency=partner_id, + payload=woe_iv) + self.ctx.model_router.push(task_id=self.ctx.task_id, + task_type=FeMessage.IV_SELECTED_FILE.value, + dst_agency=partner_id, + payload=iv_selected) + log.info(f"Sending fe results finished, task_id: {task_id}") diff --git a/python/ppc_model/feature_engineering/vertical/passive_party.py b/python/ppc_model/feature_engineering/vertical/passive_party.py new file mode 100644 index 00000000..bd9f659b --- /dev/null +++ b/python/ppc_model/feature_engineering/vertical/passive_party.py @@ -0,0 +1,172 @@ +import multiprocessing +import os +import time + +from ppc_common.ppc_protos.generated.ppc_model_pb2 import ModelCipher, EncAggrLabels, EncAggrLabelsList +from ppc_common.ppc_utils import utils +from ppc_model.common.protocol import PheMessage +from ppc_model.datasets.feature_binning.feature_binning import FeatureBinning +from ppc_model.feature_engineering.feature_engineering_context import FeatureEngineeringContext, FeMessage +from ppc_model.feature_engineering.vertical.utils import is_continuous_feature +from ppc_model.interface.model_base import VerticalModel + + +class VerticalFeatureEngineeringPassiveParty(VerticalModel): + + def __init__(self, ctx: FeatureEngineeringContext): + super().__init__(ctx) + + def fit(self, *args, **kwargs) -> None: + log = self.ctx.components.logger() + + task_id = self.ctx.task_id + start_time = time.time() + if self.ctx.use_iv: + log.info(f"Start feature engineering, task_id: {task_id}, shape: {self.ctx.feature.shape}, " + f"feature_name_list: {self.ctx.feature_name_list}.") + + # 执行密文交互,计算正样本数量 + public_key, enc_labels = self._get_enc_labels() + + # 根据特征分箱,聚合加密标签 + aggr_labels_bytes_list = self._binning_and_aggregating_all( + public_key, enc_labels) + + # 发送聚合的密文标签 + self._send_all_enc_aggr_labels(public_key, aggr_labels_bytes_list) + + self._get_and_save_result() + log.info( + f"Feature engineering finished, task_id: {task_id}, timecost: {time.time() - start_time}s") + + def _get_enc_labels(self): + log = self.ctx.components.logger() + start_time = time.time() + active_party = self.ctx.participant_id_list[0] + data = self.ctx.model_router.pop( + task_id=self.ctx.task_id, task_type=FeMessage.ENC_LABELS.value, from_inst=active_party) + public_key, enc_labels = PheMessage.unpacking_data( + self.ctx.codec, data) + log.info(f"All enc labels received, task_id: {self.ctx.task_id}, label_num: {len(enc_labels)}, " + f"size: {len(data) / 1024}KB, timecost: {time.time() - start_time}s") + return public_key, enc_labels + + def _binning_and_aggregating_all(self, public_key, enc_labels) -> list: + log = self.ctx.components.logger() + start_time = time.time() + params = [] + for i in range(self.ctx.feature.shape[1]): + is_continuous = is_continuous_feature( + self.ctx.categorical, self.ctx.feature_name_list[i]) + params.append({ + 'is_continuous': is_continuous, + 'feature_index': i, + 'field': self.ctx.feature_name_list[i], + 'feature': self.ctx.feature[:, i], + 'public_key': public_key, + 'enc_labels': enc_labels, + 'group_num': self.ctx.group_num, + 'codec': self.ctx.codec + }) + # aggr_labels_str = [] + # with ProcessPoolExecutor(max_workers=max(1, os.cpu_count() - 1)) as executor: + # futures = [executor.submit(self._binning_and_aggregating_one, param) for param in params] + # for future in as_completed(futures): + # aggr_labels_str.append(future.result()) + + pool = multiprocessing.Pool() + aggr_labels_str = pool.map(self._binning_and_aggregating_one, params) + pool.close() + pool.join() + + log.info(f"Feature binning and aggregating finished, task_id: {self.ctx.task_id}, " + f"feature_num: {len(params)}, timecost: {time.time() - start_time}s") + return aggr_labels_str + + @staticmethod + def _binning_and_aggregating_one(param): + feature = param['feature'] + if param['is_continuous']: + bins = FeatureBinning.binning_continuous_feature( + feature, param['group_num'])[0] + else: + bins = FeatureBinning.binning_categorical_feature(feature)[0] + + enc_labels = param['enc_labels'] + data_dict = {} + for key, value in zip(bins, enc_labels): + if key in data_dict: + data_dict[key]['count'] += 1 + # 执行同态加法 + data_dict[key]['sum'] = data_dict[key]['sum'] + value + else: + data_dict[key] = {'count': 1, 'sum': value} + + count_list = [data_dict[key]['count'] + for key in sorted(data_dict.keys())] + aggr_enc_labels = [data_dict[key]['sum'] + for key in sorted(data_dict.keys())] + + return VerticalFeatureEngineeringPassiveParty._encode_enc_aggr_labels( + param['codec'], param['field'], count_list, aggr_enc_labels) + + @staticmethod + def _encode_enc_aggr_labels(codec, field, count_list, aggr_enc_labels): + enc_aggr_labels_pb = EncAggrLabels() + enc_aggr_labels_pb.field = field + for count in count_list: + enc_aggr_labels_pb.count_list.append(count) + for cipher in aggr_enc_labels: + model_cipher = ModelCipher() + model_cipher.ciphertext, model_cipher.exponent = \ + codec.encode_cipher(cipher, be_secure=False) + enc_aggr_labels_pb.cipher_list.append(model_cipher) + return utils.pb_to_bytes(enc_aggr_labels_pb) + + def _send_all_enc_aggr_labels(self, public_key, aggr_labels_bytes_list): + start_time = time.time() + enc_aggr_labels_list_pb = EncAggrLabelsList() + enc_aggr_labels_list_pb.public_key = self.ctx.codec.encode_enc_key( + public_key) + + for aggr_labels_bytes in aggr_labels_bytes_list: + enc_aggr_labels_pb = EncAggrLabels() + utils.bytes_to_pb(enc_aggr_labels_pb, aggr_labels_bytes) + enc_aggr_labels_list_pb.enc_aggr_labels_list.append( + enc_aggr_labels_pb) + + data = utils.pb_to_bytes(enc_aggr_labels_list_pb) + + self.ctx.components.logger().info( + f"Encoding all enc aggr labels finished, task_id: {self.ctx.task_id}, " + f"size: {len(data) / 1024}KB, timecost: {time.time() - start_time}s") + self.ctx.model_router.push(task_id=self.ctx.task_id, + task_type=FeMessage.AGGR_LABELS.value, + dst_agency=self.ctx.participant_id_list[0], + payload=data) + self.ctx.components.logger().info( + f"Sending all enc aggr labels finished, task_id: {self.ctx.task_id}, " + f"feature_num: {len(aggr_labels_bytes_list)}, " + f"size: {len(data) / 1024}KB, timecost: {time.time() - start_time}s") + + def _get_and_save_result(self): + active_party = self.ctx.participant_id_list[0] + if self.ctx.components.transport.self_agency_id in self.ctx.result_receiver_id_list: + # 保存来自标签方的woe/iv结果 + data = self.ctx.model_router.pop( + task_id=self.ctx.task_id, task_type=FeMessage.WOE_FILE.value, from_inst=active_party) + self.ctx.components.logger().info( + f"Result of woe/iv received, task_id: {self.ctx.task_id}, size: {len(data) / 1024}KB") + with open(self.ctx.woe_iv_file, 'wb') as f: + f.write(data) + self.ctx.components.storage_client.upload_file(self.ctx.woe_iv_file, + self.ctx.remote_woe_iv_file, + self.ctx.user) + + # 保存来自标签方的iv筛选结果 + data = self.ctx.model_router.pop( + task_id=self.ctx.task_id, task_type=FeMessage.IV_SELECTED_FILE.value, from_inst=active_party) + self.ctx.components.logger().info( + f"Result of iv_select received, task_id: {self.ctx.task_id}, size: {len(data) / 1024}KB") + with open(self.ctx.iv_selected_file, 'wb') as f: + f.write(data) diff --git a/python/ppc_model/feature_engineering/vertical/utils.py b/python/ppc_model/feature_engineering/vertical/utils.py new file mode 100644 index 00000000..32faa2fc --- /dev/null +++ b/python/ppc_model/feature_engineering/vertical/utils.py @@ -0,0 +1,78 @@ +import numpy as np +import pandas as pd + +from ppc_model.datasets.feature_binning.feature_binning import FeatureBinning + + +def is_continuous_feature(categorical: str, field): + if categorical == '0': + return True + return field not in categorical.split(',') + + +def calculate_woe_iv_with_pos_event(grouped): + grouped['neg_event'] = grouped['count'] - grouped['pos_event'] + + # 避免出现无穷大woe + grouped['pos_event'] = grouped['pos_event'].astype(np.float64) + grouped['neg_event'] = grouped['neg_event'].astype(np.float64) + grouped.loc[grouped['neg_event'] == 0, 'pos_event'] += 0.5 + grouped.loc[grouped['neg_event'] == 0, 'neg_event'] = 0.5 + grouped.loc[grouped['pos_event'] == 0, 'neg_event'] += 0.5 + grouped.loc[grouped['pos_event'] == 0, 'pos_event'] = 0.5 + + # 计算WOE和IV值 + grouped['pos_event_rate'] = grouped['pos_event'] / \ + (grouped['pos_event'].sum()) + grouped['neg_event_rate'] = grouped['neg_event'] / \ + (grouped['neg_event'].sum()) + grouped['woe'] = np.log(grouped['pos_event_rate'] / + (grouped['neg_event_rate'])) + grouped['iv'] = (grouped['pos_event_rate'] - + grouped['neg_event_rate']) * grouped['woe'] + iv_total = grouped['iv'].sum() + grouped['iv_total'] = iv_total + return grouped, iv_total + + +def calculate_woe_iv(feature: np.ndarray, label: np.ndarray, num_bins: int = 10, is_continuous: bool = True, + is_equal_freq: bool = True): + # 将特征和目标变量合并 + combined = pd.DataFrame({'feature': feature, 'label': label}) + # 按特征值对数据集进行分箱 + if is_continuous: + combined['bins'] = FeatureBinning.binning_continuous_feature( + feature, num_bins, is_equal_freq)[0] + else: + combined['bins'] = FeatureBinning.binning_categorical_feature(feature)[ + 0] + # 计算每个分箱中的正负样本数量和总体样本数量 + grouped = combined.groupby('bins')['label'].agg(['count', 'sum']) + grouped = grouped.rename(columns={'sum': 'pos_event'}) + + return calculate_woe_iv_with_pos_event(grouped) + + +def calculate_woe_iv_with_pos_event(grouped): + grouped['neg_event'] = grouped['count'] - grouped['pos_event'] + + # 避免出现无穷大woe + grouped['pos_event'] = grouped['pos_event'].astype(np.float64) + grouped['neg_event'] = grouped['neg_event'].astype(np.float64) + grouped.loc[grouped['neg_event'] == 0, 'pos_event'] += 0.5 + grouped.loc[grouped['neg_event'] == 0, 'neg_event'] = 0.5 + grouped.loc[grouped['pos_event'] == 0, 'neg_event'] += 0.5 + grouped.loc[grouped['pos_event'] == 0, 'pos_event'] = 0.5 + + # 计算WOE和IV值 + grouped['pos_event_rate'] = grouped['pos_event'] / \ + (grouped['pos_event'].sum()) + grouped['neg_event_rate'] = grouped['neg_event'] / \ + (grouped['neg_event'].sum()) + grouped['woe'] = np.log(grouped['pos_event_rate'] / + (grouped['neg_event_rate'])) + grouped['iv'] = (grouped['pos_event_rate'] - + grouped['neg_event_rate']) * grouped['woe'] + iv_total = grouped['iv'].sum() + grouped['iv_total'] = iv_total + return grouped, iv_total diff --git a/python/ppc_model/interface/__init__.py b/python/ppc_model/interface/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/python/ppc_model/interface/model_base.py b/python/ppc_model/interface/model_base.py new file mode 100644 index 00000000..6ff8c6a1 --- /dev/null +++ b/python/ppc_model/interface/model_base.py @@ -0,0 +1,56 @@ +from abc import ABC + +from pandas import DataFrame +from ppc_model.common.protocol import TaskRole + + +class ModelBase(ABC): + mode: str + + def __init__(self, ctx): + self.ctx = ctx + self.ctx.model_router = self.ctx.components.model_router + self.__handshake__() + + def __handshake__(self): + # handshake with all passive parties + for i in range(0, len(self.ctx.participant_id_list)): + participant = self.ctx.participant_id_list[i] + if participant == self.ctx.my_agency_id: + continue + self.ctx.components.logger().info( + f"Send handshake to party: {participant}") + self.ctx.model_router.handshake(self.ctx.task_id, participant) + + # wait for handshake response from the passive parties + self.ctx.components.logger().info( + f"Wait for handshake from all parities") + self.ctx.model_router.wait_for_handshake( + self.ctx.task_id, self.ctx.participant_id_list, self.ctx.my_agency_id) + + def fit( + self, + *args, + **kwargs + ) -> None: + pass + + def transform(self, transform_data: DataFrame) -> DataFrame: + pass + + def predict(self, predict_data: DataFrame) -> DataFrame: + pass + + def save_model(self, file_path): + pass + + def load_model(self, file_path): + pass + + +class VerticalModel(ModelBase): + mode = "VERTICAL" + + def __init__(self, ctx): + super().__init__(ctx) + self._all_feature_name = [] diff --git a/python/ppc_model/interface/rpc_client.py b/python/ppc_model/interface/rpc_client.py new file mode 100644 index 00000000..9473be6d --- /dev/null +++ b/python/ppc_model/interface/rpc_client.py @@ -0,0 +1,8 @@ +from abc import ABC + + +class RpcClient(ABC): + rpc_type: str + + def send(self, request): + ... diff --git a/python/ppc_model/interface/task_engine.py b/python/ppc_model/interface/task_engine.py new file mode 100644 index 00000000..0f55887d --- /dev/null +++ b/python/ppc_model/interface/task_engine.py @@ -0,0 +1,9 @@ +from abc import ABC + + +class TaskEngine(ABC): + task_type: str + + @staticmethod + def run(task_id: str, args: dict): + ... diff --git a/python/ppc_model/log/__init__.py b/python/ppc_model/log/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/python/ppc_model/log/log_retriever.py b/python/ppc_model/log/log_retriever.py new file mode 100644 index 00000000..70e2b67c --- /dev/null +++ b/python/ppc_model/log/log_retriever.py @@ -0,0 +1,97 @@ +# -*- coding: utf-8 -*- +import subprocess +import logging +from ppc_model.common.protocol import LOG_START_FLAG_FORMATTER, LOG_END_FLAG_FORMATTER +from ppc_common.deps_services.storage_api import StorageApi +from ppc_model.common.base_context import BaseContext +import os + + +class LogRetriever: + # max retrieve 500k + max_retrieved_log_size = 500 * 1024 + + def __init__(self, logger, job_cache_dir, storage_client: StorageApi, log_path): + self.logger = logger + self.job_cache_dir = job_cache_dir + self.storage_client = storage_client + self.relative_log_path = log_path + + def retrieve_log(self, job_id, user): + try: + ctx = BaseContext( + job_id=job_id, job_temp_dir=self.job_cache_dir, user=user) + # get the log size + log_size_byte = self.storage_client.get_data( + self._get_remote_log_size_path(ctx)) + log_size = int.from_bytes(log_size_byte, 'big') + remote_log_path = os.path.join( + self.storage_client.get_home_path(), self._get_remote_log_path(ctx)) + if log_size > LogRetriever.max_retrieved_log_size: + return (log_size, remote_log_path, None) + # get the log data + log_data = self.storage_client.get_data( + self._get_remote_log_path(ctx)).decode(encoding='utf-8') + return (log_size, remote_log_path, log_data) + except: + return (None, None, None) + + def _get_remote_log_path(self, ctx: BaseContext): + return ctx.remote_log_path + + def _get_remote_log_size_path(self, ctx: BaseContext): + return ctx.remote_log_size_path + + def _get_local_job_log_path(self, job_id): + return os.path.join(self.job_cache_dir, job_id, f'{job_id}.log') + + def upload_log(self, job_id, user): + ret = self._record_model_job_log(job_id) + if ret is False: + return + ctx = BaseContext( + job_id=job_id, job_temp_dir=self.job_cache_dir, user=user) + # the log size + log_size = os.path.getsize(self._get_local_job_log_path(job_id)) + # store the log size + self.storage_client.save_data(log_size.to_bytes((log_size.bit_length() + 7) // 8, 'big'), + self._get_remote_log_size_path(ctx)) + # store the log path + self.storage_client.upload_file(self._get_local_job_log_path( + job_id), self._get_remote_log_path(ctx), user) + + def _make_local_log_dir(self, job_id): + local_log_path = self._get_local_job_log_path(job_id) + if os.path.exists(local_log_path): + return + parent_dir = os.path.dirname(local_log_path) + if os.path.exists(parent_dir): + return + os.makedirs(parent_dir) + + def _record_model_job_log(self, job_id): + log_file = self._get_log_file_path() + if log_file is None or log_file == "": + current_working_dir = os.getcwd() + log_file = os.path.join( + current_working_dir, self.relative_log_path) + start_keyword = LOG_START_FLAG_FORMATTER.format(job_id=job_id) + end_keyword = LOG_END_FLAG_FORMATTER.format(job_id=job_id) + self._make_local_log_dir(job_id) + + command = f"grep -i {job_id} {log_file} > {self._get_local_job_log_path(job_id)}" + result = subprocess.run( + command, shell=True, text=True, capture_output=True) + if result.stderr: + self.logger.warn( + f"record_model_job_log for job {job_id} failed, error: {result.stderr}") + return False + return True + + def _get_log_file_path(self): + log_file_path = None + for handler in self.logger.handlers: + if isinstance(handler, logging.FileHandler): + log_file_path = handler.baseFilename + break + return log_file_path diff --git a/python/ppc_model/metrics/__init__.py b/python/ppc_model/metrics/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/python/ppc_model/metrics/evaluation.py b/python/ppc_model/metrics/evaluation.py new file mode 100644 index 00000000..011a1ae7 --- /dev/null +++ b/python/ppc_model/metrics/evaluation.py @@ -0,0 +1,293 @@ +import gc +import time +import random +import traceback +import numpy as np +import pandas as pd +import matplotlib.pyplot as plt +from typing import Dict, Union, Tuple +from sklearn import metrics +from sklearn.metrics import accuracy_score +from sklearn.metrics import precision_recall_curve +from sklearn.metrics import roc_curve, auc + +from ppc_model.common.context import Context +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 +from ppc_model.secure_lgbm.monitor.feature.feature_evaluation_info import FeatureEvaluationResult + + +_Score = Union[float, Tuple[float, float]] + + +class Evaluation: + + def __init__(self, + ctx: Context, + dataset: SecureDataset, + train_praba: np.ndarray = None, + test_praba: np.ndarray = None) -> None: + self.ctx = ctx + self.job_id = ctx.job_id + self.storage_client = ctx.components.storage_client + self.summary_evaluation_file = ctx.summary_evaluation_file + self.remote_summary_evaluation_file = ctx.remote_summary_evaluation_file + self.model_result_file = ctx.test_model_result_file + self.model_output_file = ctx.test_model_output_file + self.remote_model_output_file = ctx.remote_test_model_output_file + + self.metric_roc_file = ctx.test_metric_roc_file + self.metric_ks_file = ctx.test_metric_ks_file + self.metric_pr_file = ctx.test_metric_pr_file + self.metric_acc_file = ctx.test_metric_acc_file + self.metric_ks_table = ctx.test_metric_ks_table + self.remote_metric_roc_file = ctx.remote_test_metric_roc_file + self.remote_metric_ks_file = ctx.remote_test_metric_ks_file + self.remote_metric_pr_file = ctx.remote_test_metric_pr_file + self.remote_metric_acc_file = ctx.remote_test_metric_acc_file + self.remote_metric_ks_table = ctx.remote_test_metric_ks_table + + # if test_praba is None or dataset.test_y is None: + # raise Exception('test_praba or test_y is None') + + if test_praba is not None: + test_ks, test_auc = self.evaluation_file( + ctx, dataset.test_idx, dataset.test_y, test_praba, 'test') + if train_praba is not None: + train_ks, train_auc = self.evaluation_file( + ctx, dataset.train_idx, dataset.train_y, train_praba, 'train') + if dataset.train_y is not None: + self.summary_evaluation( + dataset, test_ks, test_auc, train_ks, train_auc) + + @staticmethod + def fevaluation( + y_true: np.ndarray, + y_pred: np.ndarray, + decimal_num: int = 4 + ) -> Dict[str, _Score]: + auc = metrics.roc_auc_score(y_true, y_pred) + + y_pred_label = [0 if p <= 0.5 else 1 for p in y_pred] + acc = metrics.accuracy_score(y_true, y_pred_label) + recall = metrics.recall_score(y_true, y_pred_label) + precision = metrics.precision_score(y_true, y_pred_label) + + scores_dict = { + 'auc': auc, + 'acc': acc, + 'recall': recall, + 'precision': precision + } + for metric_name in scores_dict: + scores_dict[metric_name] = round( + scores_dict[metric_name], decimal_num) + return scores_dict + + def summary_evaluation(self, dataset, test_ks, test_auc, train_ks, train_auc): + train_evaluation = FeatureEvaluationResult( + type=EvaluationType.TRAIN, ks_value=train_ks, auc_value=train_auc, label_list=dataset.train_y) + test_evaluation = FeatureEvaluationResult( + type=EvaluationType.VALIDATION, ks_value=test_ks, auc_value=test_auc, label_list=dataset.test_y) + FeatureEvaluationResult.store_and_upload_summary( + [train_evaluation, test_evaluation], + self.summary_evaluation_file, self.remote_summary_evaluation_file, + self.storage_client, self.ctx.user) + + @staticmethod + def calculate_ks_and_stats(predicted_proba, actual_label, num_buckets=10): + # 合并预测概率和实际标签为一个 DataFrame + df = pd.DataFrame({'predicted_proba': predicted_proba.reshape(-1), + 'actual_label': actual_label.reshape(-1)}) + # 根据预测概率降序排列 + df_sorted = df.sort_values(by='predicted_proba', ascending=False) + # 将数据划分为 num_buckets 个分组 + try: + df_sorted['bucket'] = pd.qcut( + df_sorted['predicted_proba'], num_buckets, retbins=True, labels=False)[0] + except Exception: + df_sorted['bucket'] = pd.cut( + df_sorted['predicted_proba'], num_buckets, retbins=True, labels=False)[0] + # 统计每个分组的信息 + stats = df_sorted.groupby('bucket').agg({ + 'actual_label': ['count', 'sum'], + 'predicted_proba': ['min', 'max'] + }) + # 计算其他指标 + stats.columns = ['count', 'positive_count', + 'predict_proba_min', 'predict_proba_max'] + stats['positive_ratio'] = stats['positive_count'] / stats['count'] + stats['negative_ratio'] = 1 - stats['positive_ratio'] + stats['count_ratio'] = stats['count'] / stats['count'].sum() + # stats['累计坏客户占比'] = stats['坏客户数'].cumsum() / stats['坏客户数'].sum() + # 计算累计坏客户占比,从第 9 组开始计算 + stats['cum_positive_ratio'] = stats['positive_count'].iloc[::- + 1].cumsum()[::-1] / stats['positive_count'].sum() + stats = stats[['count_ratio', 'count', 'positive_count', + 'positive_ratio', 'negative_ratio', 'cum_positive_ratio']].reset_index() + stats.columns = ['分组', '样本占比', '样本数', + '正样本数', '正样本比例', '负样本比例', '累积正样本占比'] + return stats + + def evaluation_file(self, ctx, data_index: np.ndarray, + y_true: np.ndarray, y_praba: np.ndarray, label: str = 'test'): + if label == 'train': + self.model_result_file = ctx.train_model_result_file + self.model_output_file = ctx.train_model_output_file + self.remote_model_output_file = ctx.remote_train_model_output_file + + self.metric_roc_file = ctx.train_metric_roc_file + self.metric_ks_file = ctx.train_metric_ks_file + self.metric_pr_file = ctx.train_metric_pr_file + self.metric_acc_file = ctx.train_metric_acc_file + self.metric_ks_table = ctx.train_metric_ks_table + self.remote_metric_roc_file = ctx.remote_train_metric_roc_file + self.remote_metric_ks_file = ctx.remote_train_metric_ks_file + self.remote_metric_pr_file = ctx.remote_train_metric_pr_file + self.remote_metric_acc_file = ctx.remote_train_metric_acc_file + self.remote_metric_ks_table = ctx.remote_train_metric_ks_table + + if y_true is not None: + # metrics plot + max_retry = 3 + retry_num = 0 + while retry_num < max_retry: + retry_num += 1 + try: + with ctx.components.plot_lock: + ks_value, auc_value = Evaluation.plot_two_class_graph( + self, y_true, y_praba) + except: + ctx.components.logger().info( + f'y_true = {len(y_true)}, {y_true[0:2]}') + ctx.components.logger().info( + f'y_praba = {len(y_praba)}, {y_praba[0:2]}') + err = traceback.format_exc().replace('\n', ' ; error: ') + # ctx.components.logger().exception(err) + ctx.components.logger().info( + f'plot metrics in times-{retry_num} failed, traceback: {err}.') + time.sleep(random.uniform(0.1, 3)) + + ResultFileHandling._upload_file( + self.storage_client, self.metric_roc_file, self.remote_metric_roc_file, ctx.user) + ResultFileHandling._upload_file( + self.storage_client, self.metric_ks_file, self.remote_metric_ks_file, ctx.user) + ResultFileHandling._upload_file( + self.storage_client, self.metric_pr_file, self.remote_metric_pr_file, ctx.user) + ResultFileHandling._upload_file( + self.storage_client, self.metric_acc_file, self.remote_metric_acc_file, ctx.user) + + # ks table + ks_table = self.calculate_ks_and_stats(y_praba, y_true) + ks_table.to_csv(self.metric_ks_table, header=True, index=None) + ResultFileHandling._upload_file( + self.storage_client, self.metric_ks_table, self.remote_metric_ks_table, ctx.user) + else: + ks_value = auc_value = None + + # predict result + self._parse_model_result(data_index, y_true, y_praba) + ResultFileHandling._upload_file( + self.storage_client, self.model_output_file, self.remote_model_output_file, ctx.user) + + return ks_value, auc_value + + def _parse_model_result(self, data_index, y_true=None, y_praba=None): + + np.savetxt(self.model_result_file, y_praba, delimiter=',', fmt='%f') + + if y_true is None: + df = pd.DataFrame(np.column_stack( + (data_index, y_praba)), columns=['id', 'class_pred']) + else: + df = pd.DataFrame(np.column_stack((data_index, y_true, y_praba)), + columns=['id', 'class_label', 'class_pred']) + df['class_label'] = df['class_label'].astype(int) + + df['id'] = df['id'].astype(int) + df['class_pred'] = df['class_pred'].astype(float) + df = df.sort_values(by='id') + df.to_csv(self.model_output_file, index=None) + + def plot_two_class_graph(self, y_true, y_scores): + + y_label_probs = y_true + y_pred_probs = y_scores + # plt.cla() + plt.rcParams['figure.figsize'] = (12.0, 8.0) + + # plot ROC + fpr, tpr, thresholds = roc_curve( + y_label_probs, y_pred_probs, pos_label=1) + auc_value = auc(fpr, tpr) + plt.figure(f'roc-{self.job_id}') + plt.title('ROC Curve') # give plot a title + plt.xlabel('False Positive Rate (1 - Specificity)') + plt.ylabel('True Positive Rate (Sensitivity)') + plt.plot([0, 1], [0, 1], 'k--', lw=2) + plt.plot(fpr, tpr, label='area = {0:0.5f}' + ''.format(auc_value)) + plt.legend(loc="lower right") + plt.savefig(self.metric_roc_file, dpi=1000) + # plt.show() + + plt.close('all') + gc.collect() + + # plot KS + plt.figure(f'ks-{self.job_id}') + threshold_x = np.sort(thresholds) + threshold_x[-1] = 1 + ks_value = max(abs(fpr - tpr)) + plt.title('KS Curve') + plt.xlabel('Threshold') + plt.plot(threshold_x, tpr, label='True Positive Rate') + plt.plot(threshold_x, fpr, label='False Positive Rate') + # 标记最大ks值 + x_index = np.argwhere(abs(fpr - tpr) == ks_value)[0, 0] + plt.plot((threshold_x[x_index], threshold_x[x_index]), (fpr[x_index], tpr[x_index]), + label='ks = {:.3f}'.format(ks_value), color='r', marker='o', markerfacecolor='r', markersize=5) + plt.legend(loc="lower right") + plt.savefig(self.metric_ks_file, dpi=1000) + # plt.show() + + plt.close('all') + gc.collect() + + # plot Precision Recall + plt.figure(f'pr-{self.job_id}') + plt.title('Precision/Recall Curve') + plt.xlabel('Recall') + plt.ylabel('Precision') + plt.xlim(0.0, 1.0) + plt.ylim(0.0, 1.05) + precision, recall, thresholds = precision_recall_curve( + y_label_probs, y_pred_probs) + plt.plot(recall, precision) + plt.savefig(self.metric_pr_file, dpi=1000) + # plt.show() + + plt.close('all') + gc.collect() + + # plot accuracy + plt.figure(f'accuracy-{self.job_id}') + thresholds = np.linspace(0, 1, num=100) # 在0~1之间生成100个阈值 + accuracies = [] + for threshold in thresholds: + predicted_labels = (y_pred_probs >= threshold).astype(int) + accuracy = accuracy_score(y_label_probs, predicted_labels) + accuracies.append(accuracy) + plt.title('Accuracy Curve') + plt.xlabel('Threshold') + plt.ylabel('Accuracy') + plt.xlim(0.0, 1.0) + plt.ylim(0.0, 1.05) + plt.plot(thresholds, accuracies) + plt.savefig(self.metric_acc_file, dpi=1000) + # plt.show() + + plt.close('all') + gc.collect() + return (ks_value, auc_value) diff --git a/python/ppc_model/metrics/loss.py b/python/ppc_model/metrics/loss.py new file mode 100644 index 00000000..817d4f7c --- /dev/null +++ b/python/ppc_model/metrics/loss.py @@ -0,0 +1,48 @@ +import numpy as np + + +class Loss: + pass + + +class BinaryLoss(Loss): + + def __init__(self, objective: str = None) -> None: + super().__init__() + self.objective = objective + + @staticmethod + def sigmoid(x: np.ndarray): + return 1 / (1 + np.exp(-x)) + + @staticmethod + def compute_gradient(y_true: np.ndarray, y_pred: np.ndarray): + return y_pred - y_true + + @staticmethod + def compute_hessian(y_pred: np.ndarray): + return y_pred * (1 - y_pred) + + @staticmethod + def compute_loss(y_true: np.ndarray, y_pred: np.ndarray): + '''binary_cross_entropy''' + # 避免log(0)错误 + epsilon = 1e-15 + y_pred = np.clip(y_pred, epsilon, 1 - epsilon) + return -np.mean(y_true * np.log(y_pred) + (1 - y_true) * np.log(1 - y_pred)) + + @staticmethod + def dot_product(x, theta): + if x.ndim == 1: + x.reshape(1, len(x)) + if theta.ndim == 1: + theta.reshape(len(theta), 1) + g = np.matmul(x, theta) + return g + + @staticmethod + def inference(g): + # h = np.divide(np.exp(g), np.exp(g) + 1) + # 近似 + h = 0.125 * g + return h diff --git a/python/ppc_model/metrics/model_plot.py b/python/ppc_model/metrics/model_plot.py new file mode 100644 index 00000000..f3996275 --- /dev/null +++ b/python/ppc_model/metrics/model_plot.py @@ -0,0 +1,195 @@ +import gc +import time +import random +import traceback +import matplotlib.pyplot as plt +import networkx as nx +from networkx.drawing.nx_pydot import graphviz_layout + +from ppc_model.common.model_result import ResultFileHandling +from ppc_model.secure_lgbm.vertical.booster import VerticalBooster + + +class ModelPlot: + + def __init__(self, model: VerticalBooster) -> None: + + self.ctx = model.ctx + self.model = model + self._tree_id = 0 + self._leaf_id = None + self._G = None + self._split = None + self.storage_client = self.ctx.components.storage_client + + if model._trees is not None and \ + self.ctx.components.config_data['AGENCY_ID'] in self.ctx.result_receiver_id_list: + self.plot_tree() + + def plot_tree(self): + trees = self.model._trees + self._split = self.model._X_split + + for i, tree in enumerate(trees): + if i < 6: + tree_file_path = self.ctx.model_tree_prefix + \ + '_' + str(self._tree_id)+'.svg' + remote_tree_file_path = self.ctx.remote_model_tree_prefix + \ + '_' + str(self._tree_id)+'.svg' + self._tree_id += 1 + self._leaf_id = 0 + self._G = DiGraphTree() + if not isinstance(tree, list) or tree == 0: + continue + else: + self._graph_gtree(tree) + + max_retry = 3 + retry_num = 0 + while retry_num < max_retry: + retry_num += 1 + try: + with self.ctx.components.plot_lock: + self._G.tree_plot( + figsize=(10, 5), save_filename=tree_file_path) + except: + self.ctx.components.logger().info( + f'tree_id = {i}, tree = {tree}') + self.ctx.components.logger().info(f'G = {self._G}') + err = traceback.format_exc().replace('\n', ' ; error: ') + # self.ctx.components.logger().exception(err) + self.ctx.components.logger().info( + f'plot tree-{i} in times-{retry_num} failed, traceback: {err}.') + time.sleep(random.uniform(0.1, 3)) + + ResultFileHandling._upload_file( + self.storage_client, tree_file_path, + remote_tree_file_path, self.ctx.user) + + def _graph_gtree(self, tree, leaf_id=0, depth=0, orient=None, split_info=None): + self._leaf_id += 1 + self._G.add_node(self._leaf_id) + if split_info is not None: + if self.ctx.participant_id_list[split_info.agency_idx] == self.ctx.components.config_data['AGENCY_ID']: + feature = str( + self.model.dataset.feature_name[split_info.agency_feature]) + value = str( + round(float(self._split[split_info.agency_feature][split_info.value]), 4)) + else: + feature = str(split_info.feature) + value = str(split_info.value) + else: + feature = value = '' + + if isinstance(tree, list): + best_split_info, left_tree, right_tree = tree[0] + if leaf_id != 0: + if orient == 'left': + self._G.add_weighted_edges_from( + [(leaf_id, self._leaf_id, orient+'_'+feature+'_'+value+'_'+str(split_info.w_left))]) + elif orient == 'right': + self._G.add_weighted_edges_from( + [(leaf_id, self._leaf_id, orient+'_'+feature+'_'+value+'_'+str(split_info.w_right))]) + my_leaf_id = self._leaf_id + self._graph_gtree(left_tree, my_leaf_id, depth + + 1, 'left', best_split_info) + self._graph_gtree(right_tree, my_leaf_id, depth + + 1, 'right', best_split_info) + else: + if leaf_id != 0: + self._G.add_weighted_edges_from( + [(leaf_id, self._leaf_id, orient+'_'+feature+'_'+value+'_'+str(tree))]) + + +class DiGraphTree(nx.DiGraph): + + def __init__(self): + + super().__init__() + + def tree_leaves(self): + leaves_list = [x for x in self.nodes() if self.out_degree( + x) == 0 and self.in_degree(x) <= 1] + return leaves_list + + def tree_dfs_nodes(self): + nodes_list = list(nx.dfs_preorder_nodes(self)) + return nodes_list + + def tree_dfs_leaves(self): + dfs_leaves = [x for x in self.tree_dfs_nodes() + if x in self.tree_leaves()] + return dfs_leaves + + def tree_depth(self): + max_depth = max(nx.shortest_path_length(self, 0).values()) + return max_depth + + def tree_shortest_path(self, node0, node1): + path_length = nx.shortest_path_length(self, node0, node1) + return path_length + + def tree_plot(self, split=True, figsize=(20, 10), dpi=300, save_filename=None): + # plt.cla() + pos = graphviz_layout(self, prog='dot') + # pos = nx.nx_agraph.graphviz_layout(self, prog='dot') + edge_labels = nx.get_edge_attributes(self, 'weight') + + if split: + labels = {} + # leaves = self.tree_leaves() + leaves = [x for x in self.nodes() if self.out_degree(x) == + 0 and self.in_degree(x) <= 1] + + if leaves == [0]: + leaves = [] + self.remove_node(0) + + for n in self.nodes(): + + if n in leaves: + # in_node = list(nx.all_neighbors(self, n))[0] + in_node = list(self.predecessors(n))[0] + weight = edge_labels[(in_node, n)] + try: + labels[n] = round(float(str(weight).split('_')[3]), 4) + except: + labels[n] = str(weight).split('_')[3] + else: + in_node = list(nx.neighbors(self, n))[0] + weight = edge_labels[(n, in_node)] + labels[n] = weight.split( + '_')[1] + ':' + weight.split('_')[2] + + # for key, value in edge_labels.items(): + # edge_labels[key] = round(float(value.split('_')[3]), 4) + + plt.figure(figsize=figsize, dpi=dpi) + nx.draw(self, pos, + node_size=1000, node_color='#72BFC5', node_shape='o', alpha=None, + with_labels=True, labels=labels, font_weight='normal', font_color='black') + # nx.draw_networkx_edge_labels(self, pos, edge_labels=edge_labels) + # plt.show() + if save_filename is not None: + plt.savefig(save_filename) + else: + plt.show() + + else: + labels = {n: n for n in self.nodes()} + for key, value in edge_labels.items(): + edge_labels[key] = value.split('_')[1] + '-' + value.split('_')[2] + \ + '-' + str(round(float(value.split('_')[3]), 4)) + + plt.figure(figsize=figsize, dpi=dpi) + nx.draw(self, pos, with_labels=True, + labels=labels, font_weight='bold') + nx.draw_networkx_edge_labels(self, pos, edge_labels=edge_labels) + # plt.show() + if save_filename is not None: + plt.savefig(save_filename) + else: + plt.show() + + plt.close('all') + gc.collect() diff --git a/python/ppc_model/metrics/test/__init__.py b/python/ppc_model/metrics/test/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/python/ppc_model/metrics/test/test_metrics.py b/python/ppc_model/metrics/test/test_metrics.py new file mode 100644 index 00000000..76a2d92a --- /dev/null +++ b/python/ppc_model/metrics/test/test_metrics.py @@ -0,0 +1,170 @@ +import os +import unittest +import numpy as np + +from ppc_model.common.initializer import Initializer +from ppc_common.ppc_mock.mock_objects import MockLogger +from ppc_model.datasets.dataset import SecureDataset +from ppc_model.metrics.evaluation import Evaluation +from ppc_model.metrics.model_plot import ModelPlot, DiGraphTree +from ppc_model.common.model_result import ResultFileHandling +from ppc_model.secure_lgbm.secure_lgbm_context import SecureLGBMContext +from ppc_model.secure_lgbm.vertical import VerticalLGBMActiveParty, VerticalLGBMPassiveParty + + +ACTIVE_PARTY = 'ACTIVE_PARTY' +PASSIVE_PARTY = 'PASSIVE_PARTY' + +data_size = 1000 +feature_dim = 20 + + +def mock_args(): + job_id = 'j-111' + task_id = 't-111' + + model_dict = { + 'objective': 'regression', + 'categorical_feature': [], + 'max_bin': 10, + 'n_estimators': 2, + 'max_depth': 3, + 'use_goss': 1, + 'feature_rate': 0.8, + 'random_state': 2024 + } + + args_a = { + 'job_id': job_id, + 'task_id': task_id, + 'is_label_holder': True, + 'result_receiver_id_list': [ACTIVE_PARTY, PASSIVE_PARTY], + 'participant_id_list': [ACTIVE_PARTY, PASSIVE_PARTY], + 'model_predict_algorithm': None, + 'algorithm_type': 'Train', + 'algorithm_subtype': 'HeteroXGB', + 'model_dict': model_dict + } + + args_b = { + 'job_id': job_id, + 'task_id': task_id, + 'is_label_holder': False, + 'result_receiver_id_list': [ACTIVE_PARTY, PASSIVE_PARTY], + 'participant_id_list': [ACTIVE_PARTY, PASSIVE_PARTY], + 'model_predict_algorithm': None, + 'algorithm_type': 'Train', + 'algorithm_subtype': 'HeteroXGB', + 'model_dict': model_dict + } + + return args_a, args_b + + +class TestXgboostTraining(unittest.TestCase): + + args_a, args_b = mock_args() + + def test_active_metrics(self): + + active_components = Initializer(log_config_path='', config_path='') + active_components.config_data = { + 'JOB_TEMP_DIR': '/tmp/active', 'AGENCY_ID': ACTIVE_PARTY} + active_components.mock_logger = MockLogger() + task_info_a = SecureLGBMContext(self.args_a['task_id'], self.args_a, active_components) + model_data = SecureDataset.simulate_dataset( + data_size, feature_dim, has_label=True) + secure_dataset_a = SecureDataset(task_info_a, model_data) + booster_a = VerticalLGBMActiveParty(task_info_a, secure_dataset_a) + print(secure_dataset_a.feature_name) + print(secure_dataset_a.train_idx.shape) + print(secure_dataset_a.train_X.shape) + print(secure_dataset_a.train_y.shape) + print(secure_dataset_a.test_idx.shape) + print(secure_dataset_a.test_X.shape) + print(secure_dataset_a.test_y.shape) + + # booster_a._train_praba = np.random.rand(len(secure_dataset_a.train_y)) + booster_a._test_praba = np.random.rand(len(secure_dataset_a.test_y)) + + Evaluation(task_info_a, secure_dataset_a, + booster_a._train_praba, booster_a._test_praba) + + def test_passive_metrics(self): + + passive_components = Initializer(log_config_path='', config_path='') + passive_components.config_data = { + 'JOB_TEMP_DIR': '/tmp/passive', 'AGENCY_ID': PASSIVE_PARTY} + passive_components.mock_logger = MockLogger() + task_info_b = SecureLGBMContext(self.args_b['task_id'], self.args_b, passive_components) + model_data = SecureDataset.simulate_dataset( + data_size, feature_dim, has_label=False) + secure_dataset_b = SecureDataset(task_info_b, model_data) + booster_b = VerticalLGBMPassiveParty(task_info_b, secure_dataset_b) + print(secure_dataset_b.feature_name) + print(secure_dataset_b.train_idx.shape) + print(secure_dataset_b.train_X.shape) + print(secure_dataset_b.test_idx.shape) + print(secure_dataset_b.test_X.shape) + + # booster_b._train_praba = np.random.rand(len(secure_dataset_b.train_idx)) + booster_b._test_praba = np.random.rand(len(secure_dataset_b.test_idx)) + + Evaluation(task_info_b, secure_dataset_b, + booster_b._train_praba, booster_b._test_praba) + + def test_model_plot(self): + + active_components = Initializer(log_config_path='', config_path='') + active_components.config_data = { + 'JOB_TEMP_DIR': '/tmp/active', 'AGENCY_ID': ACTIVE_PARTY} + active_components.mock_logger = MockLogger() + task_info_a = SecureLGBMContext(self.args_a['task_id'], self.args_a, active_components) + model_data = SecureDataset.simulate_dataset( + data_size, feature_dim, has_label=True) + secure_dataset_a = SecureDataset(task_info_a, model_data) + booster_a = VerticalLGBMActiveParty(task_info_a, secure_dataset_a) + if os.path.exists(booster_a.ctx.model_data_file): + booster_a.load_model() + ModelPlot(booster_a) + + def test_digraphtree(self): + Gtree = DiGraphTree() + Gtree.add_node(0) + Gtree.add_nodes_from([1, 2]) + Gtree.add_weighted_edges_from( + [(0, 1, 'left_'+str(2)+'_'+str(3)+'_'+str(0.5)), + (0, 2, 'right_'+str(2)+'_'+str(3)+'_'+str(0.9))]) + Gtree.add_nodes_from([3, 4]) + Gtree.add_weighted_edges_from( + [(1, 3, 'left_'+str(20)+'_'+str(4)+'_'+str(0.5)), + (1, 4, 'right_'+str(20)+'_'+str(4)+'_'+str(0.9))]) + Gtree.add_nodes_from([5, 6]) + Gtree.add_weighted_edges_from( + [(2, 5, 'left_'+str(2)+'_'+str(7)+'_'+str(0.5)), + (2, 6, 'right_'+str(2)+'_'+str(7)+'_'+str(0.9))]) + Gtree.add_nodes_from([7, 8]) + Gtree.add_weighted_edges_from( + [(3, 7, 'left_'+str(1)+'_'+str(11)+'_'+str(0.5)), + (3, 8, 'right_'+str(1)+'_'+str(11)+'_'+str(0.9))]) + Gtree.add_nodes_from([9, 10]) + Gtree.add_weighted_edges_from( + [(4, 9, 'left_'+str(18)+'_'+str(2)+'_'+str(0.5)), + (4, 10, 'right_'+str(18)+'_'+str(2)+'_'+str(0.9))]) + Gtree.add_nodes_from([11, 12]) + Gtree.add_weighted_edges_from( + [(5, 11, 'left_'+str(23)+'_'+str(25)+'_'+str(0.5)), + (5, 12, 'right_'+str(23)+'_'+str(25)+'_'+str(0.9))]) + Gtree.add_nodes_from([13, 14]) + Gtree.add_weighted_edges_from( + [(6, 13, 'left_'+str(16)+'_'+str(10)+'_'+str(0.5)), + (6, 14, 'right_'+str(16)+'_'+str(10)+'_'+str(0.9))]) + + # Gtree.tree_plot() + # Gtree.tree_plot(split=False, figsize=(10, 5)) + # Gtree.tree_plot(figsize=(6, 3)) + Gtree.tree_plot(figsize=(10, 5), save_filename='tree.svg') + + +if __name__ == '__main__': + unittest.main() diff --git a/python/ppc_model/model_crypto/__init__.py b/python/ppc_model/model_crypto/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/python/ppc_model/model_crypto/crypto_aes.py b/python/ppc_model/model_crypto/crypto_aes.py new file mode 100644 index 00000000..df0e6f40 --- /dev/null +++ b/python/ppc_model/model_crypto/crypto_aes.py @@ -0,0 +1,79 @@ +import os +import base64 + +from cryptography.hazmat.backends import default_backend +from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes +from cryptography.hazmat.primitives import padding + + +# 生成256位(32字节)的AES密钥 +def generate_aes_key(): + return os.urandom(32) # 32 bytes == 256 bits + + +# 将密钥保存到文件 +def save_key_to_file(key, filename): + with open(filename, 'wb') as file: + file.write(key) + + +# 从文件中加载密钥 +def load_key_from_file(filename): + with open(filename, 'rb') as file: + key = file.read() + return key + +# AES加密函数 + + +def encrypt_data(key, plaintext): + # 使用随机生成的初始向量 (IV) + iv = os.urandom(16) # AES块大小为128位(16字节) + + # 创建AES加密器 + cipher = Cipher(algorithms.AES(key), modes.CBC(iv), + backend=default_backend()) + encryptor = cipher.encryptor() + + # 对数据进行填充(AES要求输入的块大小为128位) + padder = padding.PKCS7(128).padder() + padded_data = padder.update(plaintext) + padder.finalize() + + # 加密数据 + ciphertext = encryptor.update(padded_data) + encryptor.finalize() + + # 返回IV和密文 + return iv + ciphertext + + +# AES解密函数 +def decrypt_data(key, ciphertext): + # 提取IV和密文 + iv = ciphertext[:16] # 前16字节是IV + actual_ciphertext = ciphertext[16:] + + # 创建AES解密器 + cipher = Cipher(algorithms.AES(key), modes.CBC(iv), + backend=default_backend()) + decryptor = cipher.decryptor() + + # 解密数据 + decrypted_padded_data = decryptor.update( + actual_ciphertext) + decryptor.finalize() + + # 去除填充 + unpadder = padding.PKCS7(128).unpadder() + plaintext = unpadder.update(decrypted_padded_data) + unpadder.finalize() + + return plaintext + + +def cipher_to_base64(ciphertext): + # 将bytes类型转换为Base64字符串 + encoded_ciphertext = base64.b64encode(ciphertext).decode('utf-8') + return encoded_ciphertext + + +def base64_to_cipher(data): + decoded_ciphertext = base64.b64decode(data) + return decoded_ciphertext diff --git a/python/ppc_model/model_crypto/test_aes.py b/python/ppc_model/model_crypto/test_aes.py new file mode 100644 index 00000000..802ee54e --- /dev/null +++ b/python/ppc_model/model_crypto/test_aes.py @@ -0,0 +1,26 @@ +from ppc_model.model_crypto.crypto_aes import generate_aes_key, save_key_to_file +from ppc_model.model_crypto.crypto_aes import encrypt_data, decrypt_data +from ppc_model.model_crypto.crypto_aes import base64_to_cipher, cipher_to_base64 + + +key = generate_aes_key() +save_key_to_file(key, 'aes_key.bin') +print("AES密钥已生成并保存到aes_key.bin文件中。") + +plaintext = "需要加密的内容".encode('utf-8') +ciphertext = encrypt_data(key, plaintext) +print(f"加密后的内容: {ciphertext}") + +decrypted_text = decrypt_data(key, ciphertext) +print(f"解密后的内容: {decrypted_text.decode('utf-8')}") + +# 保存密文到文件 +# ciphertext = encrypt_data(key, plaintext) +encoded_ciphertext = cipher_to_base64(ciphertext) +print(f"encoded_ciphertext: {encoded_ciphertext}") + +# 使用AES密钥解密 +decoded_ciphertext = base64_to_cipher(encoded_ciphertext) +print(f"encoded_ciphertext: {decoded_ciphertext}") +decrypted_text = decrypt_data(key, decoded_ciphertext) +print(f"解密后的内容字符串: {decrypted_text.decode('utf-8')}") diff --git a/python/ppc_model/model_result/task_result_handler.py b/python/ppc_model/model_result/task_result_handler.py new file mode 100644 index 00000000..70f99a6e --- /dev/null +++ b/python/ppc_model/model_result/task_result_handler.py @@ -0,0 +1,441 @@ +# -*- coding: utf-8 -*- +from ppc_common.ppc_utils.utils import PpcException, PpcErrorCode +from ppc_common.ppc_utils import utils +from ppc_model.common.protocol import ModelTask +from ppc_model.common.base_context import BaseContext +from ppc_common.ppc_ml.model.algorithm_info import ClassificationType +from ppc_model.common.model_result import ResultFileHandling +from ppc_common.ppc_ml.model.algorithm_info import EvaluationType +from ppc_model.common.initializer import Initializer +from enum import Enum + + +class TaskResultRequest: + def __init__(self, job_id, task_type, + fetch_log: bool, + fetch_result: bool, user): + self.job_id = job_id + self.task_type = task_type + self.fetch_log = fetch_log + self.fetch_result = fetch_result + self.user = user + + +class DataType(Enum): + TEXT = "str", + TABLE = "table", + IMAGE = "image" + + +class DataItem: + DEFAULT_NAME_PROPERTY = "metricsName" + DEFAULT_DATA_PROPERTY = "metricsData" + DEFAULT_TYPE_PROPERTY = "metricsType" + + def __init__(self, name, data, type, + name_property=DEFAULT_NAME_PROPERTY, + data_property=DEFAULT_DATA_PROPERTY, + type_property=DEFAULT_TYPE_PROPERTY): + self.name = name + self.data = data + self.type = type + self.name_property = name_property + self.data_property = data_property + self.type_property = type_property + + def to_dict(self): + return {self.name_property: self.name, + self.data_property: self.data, + self.type_property: self.type.name} + + +class ResultFileMeta: + def __init__(self, table_file_name, retrieve_lines=-1): + self.table_file_name = table_file_name + self.retrieve_lines = retrieve_lines + + +class JobEvaluationResult: + DEFAULT_TRAIN_EVALUATION_FILES = { + EvaluationType.ROC: utils.MPC_TRAIN_METRIC_ROC_FILE, + EvaluationType.PR: utils.MPC_TRAIN_METRIC_PR_FILE, + EvaluationType.KS: utils.MPC_TRAIN_METRIC_KS_FILE, + EvaluationType.ACCURACY: utils.MPC_TRAIN_METRIC_ACCURACY_FILE, + EvaluationType.CONFUSION_MATRIX: utils.MPC_TRAIN_METRIC_CONFUSION_MATRIX_FILE} + + DEFAULT_VALIDATION_EVALUATION_FILES = { + EvaluationType.ROC: utils.MPC_TRAIN_SET_METRIC_ROC_FILE, + EvaluationType.PR: utils.MPC_TRAIN_SET_METRIC_PR_FILE, + EvaluationType.KS: utils.MPC_TRAIN_SET_METRIC_KS_FILE, + EvaluationType.ACCURACY: utils.MPC_TRAIN_SET_METRIC_ACCURACY_FILE} + + DEFAULT_EVAL_EVALUATION_FILES = { + EvaluationType.ROC: utils.MPC_TRAIN_METRIC_ROC_FILE, + EvaluationType.PR: utils.MPC_TRAIN_METRIC_PR_FILE, + EvaluationType.KS: utils.MPC_TRAIN_METRIC_KS_FILE, + EvaluationType.ACCURACY: utils.MPC_TRAIN_METRIC_ACCURACY_FILE + } + + def __init__(self, property_name, classification_type, + ctx: BaseContext, + job_id, evaluation_files, components): + self.ctx = ctx + self.job_id = job_id + self.classification_type = classification_type + self.components = components + self.logger = self.components.logger() + self.classification_type = classification_type + self.property_name = property_name + self.evaluation_files = evaluation_files + self.evaluation_results = [] + try: + self._fetch_evaluation_result() + self._fetch_two_classifcation_evaluation_result() + self._fetch_multi_classifcation_evaluation_result() + except Exception as e: + pass + + def _fetch_evaluation_result(self): + self.logger.info( + f"fetch roc-evaluation from: {self.evaluation_files[EvaluationType.ROC]}") + self.evaluation_results.append(DataItem("ROC", ResultFileHandling.make_graph_data( + self.components, + self.ctx, + self.evaluation_files[EvaluationType.ROC]), + DataType.IMAGE)) + self.logger.info( + f"fetch pr-evaluation from: {self.evaluation_files[EvaluationType.PR]}") + self.evaluation_results.append(DataItem("Precision Recall", ResultFileHandling.make_graph_data( + self.components, + self.ctx, + self.evaluation_files[EvaluationType.PR]), DataType.IMAGE)) + + def _fetch_two_classifcation_evaluation_result(self): + if self.classification_type is not ClassificationType.TWO: + return + + self.logger.info( + f"fetch ks-evaluation from: {self.evaluation_files[EvaluationType.KS]}") + self.evaluation_results.append(DataItem("K-S", ResultFileHandling.make_graph_data( + self.components, + self.ctx, + self.evaluation_files[EvaluationType.KS]), + DataType.IMAGE)) + + self.logger.info( + f"fetch accuracy-evaluation from: {self.evaluation_files[EvaluationType.ACCURACY]}") + self.evaluation_results.append(DataItem("Accuracy", + ResultFileHandling.make_graph_data( + self.components, + self.ctx, + self.evaluation_files[EvaluationType.ACCURACY]), + DataType.IMAGE)) + + def _fetch_multi_classifcation_evaluation_result(self): + if self.classification_type is not ClassificationType.MULTI: + return + self.logger.info( + f"fetch confusion-matrix-evaluation from: {self.evaluation_files[EvaluationType.CONFUSION_MATRIX]}") + self.evaluation_results.append(DataItem("Confusion Matrix", + ResultFileHandling.make_graph_data(self.components, + self.ctx, + self.evaluation_files[EvaluationType.CONFUSION_MATRIX]), + DataType.IMAGE)) + + def load_ks_table(self, ks_table_file, ks_table_property): + ks_table_object = TableResult(ctx=self.ctx, + components=self.components, + job_id=self.job_id, + file_meta=ResultFileMeta(table_file_name=ks_table_file)) + self.ks_table = ks_table_object.to_dict() + self.ks_table_property = ks_table_property + + def to_dict(self): + evaluation_result_list = [] + for evaluation in self.evaluation_results: + evaluation_result_list.append(evaluation.to_dict()) + result = {self.property_name: evaluation_result_list} + if self.ks_table is not None: + result.update({self.ks_table_property: self.ks_table}) + return result + + +class TableResult: + def __init__(self, ctx: BaseContext, components, job_id, file_meta): + self.ctx = ctx + self.components = components + self.job_id = job_id + self.file_meta = file_meta + + def to_dict(self): + try: + df = ResultFileHandling.make_csv_data(self.components, self.ctx, + self.file_meta.table_file_name) + csv_columns = list(df.columns) + + if self.file_meta.retrieve_lines == -1 or df.shape[0] <= self.file_meta.retrieve_lines: + csv_data = df.values.tolist() + else: + csv_data = df.iloc[:self.file_meta.retrieve_lines].values.tolist( + ) + return {'columns': csv_columns, 'data': csv_data} + except Exception as e: + pass + + +class FeatureProcessingResult: + DEFAULT_FEATURE_PROCESSING_FILES = { + "PRPreview": ResultFileMeta("xgb_result_column_info_selected.csv"), + "FEPreview": ResultFileMeta("woe_iv.csv", 5)} + + def __init__(self, ctx: BaseContext, components, job_id, file_infos): + self.ctx = ctx + self.components = components + self.job_id = job_id + self.file_infos = file_infos + self.result = dict() + self._fetch_result() + + def _fetch_result(self): + for property in self.file_infos.keys(): + table_info = TableResult(self.ctx, self.components, + self.job_id, self.file_infos[property]).to_dict() + self.result.update({property: table_info}) + + def to_dict(self): + return self.result + + +class ModelJobResult: + DEFAULT_PROPERTY_NAME = "outputModelResult" + MODEL_RESULT = "ModelResult" + MODEL_RESULT_PATH = "modelResultPath" + TRAIN_RESULT_PATH = "trainResultPath" + TEST_RESULT_PATH = "testResultPath" + WOE_RESULT_PATH = "woeIVResultPath" + + def __init__(self, ctx: BaseContext, xgb_job, job_id, components, property_name=DEFAULT_PROPERTY_NAME): + self.job_id = job_id + self.ctx = ctx + self.xgb_job = xgb_job + self.components = components + self.logger = components.logger() + self.property_name = property_name + self.model_result_list = None + self.job_result = None + self.model_result_path = None + self.train_result_path = None + self.woe_iv_result_path = None + self.model_result_path_dict = None + self.evaluation_table = None + self.feature_importance_table = None + self.iteration_metrics = None + + def fetch_xgb_model_result(self): + if not self.xgb_job: + return + self.model_result_list = [] + i = 0 + # while True: + while i < 6: + try: + tree_data = DataItem(data=ResultFileHandling.make_graph_data(self.components, + self.ctx, + utils.XGB_TREE_PERFIX + '_' + str(i) + '.svg'), + name='tree-' + str(i), name_property="ModelPlotName", data_property="ModelPlotData", + type=DataType.IMAGE) + self.model_result_list.append(tree_data.to_dict()) + i += 1 + except Exception: + break + + def load_result(self, result_path, result_property): + self.result_property = result_property + job_result_object = TableResult(self.ctx, self.components, + self.job_id, ResultFileMeta(result_path, 5)) + self.job_result = job_result_object.to_dict() + + def load_model_result_path(self, predict: bool): + self.model_result_path_dict = dict() + self.model_result_path = ResultFileHandling.get_remote_path( + self.components, self.ctx, BaseContext.MODEL_DATA_FILE) + self.model_result_path_dict.update( + {ModelJobResult.MODEL_RESULT_PATH: self.model_result_path}) + + self.train_result_path = ResultFileHandling.get_remote_path( + self.components, self.ctx, BaseContext.TRAIN_MODEL_OUTPUT_FILE) + self.model_result_path_dict.update( + {ModelJobResult.TRAIN_RESULT_PATH: self.train_result_path}) + + self.model_result_path_dict.update( + {ModelJobResult.TEST_RESULT_PATH: ResultFileHandling.get_remote_path( + self.components, self.ctx, BaseContext.TEST_MODEL_OUTPUT_FILE)}) + + self.woe_iv_result_path = ResultFileHandling.get_remote_path( + self.components, self.ctx, BaseContext.WOE_IV_FILE) + self.model_result_path_dict.update( + {ModelJobResult.WOE_RESULT_PATH: self.woe_iv_result_path}) + + def load_evaluation_table(self, evaluation_path, property): + evaluation_table_object = TableResult(self.ctx, self.components, + self.job_id, ResultFileMeta(evaluation_path)) + self.evaluation_table = {property: DataItem(name=property, data=evaluation_table_object.to_dict(), + type=DataType.TABLE).to_dict()} + + def load_feature_importance_table(self, feature_importance_path, property): + if not self.xgb_job: + return + feature_importance_table = TableResult(self.ctx, self.components, + self.job_id, ResultFileMeta(feature_importance_path)) + self.feature_importance_table = {property: DataItem(name=property, data=feature_importance_table.to_dict(), + type=DataType.TABLE).to_dict()} + + def load_encrypted_model_data(self): + try: + return self.components.storage_client.get_data(self.ctx.remote_model_enc_file).decode("utf-8") + except: + pass + + def load_iteration_metrics(self, iteration_path, property): + if not self.xgb_job: + return + try: + iteration_metrics_data = DataItem(data=ResultFileHandling.make_graph_data(self.components, self.ctx, utils.METRICS_OVER_ITERATION_FILE), + name='iteration_metrics', name_property="ModelPlotName", data_property="ModelPlotData", + type=DataType.IMAGE) + self.iteration_metrics = [] + self.iteration_property = property + self.iteration_metrics.append(iteration_metrics_data.to_dict()) + except: + pass + + def to_dict(self): + result = dict() + if self.model_result_list is not None: + result.update({self.property_name: self.model_result_list}) + if self.job_result is not None: + result.update({self.result_property: self.job_result}) + if self.evaluation_table is not None: + result.update(self.evaluation_table) + if self.feature_importance_table is not None: + result.update(self.feature_importance_table) + if self.iteration_metrics is not None: + result.update({self.iteration_property: self.iteration_metrics}) + if self.model_result_path_dict is not None: + result.update( + {ModelJobResult.MODEL_RESULT: self.model_result_path_dict}) + return result + + +class TaskResultHandler: + def __init__(self, task_result_request: TaskResultRequest, components: Initializer): + self.task_result_request = task_result_request + self.components = components + self.logger = components.logger() + self.result_list = [] + self.predict = False + self.xgb_job = False + self.model_data = None + self.ctx = BaseContext(job_id=task_result_request.job_id, + job_temp_dir="tmp", user=task_result_request.user) + if self.task_result_request.task_type == ModelTask.XGB_PREDICTING.name or self.task_result_request.task_type == ModelTask.LR_PREDICTING.name: + self.predict = True + if self.task_result_request.task_type == ModelTask.XGB_PREDICTING.name or self.task_result_request.task_type == ModelTask.XGB_TRAINING.name: + self.xgb_job = True + self.logger.info( + f"Init jobResultHandler for: {self.task_result_request.job_id}") + self._get_evaluation_result() + self._get_feature_processing_result() + + def get_response(self): + response = dict() + if self.task_result_request.fetch_result is True: + merged_result = dict() + for result in self.result_list: + merged_result.update(result.to_dict()) + if self.model_data is None: + response = {"jobPlanetResult": merged_result} + else: + response = {"jobPlanetResult": merged_result, + "modelData": self.model_data} + # record the log + if self.task_result_request.fetch_log is True: + log_size, log_path, log_content = self.components.log_retriever.retrieve_log( + self.task_result_request.job_id, self.task_result_request.user) + log_result = {} + log_result.update({"logSize": log_size}) + log_result.update({"logPath": log_path}) + log_result.update({"logContent": log_content}) + response.update({"logDetail": log_result}) + return utils.make_response(PpcErrorCode.SUCCESS.get_code(), PpcErrorCode.SUCCESS.get_msg(), response) + + def _get_evaluation_result(self): + if not self.predict: + # the train evaluation result + self.train_evaluation_result = JobEvaluationResult( + ctx=self.ctx, + property_name="outputMetricsGraphs", + classification_type=ClassificationType.TWO, + job_id=self.task_result_request.job_id, + evaluation_files=JobEvaluationResult.DEFAULT_TRAIN_EVALUATION_FILES, + components=self.components) + # load the ks table + self.train_evaluation_result.load_ks_table( + utils.MPC_TRAIN_METRIC_KS_TABLE, "TrainKSTable") + self.result_list.append(self.train_evaluation_result) + + self.validation_evaluation_result = JobEvaluationResult( + ctx=self.ctx, + property_name="outputTrainMetricsGraphs", + classification_type=ClassificationType.TWO, + job_id=self.task_result_request.job_id, + evaluation_files=JobEvaluationResult.DEFAULT_VALIDATION_EVALUATION_FILES, + components=self.components) + # load the ks_table + self.validation_evaluation_result.load_ks_table( + utils.MPC_TRAIN_METRIC_KS_TABLE, "KSTable") + self.result_list.append(self.validation_evaluation_result) + + self.model = ModelJobResult(self.ctx, self.xgb_job, + self.task_result_request.job_id, + self.components, ModelJobResult.DEFAULT_PROPERTY_NAME) + self.model.fetch_xgb_model_result() + # the ks-auc table + self.model.load_evaluation_table( + utils.MPC_XGB_EVALUATION_TABLE, "EvaluationTable") + # the feature-importance table + self.model.load_feature_importance_table( + utils.XGB_FEATURE_IMPORTANCE_TABLE, "FeatureImportance") + self.result_list.append(self.model) + # the metrics iteration graph + self.model.load_iteration_metrics( + utils.METRICS_OVER_ITERATION_FILE, "IterationGraph") + self.model_data = self.model.load_encrypted_model_data() + + if self.predict: + # the train evaluation result + self.predict_evaluation_result = JobEvaluationResult( + ctx=self.ctx, + property_name="outputMetricsGraphs", + classification_type=ClassificationType.TWO, + job_id=self.task_result_request.job_id, + evaluation_files=JobEvaluationResult.DEFAULT_EVAL_EVALUATION_FILES, + components=self.components) + # load ks_table + self.predict_evaluation_result.load_ks_table( + utils.MPC_TRAIN_METRIC_KS_TABLE, "KSTable") + self.result_list.append(self.predict_evaluation_result) + + # load model_result + self.model_result = ModelJobResult(self.ctx, self.xgb_job, + self.task_result_request.job_id, + self.components, ModelJobResult.DEFAULT_PROPERTY_NAME) + self.model_result.load_result( + BaseContext.TRAIN_MODEL_OUTPUT_FILE, "outputTrainPreview") + self.model_result.load_model_result_path(self.predict) + self.result_list.append(self.model_result) + + def _get_feature_processing_result(self): + self.feature_processing_result = FeatureProcessingResult(self.ctx, + self.components, self.task_result_request.job_id, FeatureProcessingResult.DEFAULT_FEATURE_PROCESSING_FILES) + self.result_list.append(self.feature_processing_result) diff --git a/python/ppc_model/network/__init__.py b/python/ppc_model/network/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/python/ppc_model/network/http/__init__.py b/python/ppc_model/network/http/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/python/ppc_model/network/http/body_schema.py b/python/ppc_model/network/http/body_schema.py new file mode 100644 index 00000000..aacb7616 --- /dev/null +++ b/python/ppc_model/network/http/body_schema.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +import json + +from flask_restx import fields, reqparse + +from ppc_model.network.http.restx import api + +response_base = api.model('Response base info', { + 'errorCode': fields.Integer(description='return code'), + 'message': fields.String(description='return message') +}) + +response_task_status = api.inherit('Task status', response_base, { + 'data': fields.Raw(description='Task status data as key-value dictionary', example={ + 'status': 'RUNNING', + 'traffic_volume': '10MB', + 'time_costs': '30s' + }) +}) diff --git a/python/ppc_model/network/http/model_controller.py b/python/ppc_model/network/http/model_controller.py new file mode 100644 index 00000000..d99efc2a --- /dev/null +++ b/python/ppc_model/network/http/model_controller.py @@ -0,0 +1,125 @@ +# -*- coding: utf-8 -*- + +from flask import request +from flask_restx import Resource +import time + +from ppc_common.ppc_utils import utils +from ppc_model.common.global_context import components +from ppc_model.common.protocol import ModelTask +from ppc_model.network.http.body_schema import response_task_status, response_base +from ppc_model.network.http.restx import api +from ppc_model.model_result.task_result_handler import TaskResultHandler +from ppc_model.model_result.task_result_handler import TaskResultRequest + +ns = api.namespace('ppc-model/pml/run-model-task', + description='Operations related to run model task') +ns2 = api.namespace('ppc-model/pml/record-model-log', + description='Operations related to record model log') +ns_get_job_result = api.namespace( + 'ppc-model/pml/get-job-result', description='Get the job result') + + +@ns.route('/') +class ModelCollection(Resource): + + @api.response(201, 'Task started successfully.', response_base) + def post(self, model_id): + """ + Run a specific task by task_id. + """ + try: + args = request.get_json() + task_id = model_id + components.logger().info( + f"run task request, task_id: {task_id}") + task_type = args['task_type'] + if 'user' not in args.keys(): + raise Exception( + f"Must pass the user that trigger the job, task_id: {task_id}") + if 'job_id' not in args.keys(): + raise Exception(f"Must pass the job_id, task_id: {task_id}") + components.task_manager.run_task( + task_id, ModelTask(task_type), (args,)) + return utils.BASE_RESPONSE + except Exception as e: + response = {} + response.update({'errorCode': -1}) + response.update( + {'message': f'submit task {model_id} failed for {e}'}) + return response + + @api.response(200, 'Task status retrieved successfully.', response_task_status) + def get(self, model_id): + try: + """ + Get the status of a specific task by task_id. + """ + response = utils.BASE_RESPONSE + task_id = model_id + status, traffic_volume, exec_result = components.task_manager.status( + task_id) + response['data'] = { + 'status': status, + 'traffic_volume': traffic_volume, + 'exec_result': exec_result, + } + return response + except Exception as e: + response = {} + response.update({'errorCode': -1}) + response.update( + {'message': f'query task status for {model_id} failed for {e}'}) + return response + + @api.response(200, 'Task killed successfully.', response_base) + def delete(self, model_id): + try: + """ + Kill a specific task by job_id. + """ + job_id = model_id + components.logger().info( + f"kill request, job_id: {job_id}") + components.task_manager.kill_task(job_id=job_id) + return utils.BASE_RESPONSE + except Exception as e: + response = {} + response.update({'errorCode': -1}) + response.update( + {'message': f'kill task {model_id} failed for {e}'}) + return response + + +@ns_get_job_result.route('/') +class ModelResultCollection(Resource): + @api.response(201, 'Get task result successfully.', response_base) + def post(self, task_id): + try: + """ + Get the result related to the task_id + """ + start_t = time.time() + args = request.get_json() + components.logger().info( + f"get task result, task_id: {task_id}, args: {args}") + user_name = args['user'] + task_type = args['jobType'] + fetch_log = args['fetchLog'] + fetch_job_result = args['fetchJobResult'] + components.logger().info( + f"get_job_direct_result_response, job: {task_id}, fetch_log: {fetch_log}, fetch_job_result: {fetch_job_result}") + task_result_request = TaskResultRequest( + task_id, task_type, fetch_log, fetch_job_result, user_name) + job_result_handler = TaskResultHandler( + task_result_request=task_result_request, components=components) + response = job_result_handler.get_response() + components.logger().info( + f"get_job_direct_result_response success, user: {user_name}, job: {task_id}, timecost: {time.time() - start_t}s") + return response + except Exception as e: + response = {} + response.update({'errorCode': -1}) + response.update( + {'message': f'query task log for {task_id} failed for {e}'}) + return response diff --git a/python/ppc_model/network/http/restx.py b/python/ppc_model/network/http/restx.py new file mode 100644 index 00000000..553337ae --- /dev/null +++ b/python/ppc_model/network/http/restx.py @@ -0,0 +1,36 @@ +# -*- coding: utf-8 -*- + +from flask_restx import Api + +from ppc_common.ppc_utils.exception import PpcException, PpcErrorCode +from ppc_model.common.global_context import components + +authorizations = { + 'apikey': { + 'type': 'apiKey', + 'in': 'header', + 'name': 'Authorization' + } +} + +api = Api(version='1.0', title='Ppc Model Service', + authorizations=authorizations, security='apikey') + + +@api.errorhandler(PpcException) +def default_error_handler(e): + components.logger().exception(e) + info = e.to_dict() + response = {'errorCode': info['code'], 'message': info['message']} + components.logger().error( + f"OnError: code: {info['code']}, message: {info['message']}") + return response, 500 + + +@api.errorhandler(BaseException) +def default_error_handler(e): + components.logger().exception(e) + message = 'unknown error.' + response = {'errorCode': PpcErrorCode.INTERNAL_ERROR, 'message': message} + components.logger().error(f"OnError: unknown error") + return response, 500 diff --git a/python/ppc_model/network/test/__init__.py b/python/ppc_model/network/test/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/python/ppc_model/network/wedpr_model_transport.py b/python/ppc_model/network/wedpr_model_transport.py new file mode 100644 index 00000000..a2dc50bd --- /dev/null +++ b/python/ppc_model/network/wedpr_model_transport.py @@ -0,0 +1,152 @@ +# -*- coding: utf-8 -*- +from wedpr_python_gateway_sdk.transport.impl.transport import Transport +from wedpr_python_gateway_sdk.transport.impl.transport import RouteType +from wedpr_python_gateway_sdk.transport.api.message_api import MessageAPI +from ppc_model.network.wedpr_model_transport_api import ModelTransportApi +from ppc_model.network.wedpr_model_transport_api import ModelRouterApi +from ppc_model.task.task_manager import TaskManager +import time +from readerwriterlock import rwlock +from enum import Enum + + +class ModelTransport(ModelTransportApi): + def __init__(self, transport: Transport, self_agency_id: str, task_manager: TaskManager, + component_type, + send_msg_timeout_ms: int = 5000, + pop_msg_timeout_ms: int = 60000): + self.transport = transport + self.self_agency_id = self_agency_id + # default send msg timeout + self.send_msg_timeout = send_msg_timeout_ms + self.pop_msg_timeout = pop_msg_timeout_ms + self.task_manager = task_manager + self.component_type = component_type + + @staticmethod + def get_topic(task_id: str, task_type: str, agency: str): + return f"{agency}_{task_id}_{task_type}" + + @staticmethod + def get_topic_without_agency(task_id: str, task_type: str): + return f"{task_id}_{task_type}" + + def push_by_component(self, task_id: str, task_type: str, dst_inst: str, data): + self.transport.push_by_component(topic=self.get_topic(task_id, task_type, dst_inst), + dstInst=dst_inst, + component=self.component_type, + payload=data, timeout=self.send_msg_timeout) + + def push_by_nodeid(self, task_id: str, task_type: str, dst_node: str, payload: bytes, seq: int = 0): + self.transport.push_by_nodeid(topic=self.get_topic(task_id, task_type, self.self_agency_id), + dstNode=bytes( + dst_node, encoding="utf-8"), + seq=seq, payload=payload, + timeout=self.send_msg_timeout) + + def pop_by_topic(self, topic, task_id) -> MessageAPI: + while not self.task_manager.task_finished(task_id): + msg = self.transport.pop( + topic=topic, timeout_ms=self.pop_msg_timeout) + # wait for the msg if the task is running + if msg is None: + time.sleep(0.04) + else: + return msg + raise Exception(f"Not receive the message of topic:" + f" {topic} " + f"even after the task has been killed!") + + def pop(self, task_id: str, task_type: str, dst_inst: str) -> MessageAPI: + return self.pop_by_topic(topic=self.get_topic(task_id, task_type, dst_inst), task_id=task_id) + + def get_component_type(self): + return self.component_type + + def select_node(self, route_type: RouteType, dst_agency: str, dst_component: str) -> str: + return self.transport.select_node_by_route_policy(route_type=route_type, + dst_inst=dst_agency, dst_component=dst_component) + + def stop(self): + self.transport.stop() + + +class BaseMessage(Enum): + Handshake = "Handshake" + + +class ModelRouter(ModelRouterApi): + def __init__(self, logger, transport: ModelTransport): + self.logger = logger + self.transport = transport + # task_id=>{agency=>selectedNode} + self.router_info = {} + self._rw_lock = rwlock.RWLockWrite() + + def handshake(self, task_id, participant): + self.logger.info(f"handshake with {participant}") + topic = ModelTransport.get_topic_without_agency( + task_id, BaseMessage.Handshake.value) + self.transport.transport.register_topic(topic) + self.transport.transport.push_by_topic(topic=topic, + dstInst=participant, + seq=0, payload=bytes(), + timeout=self.transport.send_msg_timeout) + + def __all_connected__(self, task_id, participant_id_list, self_agency_id): + with self._rw_lock.gen_rlock(): + if task_id not in self.router_info.keys(): + return False + for participant in participant_id_list: + if participant == self_agency_id: + continue + if participant not in self.router_info.get(task_id).keys(): + return False + self.logger.info( + f"__all_connected__, task: {task_id}, participant_id_list: {participant_id_list}") + return True + + def wait_for_handshake(self, task_id, participant_id_list: list, self_agency_id): + while not self.__all_connected__(task_id, participant_id_list, self_agency_id): + time.sleep(0.04) + topic = ModelTransport.get_topic_without_agency( + task_id, BaseMessage.Handshake.value) + self.transport.transport.register_topic(topic) + result = self.transport.pop_by_topic(topic=topic, task_id=task_id) + + if result is None: + raise Exception(f"wait_for_handshake failed!") + self.logger.info( + f"wait_for_handshake success, task: {task_id}, detail: {result}") + with self._rw_lock.gen_wlock(): + from_inst = result.get_header().get_src_inst() + if task_id not in self.router_info.keys(): + self.router_info.update({task_id: dict()}) + self.router_info.get(task_id).update( + {from_inst: result.get_header().get_src_node().decode("utf-8")}) + + def on_task_finish(self, task_id): + topic = ModelTransport.get_topic_without_agency( + task_id, BaseMessage.Handshake.value) + self.transport.transport.unregister_topic(topic) + with self._rw_lock.gen_wlock(): + if task_id in self.router_info.keys(): + self.router_info.pop(task_id) + + def __get_dstnode__(self, task_id, dst_agency): + with self._rw_lock.gen_rlock(): + if task_id in self.router_info.keys() and dst_agency in self.router_info.get(task_id).keys(): + return self.router_info.get(task_id).get(dst_agency) + raise Exception( + f"No Router found for task {task_id}, dst_agency: {dst_agency}") + + def push(self, task_id: str, task_type: str, dst_agency: str, payload: bytes, seq: int = 0): + dst_node = self.__get_dstnode__(task_id, dst_agency) + self.transport.push_by_nodeid( + task_id=task_id, task_type=task_type, dst_node=dst_node, payload=payload, seq=seq) + + def pop(self, task_id: str, task_type: str, from_inst: str) -> bytes: + result = self.transport.pop( + task_id=task_id, task_type=task_type, dst_inst=from_inst) + self.logger.debug(f"Receive message from {result}") + return result.get_payload() diff --git a/python/ppc_model/network/wedpr_model_transport_api.py b/python/ppc_model/network/wedpr_model_transport_api.py new file mode 100644 index 00000000..c2f60172 --- /dev/null +++ b/python/ppc_model/network/wedpr_model_transport_api.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- + +from abc import ABC, abstractmethod + + +class ModelTransportApi(ABC): + @abstractmethod + def push_by_nodeid(self, task_id: str, task_type: str, dst_node: str, payload: bytes, seq: int = 0): + pass + + @abstractmethod + def pop(self, task_id: str, task_type: str, dst_inst: str): + pass + + +class ModelRouterApi: + @abstractmethod + def push(self, task_id: str, task_type: str, dst_agency: str, payload: bytes, seq: int = 0): + pass + + @abstractmethod + def pop(self, task_id: str, task_type: str, from_inst: str) -> bytes: + pass diff --git a/python/ppc_model/ppc_model_app.py b/python/ppc_model/ppc_model_app.py new file mode 100644 index 00000000..036301c3 --- /dev/null +++ b/python/ppc_model/ppc_model_app.py @@ -0,0 +1,77 @@ +# Note: here can't be refactored by autopep +import sys +import os +root_path = os.path.abspath(os.path.dirname(__file__)) +sys.path.append(os.path.join(root_path, "../")) +# Note: here can't be refactored by autopep + +from ppc_model.secure_lgbm.secure_lgbm_training_engine import SecureLGBMTrainingEngine +from ppc_model.secure_lgbm.secure_lgbm_prediction_engine import SecureLGBMPredictionEngine +from ppc_model.secure_lr.secure_lr_training_engine import SecureLRTrainingEngine +from ppc_model.secure_lr.secure_lr_prediction_engine import SecureLRPredictionEngine +from ppc_model.preprocessing.preprocessing_engine import PreprocessingEngine +from ppc_model.network.http.restx import api +from ppc_model.network.http.model_controller import ns2 as log_namespace +from ppc_model.network.http.model_controller import ns as task_namespace +from ppc_model.feature_engineering.feature_engineering_engine import FeatureEngineeringEngine +from ppc_model.common.protocol import ModelTask +from ppc_model.common.global_context import components +from paste.translogger import TransLogger +from flask import Flask, Blueprint +from cheroot.wsgi import Server as WSGIServer +from cheroot.ssl.builtin import BuiltinSSLAdapter +import multiprocessing + + +app = Flask(__name__) + + +def initialize_app(app): + # 初始化应用功能组件 + components.init_all() + + app.config.update(components.config_data) + blueprint = Blueprint('api', __name__, url_prefix='/api') + api.init_app(blueprint) + api.add_namespace(task_namespace) + api.add_namespace(log_namespace) + app.register_blueprint(blueprint) + + +def register_task_handler(): + task_manager = components.task_manager + task_manager.register_task_handler( + ModelTask.PREPROCESSING, PreprocessingEngine.run) + task_manager.register_task_handler( + ModelTask.FEATURE_ENGINEERING, FeatureEngineeringEngine.run) + task_manager.register_task_handler( + ModelTask.XGB_TRAINING, SecureLGBMTrainingEngine.run) + task_manager.register_task_handler( + ModelTask.XGB_PREDICTING, SecureLGBMPredictionEngine.run) + task_manager.register_task_handler( + ModelTask.LR_TRAINING, SecureLRTrainingEngine.run) + task_manager.register_task_handler( + ModelTask.LR_PREDICTING, SecureLRPredictionEngine.run) + # register clear handlers + task_manager.register_task_clear_handler( + components.model_router.on_task_finish) + +if __name__ == '__main__': + initialize_app(app) + register_task_handler() + + # 启动子进程不继承父进程的锁状态,防止死锁 + multiprocessing.set_start_method('spawn') + + app.config['SECRET_KEY'] = os.urandom(24) + server = WSGIServer((app.config['HOST'], app.config['HTTP_PORT']), + TransLogger(app, setup_console_handler=False), numthreads=2) + + protocol = 'http' + message = f"* Starting ppc model server at {protocol}://{app.config['HOST']}:{app.config['HTTP_PORT']} successfully" + print(message) + components.logger().info(message) + server.start() + # stop the nodes + components.transport.stop() + print("Stop ppc model server successfully") diff --git a/python/ppc_model/preprocessing/__init__.py b/python/ppc_model/preprocessing/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/python/ppc_model/preprocessing/local_processing/local_processing_party.py b/python/ppc_model/preprocessing/local_processing/local_processing_party.py new file mode 100644 index 00000000..4a71bfdf --- /dev/null +++ b/python/ppc_model/preprocessing/local_processing/local_processing_party.py @@ -0,0 +1,85 @@ +import os +import time +from abc import ABC + +import pandas as pd + +from ppc_common.ppc_utils import utils +from ppc_model.preprocessing.local_processing.preprocessing import process_dataframe +from ppc_model.preprocessing.processing_context import ProcessingContext +from ppc_model.common.base_context import BaseContext + + +class LocalProcessingParty(ABC): + + def __init__(self, ctx: ProcessingContext): + self.ctx = ctx + + def processing(self): + log = self.ctx.components.logger() + start = time.time() + need_psi = self.ctx.need_run_psi + job_id = self.ctx.job_id + log.info( + f"run data preprocessing job, job: {job_id}, need_psi: {need_psi}") + dataset_path = self.ctx.dataset_path + dataset_file_path = self.ctx.dataset_file_path + storage_client = self.ctx.components.storage_client + job_algorithm_type = self.ctx.job_algorithm_type + psi_result_path = self.ctx.psi_result_path + model_prepare_file = self.ctx.model_prepare_file + + storage_client.download_file(dataset_path, dataset_file_path) + if need_psi and (not utils.file_exists(psi_result_path)): + storage_client.download_file( + self.ctx.remote_psi_result_path, psi_result_path) + + log.info( + f"prepare_xgb_after_psi, make_dataset_to_xgb_data_plus_psi_data, local_dataset_file_path={dataset_file_path}, " + f"remote_dataset_path={dataset_path}, model_prepare_file={model_prepare_file}, " + f"remote_psi_result_path: {self.ctx.remote_psi_result_path}") + self.make_dataset_to_xgb_data() + storage_client.upload_file( + model_prepare_file, self.ctx.remote_model_prepare_file, self.ctx.user) + log.info(f"upload model_prepare_file to hdfs, job_id={job_id}") + if job_algorithm_type == utils.AlgorithmType.Train.name: + log.info(f"upload column_info to hdfs, job_id={job_id}") + storage_client.upload_file(self.ctx.preprocessing_result_file, + self.ctx.remote_preprocessing_file, self.ctx.user) + log.info( + f"call prepare_xgb_after_psi success, job_id={job_id}, timecost: {time.time() - start}") + + def make_dataset_to_xgb_data(self): + log = self.ctx.components.logger() + dataset_file_path = self.ctx.dataset_file_path + psi_result_file_path = self.ctx.psi_result_path + model_prepare_file = self.ctx.model_prepare_file + log.info(f"dataset_file_path:{dataset_file_path}") + log.info(f"model_prepare_file:{model_prepare_file}") + need_run_psi = self.ctx.need_run_psi + job_id = self.ctx.job_id + if not utils.file_exists(dataset_file_path): + raise FileNotFoundError( + f"dataset_file_path not found: {dataset_file_path}") + dataset_df = pd.read_csv(dataset_file_path) + if need_run_psi: + psi_data = pd.read_csv(psi_result_file_path, + delimiter=utils.CSV_SEP) + dataset_df = pd.merge(dataset_df, psi_data, on=[ + 'id']).sort_values(by='id', ascending=True) + log.info( + f"psi_result_file_path:{psi_result_file_path}, dataset_columns: {dataset_df.columns}") + + ppc_job_type = self.ctx.job_algorithm_type + column_info = process_dataframe( + dataset_df, self.ctx.model_setting, model_prepare_file, ppc_job_type, job_id, self.ctx) + + column_info_pd = pd.DataFrame(column_info).transpose() + # 如果是训练任务先写本地 + log.info(f"jobid {job_id}, job_algorithm_type {ppc_job_type}") + if ppc_job_type == utils.AlgorithmType.Train.name: + log.info( + f"write {column_info} to {self.ctx.preprocessing_result_file}") + column_info_pd.to_csv( + self.ctx.preprocessing_result_file, sep=utils.CSV_SEP, header=True) + log.info("finish make_dataset_to_xgb_data_plus_psi_data") diff --git a/python/ppc_model/preprocessing/local_processing/preprocessing.py b/python/ppc_model/preprocessing/local_processing/preprocessing.py new file mode 100644 index 00000000..66346bb8 --- /dev/null +++ b/python/ppc_model/preprocessing/local_processing/preprocessing.py @@ -0,0 +1,631 @@ +# -*- coding: utf-8 -*- +# from concurrent.futures import ProcessPoolExecutor, as_completed + +import json +import os + +import numpy as np +import pandas as pd +from sklearn.preprocessing import MinMaxScaler, StandardScaler +from ppc_model.common.model_setting import ModelSetting + +from ppc_common.ppc_utils import utils +from ppc_common.ppc_utils.exception import PpcException, PpcErrorCode +from ppc_model.common.global_context import components +from ppc_model.preprocessing.local_processing.psi_select import calculate_psi +from ppc_model.preprocessing.local_processing.standard_type_enum import standardType +# from ppc_common.ppc_mock.mock_objects import MockLogger + +# components.mock_logger = MockLogger() +# log = components.mock_logger +log = components.logger() + + +def process_train_dataframe(dataset_df: pd.DataFrame, column_info_dict: dict): + """ + 使用column_info对dataset_df进行处理 只保留column_info中的列 + + 参数: + - dataset_df: 待处理的DataFrame数据 + - column_info: 字段信息, 字典类型 + + 返回值: + - dataset_df_filled: 处理后的DataFrame数据 + """ + # dataset_df_filled = None + # Iterate over column_info_dict keys, if 'isExisted' is False, drop the column + for key, value in column_info_dict.items(): + if value.get('isExisted') is None: + raise PpcException(PpcErrorCode.XGB_PREPROCESSING_ERROR.get_code( + ), "column_info_dict isExisted is None") + if value.get('isExisted') is False: + dataset_df = dataset_df.drop(key, axis=1) + + return dataset_df + + +def process_dataframe(dataset_df: pd.DataFrame, model_setting: ModelSetting, xgb_data_file_path: str, + ppc_job_type: str = utils.AlgorithmType.Train.name, job_id: str = None, ctx=None): + """ + 对数据集进行预处理的函数。 + 共执行6步操作 + 1. 去除唯一属性: 为了让无意义的参数不影响模型, 比如id, id不代表样本本身的规律, 所以要把这些属性删掉 + 2. 缺失值处理: 删除含有缺失值的特征,若变量的缺失率较高(大于80%),覆盖率较低,且重要性较低,可以直接将变量删除. + 每一行的数据不一定拥有所有的模型标签,支持不填充,和均值插补, + 我们目前使用均值插补,以该属性存在值的平均值来插补缺失的值 + 连续性:普通均值 + 类别:单独类别,当做新类别 + 3. 离群值处理方法: 数据过大或过小会一个峡谷分析结果,要先调整因子值的离群值上下限,减少离群值的影响,防止下一步归一化后的偏差过大 + 我们用的3 \sigma 法,又叫做标准差法 + 4. 特征编码: 将特征编码为固定的值 比如one-hot就是将不同的type 编码为1 2 3 4 5...这样的值 + 5. 数据标准化: min-max标准化(归一化):最大值1. 最小值0或-1 以及z-score标准化 规范化:均值为0 标准差为1 + 6. 特征选择: 从给定的特征集合中选出相关特征子集的过程称为特征选择, 我们使用的是PSI 风控模型,群体稳定性指标 PSI-Population Stability Index + 参考 https://zhuanlan.zhihu.com/p/79682292 + + + 参数: + dataset_df (pandas.DataFrame): 输入的数据集。 + xgb_data_file_path (str): XGBoost数据文件路径。 + + 返回: + column_info: 处理后的数据集字段。 + """ + log.info( + f"jobid: {job_id}, xgb_data_file_path:{xgb_data_file_path}, ppc_job_type: {ppc_job_type}") + if model_setting is None: + log.error("model_setting is None") + raise PpcException( + PpcErrorCode.XGB_PREPROCESSING_ERROR.get_code(), "model_setting is None") + + column_info = {} + + if ppc_job_type != utils.AlgorithmType.Predict.name: + # 如果是训练任务 先默认所有数据都存在 + column_info = {col: {'isExisted': True} for col in dataset_df.columns} + + if model_setting.eval_set_column is not None: + if model_setting.eval_set_column in dataset_df.columns: + eval_column = model_setting.eval_set_column + dataset_df[['id', eval_column]].to_csv( + ctx.eval_column_file, index=None) + ctx.components.storage_client.upload_file(ctx.eval_column_file, + ctx.remote_eval_column_file, ctx.user) + if model_setting.eval_set_column != model_setting.psi_select_col: + dataset_df = dataset_df.drop(columns=[eval_column]) + + categorical_cols = ['id', 'y'] + + # 判断 model_setting['categorical']是否为None + if model_setting.categorical is None: + log.error( + f"jobid: {job_id} model_setting['categorical'] is None, model_setting:{model_setting}") + raise PpcException(PpcErrorCode.XGB_PREPROCESSING_ERROR.get_code( + ), "xgb_model_dict['categorical'] is None") + + if model_setting.fillna is None: + log.error( + f"jobid: {job_id} xgb_model_dict['fillna'] is None, model_setting:{model_setting}") + raise PpcException(PpcErrorCode.XGB_PREPROCESSING_ERROR.get_code( + ), "xgb_model_dict['fillna'] is None") + + # 指定分类特征索引 + if model_setting.categorical != '0': + categoricals = model_setting.categorical.split(',') + categorical_cols.extend(categoricals) + # 去除categorical_cols中的重复元素 + categorical_cols = list(set(categorical_cols)) + + df_filled = dataset_df + # 预处理表格信息 包含每一列缺失值比例 缺失值是否被筛掉 psi筛选和相关性筛选 如果在某个阶段被筛掉则设置为0 保留则为1 + # 1.去除唯一属性 + if 'id' in df_filled.columns: + log.info(f"jobid: {job_id} move id column start.") + df_filled = df_filled.drop('id', axis=1) + log.info(f"jobid: {job_id} move id column finish.") + + # 2.1 缺失值筛选 + if ppc_job_type != utils.AlgorithmType.Predict.name: + if 0 <= model_setting.na_select <= 1: + log.info(f"jobid: {job_id} run fillna start") + df_filled, column_info = process_na_dataframe( + df_filled, model_setting.na_select) + log.info(f"jobid: {job_id} run fillna finish") + else: + log.error( + f"jobid: {job_id} xgb_model_dict['na_select'] is range not 0 to 1, xgb_model_dict:{model_setting}") + raise PpcException(PpcErrorCode.XGB_PREPROCESSING_ERROR.get_code(), + "xgb_model_dict['na_select'] range not 0 to 1") + else: + log.info(f"jobid: {job_id} don't need run fillna for predict job.") + + # 2.2 缺失值处理 + if model_setting.fillna == 1: + # 填充 + log.info(f"jobid: {job_id} run fillna with means start") + try: + df_filled = process_na_fill_dataframe( + df_filled, categorical_cols, model_setting.psi_select_col) + log.info(f"jobid: {job_id} run fillna with means finish") + except Exception as e: + log.error( + f"jobid: {job_id} process_na_fill_dataframe error, e:{e}") + raise PpcException(PpcErrorCode.XGB_PREPROCESSING_ERROR.get_code( + ), "process_na_fill_dataframe error") + elif model_setting.fillna == 0: + # 不填充 + log.info(f"jobid: {job_id} don't need run fillna ") + # 如果本身是None就不需要处理 + df_filled.replace('None', np.nan) + else: + log.error( + f"jobid: {job_id} xgb_model_dict['fillna'] is not 0 or 1, model_setting:{model_setting}") + raise PpcException(PpcErrorCode.XGB_PREPROCESSING_ERROR.get_code( + ), "xgb_model_dict['fillna'] is not 0 or 1") + + # 6.1 特征选择 进行 psi稳定性指标筛选 计算特征相关性 降维可以减少模型的复杂度,提高模型的泛化能力 + if ppc_job_type != utils.AlgorithmType.Predict.name: + if model_setting.psi_select_col in df_filled.columns.tolist() and model_setting.psi_select_col != 0: + log.info(f"jobid: {job_id} run psi_select_col start") + psi_select_base = model_setting.psi_select_base + psi_select_thresh = model_setting.psi_select_thresh + psi_select_bins = model_setting.psi_select_bins + psi_select_col = model_setting.psi_select_col + + if psi_select_base is None or psi_select_thresh is None or psi_select_bins is None: + log.error( + f"jobid: {job_id} psi_select_base or psi_select_thresh or psi_select_bins is None, model_setting:{model_setting}") + raise PpcException(PpcErrorCode.XGB_PREPROCESSING_ERROR.get_code(), + "psi_select_base or psi_select_thresh or psi_select_bins is None") + df_filled, psi_selected_cols = process_psi(df_filled, categorical_cols, psi_select_col, psi_select_base, + psi_select_thresh, psi_select_bins) + # 使用column_info和psi_selected_cols 追加psi_selected列 如果列还在则选中是1 否则是0 + for col in column_info.keys(): + if col in psi_selected_cols: + column_info[col]['psi_selected'] = 1 + column_info[col]['isExisted'] = True + else: + column_info[col]['psi_selected'] = 0 + column_info[col]['isExisted'] = False + log.info(f"jobid: {job_id} run psi_select_col finish") + elif model_setting.psi_select_col == 0 or model_setting.psi_select_col == "": + log.info(f"jobid: {job_id} don't need run psi_select_col") + else: + log.error( + f"jobid: {job_id} xgb_model_dict['psi_select_col'] is not 0 or in col, model_setting:{model_setting}") + raise PpcException(PpcErrorCode.XGB_PREPROCESSING_ERROR.get_code(), + "xgb_model_dict['psi_select_col'] is not 0 or in col") + else: + log.info( + f"jobid: {job_id} don't need run psi_select_col for predict job.") + + # 6.2 特征选择 进行 corr_select 计算特征相关性 + if ppc_job_type != utils.AlgorithmType.Predict.name: + if model_setting.corr_select > 0: + log.info(f"jobid: {job_id} run corr_select start") + corr_select = model_setting.corr_select + df_filled = remove_high_correlation_features( + df_filled, categorical_cols, corr_select) + # 设置相关性筛选的column_info + for col in column_info.keys(): + if col in df_filled.columns.tolist(): + column_info[col]['corr_selected'] = 1 + column_info[col]['isExisted'] = True + else: + column_info[col]['corr_selected'] = 0 + column_info[col]['isExisted'] = False + log.info(f"jobid: {job_id} run corr_select finish") + elif model_setting.corr_select == 0: + log.info(f"jobid: {job_id} don't need run corr_select") + else: + log.error( + f"jobid: {job_id} xgb_model_dict['corr_select'] is not >= 0, model_setting:{model_setting}") + raise PpcException(PpcErrorCode.XGB_PREPROCESSING_ERROR.get_code(), + "xgb_model_dict['corr_select'] is not >= 0") + else: + log.info( + f"jobid: {job_id} don't need run corr_select for predict job.") + + # 3. 离群值处理 3-sigma 法 + if model_setting.filloutlier == 1: + log.info(f"jobid: {job_id} run filloutlier start") + df_filled = process_outliers(df_filled, categorical_cols) + log.info(f"jobid: {job_id} run filloutlier finish") + elif model_setting.filloutlier == 0: + log.info(f"jobid: {job_id} don't need run filloutlier") + else: + log.error( + f"jobid: {job_id} xgb_model_dict['filloutlier'] is not 0 or 1, model_setting:{model_setting}") + raise PpcException(PpcErrorCode.XGB_PREPROCESSING_ERROR.get_code(), + "xgb_model_dict['filloutlier'] is not 0 or 1") + + # 5.1 数据标准化 支持max-min normalized + if model_setting.normalized == 1: + log.info(f"jobid: {job_id} run normalized start") + df_filled = normalize_dataframe( + df_filled, categorical_cols, standardType.min_max.value) + log.info(f"jobid: {job_id} run normalized finish") + elif model_setting.normalized == 0: + log.info(f"jobid: {job_id} don't need run normalized") + else: + log.error( + f"jobid: {job_id} xgb_model_dict['normalized'] is not 0 or 1, model_setting:{model_setting}") + raise PpcException(PpcErrorCode.XGB_PREPROCESSING_ERROR.get_code(), + "xgb_model_dict['normalized'] is not 0 or 1") + + # 5.2 z-score标准化(规范化) standardized + if model_setting.standardized == 1: + log.info(f"jobid: {job_id} run standardized start") + df_filled = normalize_dataframe( + df_filled, categorical_cols, standardType.z_score.value) + log.info(f"jobid: {job_id} run standardized finish") + elif model_setting.standardized == 0: + log.info(f"jobid: {job_id} don't need run standardized") + else: + log.error( + f"jobid: {job_id} xgb_model_dict['standardized'] is not 0 or 1, model_setting:{model_setting}") + raise PpcException(PpcErrorCode.XGB_PREPROCESSING_ERROR.get_code(), + "xgb_model_dict['standardized'] is not 0 or 1") + + # 4. 特征编码,对分类特征进行one-hot编码 这里会多一些列 所以放到最后 + if model_setting.one_hot == 1: + log.info(f"jobid: {job_id} run one_hot start") + df_filled = one_hot_encode_and_merge(df_filled, categorical_cols) + log.info(f"jobid: {job_id} run one_hot finish") + elif model_setting.one_hot == 0: + log.info(f"jobid: {job_id} don't need run one_hot") + else: + log.error( + f"jobid: {job_id} model_setting['one_hot'] is not 0 or 1, xgb_model_dict:{model_setting}") + raise PpcException(PpcErrorCode.XGB_PREPROCESSING_ERROR.get_code( + ), "model_setting['one_hot'] is not 0 or 1") + df_filled.to_csv(xgb_data_file_path, mode='w', + sep=utils.BLANK_SEP, header=True, index=None) + # log.info(f"jobid: {job_id} column_info:{column_info} in type: {ppc_job_type}, process_dataframe succeed") + log.info( + f"jobid: {job_id} in type: {ppc_job_type}, process_dataframe succeed") + return column_info + + +def process_na_dataframe(df: pd.DataFrame, na_select: float): + """ + 缺失值处理 如果小于阈值则移除该列 + + 参数 + - df: 待处理的DataFrame数据 + - na_select: 缺失值占比阈值 + + 返回值: + 处理后的DataFrame数据 + """ + missing_ratios = df.isnull().mean() + + # 剔除缺失值占比大于na_select的列 + selected_cols = missing_ratios[missing_ratios <= na_select].index + + column_info = {col: {'missing_ratio': missing_ratios[col], 'na_selected': 1 if col in selected_cols else 0, } for + col in df.columns} + # 如果没被选择 将isExisted设置为false + for col in column_info.keys(): + if col not in selected_cols: + column_info[col]['isExisted'] = False + else: + column_info[col]['isExisted'] = True + df_processed = df[selected_cols] + return df_processed, column_info + + +def process_na_fill_dataframe(df: pd.DataFrame, categorical_cols: list = None, psi_select_col: str = None): + """ + 处理DataFrame数据: + 1. 计算每一列的缺失值占比; + 2. 剔除缺失值占比大于阈值的列; + 3. 使用每列的均值填充剩余的缺失值。 + + 参数: + - df: 待处理的DataFrame数据 + - na_select: 缺失值占比阈值 + - categorical_cols: 分类特征列 + + + 返回值: + 处理后的DataFrame数据 + """ + # 计算每一列的缺失值占比 + + # 判断categorical_cols是否在df中,如果是,填充则用col的max+1, 否则用均值插补 + df_processed = df.copy() # Assign the sliced DataFrame to a new variable + for col in df_processed.columns.to_list(): + # 如果col是y,则忽略 + if col == 'y': + continue + elif psi_select_col and col == psi_select_col: + continue + if col in categorical_cols: + df_processed.fillna( + {col: df_processed[col].max() + 1}, inplace=True) + else: + df_processed.fillna({col: df_processed[col].mean()}, inplace=True) + return df_processed + + +def process_outliers(df: pd.DataFrame, categorical_cols: list): + """ + 处理DataFrame数据中的异常值 + 1. 计算每一列的均值和标准差; + 2. 对于超出均值+-3倍标准差的数据 使用均值填充。 + + 参数: + - df: 待处理的DataFrame数据 + - categorical_cols: 列表,包含分类列的名称 + + 返回值: + 处理后的DataFrame数据 + """ + # 计算每一列的均值和标准差 + means = df.mean() + threshold = 3 * df.std() + + # 定义处理异常值的函数 + def replace_outliers(col): + # 如果列是分类列,不处理 + if col.name in categorical_cols: + return col + else: + lower_bound = means[col.name] - threshold[col.name] + upper_bound = means[col.name] + threshold[col.name] + # 如果元素是空值或不是异常值,保持不变;否则使用均值填充 + return np.where(col.notna() & ((col < lower_bound) | (col > upper_bound)), means[col.name], col) + + # 应用处理异常值的函数到DataFrame的每一列 + df_processed = df.apply(replace_outliers) + return df_processed + + +def one_hot_encode_and_merge(df_filled: pd.DataFrame, categorical_features: list): + """ + 对DataFrame中指定的分类特征列进行One-Hot编码 并将编码后的结果合并到DataFrame中。 + + 参数: + - df: 待处理的DataFrame数据 + - categorical_features: 分类特征列表 需要进行One-Hot编码的列名 + + 返回值: + 处理后的DataFrame数据 + """ + categorical_cols_without_y_and_id = categorical_features.copy() + if 'id' in categorical_cols_without_y_and_id: + categorical_cols_without_y_and_id.remove('id') + if 'y' in categorical_cols_without_y_and_id: + categorical_cols_without_y_and_id.remove('y') + # 如果categorical_cols_without_y_and_id不在df_filled的col name中 报错 + if not set(categorical_cols_without_y_and_id).issubset(set(df_filled.columns)): + log.error( + f"categorical_cols_without_y_and_id is not in df_filled columns, categorical_cols_without_y_and_id:{categorical_cols_without_y_and_id}") + raise PpcException(PpcErrorCode.XGB_PREPROCESSING_ERROR.get_code(), + "categorical_cols_without_y_and_id is not in df_filled columns") + df_merged = pd.get_dummies( + df_filled, columns=categorical_cols_without_y_and_id) + + return df_merged + + +def normalize_dataframe(df: pd.DataFrame, categorical_cols: list, type: standardType = standardType.min_max.value): + """ + 对DataFrame进行标准化,排除指定的分类特征 + + 参数: + - df: 待标准化的DataFrame数据 + - categorical_cols: 列表,包含不需要标准化的分类特征的名称 + + 返回值: + 标准化后的DataFrame数据 + """ + # 创建MinMaxScaler对象 + if type == standardType.min_max.value: + scaler = MinMaxScaler() + elif type == standardType.z_score.value: + scaler = StandardScaler() + else: + log.error(f"unspport type in normalize_dataframe type:{type}") + raise PpcException(PpcErrorCode.XGB_PREPROCESSING_ERROR.get_code( + ), "unspport type in normalize_dataframe type") + + # 获取数值变量的列名 + numeric_cols = df.select_dtypes(include=['int', 'float']).columns + + # 排除指定的分类特征 + numeric_cols = [col for col in numeric_cols if col not in categorical_cols] + + # 对数值变量进行标准化 + df_normalized = df.copy() + df_normalized[numeric_cols] = scaler.fit_transform( + df_normalized[numeric_cols]) + return df_normalized + +# def calculate_correlation(df_i_col_name, df_j_col_name, i, j, col_i, col_j, categorical_cols): +# if df_i_col_name in categorical_cols or df_j_col_name in categorical_cols: +# return None # 返回NaN表示忽略这个计算 +# common_index = col_i.index.intersection(col_j.index) +# return i,j,np.corrcoef(col_i.loc[common_index], col_j.loc[common_index])[0, 1] + + +def remove_high_correlation_features(df: pd.DataFrame, categorical_cols: list, corr_select: float): + """ + 删除DataFrame中相关系数大于corr_select的特征中的一个。 + + 参数: + - df: 待处理的DataFrame数据 + - categorical_cols: 列表,包含分类特征的名称 + - corr_select: 相关系数阈值 + + 返回值: + 处理后的DataFrame数据 + """ + # ===========原有逻辑============== + # 计算特征之间的相关系数矩阵 + # num_features = df.shape[1] + # correlation_matrix = np.zeros((num_features, num_features)) + + # for i in range(num_features): + # for j in range(i+1, num_features): + # # if i == j: + # # continue + # # 忽略categorical_cols的列 + # if df.columns[i] in categorical_cols or df.columns[j] in categorical_cols: + # continue + # # 当有缺失值时 去除该行对应的缺失值进行比较, 比如col1有缺失值, col2没有, 那么col1的缺失值对应的位置,和col2一起去掉,共同参与计算 + # col_i = df.iloc[:, i].dropna() + # col_j = df.iloc[:, j].dropna() + # common_index = col_i.index.intersection(col_j.index) + # correlation_matrix[i, j] = np.corrcoef(col_i.loc[common_index], col_j.loc[common_index])[0, 1] + # # print(f"correlation_matrix: {correlation_matrix}") + # # correlation_matrix[i, j] = np.corrcoef(df.iloc[:, i], df.iloc[:, j])[0, 1] + + # # 获取相关系数大于corr_select的特征对, 获取列名 + # high_correlation = np.argwhere(np.abs(correlation_matrix) > corr_select) + + # high_correlation_col_name = [] + # for i, j in high_correlation: + # high_correlation_col_name.append((df.columns[i], df.columns[j])) + # # 删除相关性大于corr_select的特征中的一个 + # for col_left, col_right in high_correlation_col_name: + # try: + # # 如果col_left和col_right都在df中, 删除右边, 否则不动 + # if col_left in df.columns and col_right in df.columns: + # df.drop(col_right, axis=1, inplace=True) + # # df.drop(df.columns[j], axis=1, inplace=True) + # except: + # log.warning( + # f"remove_high_correlation_features error, i:{i}, j:{j}, df[col_left]:{df[col_left]}, df[col_right]:{df[col_right]}") + # pass + # return df + # ===========原有逻辑============== + num_features = df.shape[1] + correlation_matrix = np.zeros((num_features, num_features)) + + df_copy = df.copy() + for col_name in categorical_cols: + if col_name in df_copy.columns: + df_copy.drop(col_name, axis=1, inplace=True) + correlation_matrix = df_copy.corr() + # ===========尝试已提交多线程============== + # 提前设置好需要的列 + # col_list = {} + # for i in range(num_features): + # for j in range(i+1, num_features): + # col_list[i,j]=df.iloc[:, i].dropna().copy(), df.iloc[:, j].dropna().copy() + # print(correlation_matrix) + # for i in range(num_features): + # for j in range(i+1, num_features): + # result = calculate_correlation(df.columns[i], df.columns[j], i, j, df.iloc[:, i], df.iloc[:, j], categorical_cols) + # if result != None: + # i,j, correlation_matrix_i_j = result + # correlation_matrix[i,j] = correlation_matrix_i_j + # with ProcessPoolExecutor() as executor: + # col_i, col_j = col_list[i,j] + # results = [executor.submit(calculate_correlation, df.columns[i], df.columns[j], i, j, col_i, col_j, categorical_cols) for j in range(i + 1, num_features)] + # for future in as_completed(results): + # result = future.result() + # # print(f"result: {result}, {type(result)}") + # if result != None: + # i,j, correlation_matrix_i_j = result + # correlation_matrix[i,j] = correlation_matrix_i_j + # print(f"correlation_matrix: {correlation_matrix}") + # ===========尝试已提交多线程============== + high_correlation = np.argwhere(np.abs(correlation_matrix) > corr_select) + + high_correlation_col_name = [] + for i, j in high_correlation: + if i >= j: + continue + high_correlation_col_name.append( + (df_copy.columns[i], df_copy.columns[j])) + # 删除相关性大于corr_select的特征中的一个 + for col_left, col_right in high_correlation_col_name: + try: + # 如果col_left和col_right都在df中, 删除右边, 否则不动 + if col_left in df.columns and col_right in df.columns: + df.drop(col_right, axis=1, inplace=True) + # df.drop(df.columns[j], axis=1, inplace=True) + except: + log.warn( + f"remove_high_correlation_features error, i:{i}, j:{j}, df[col_left]:{df[col_left]}, df[col_right]:{df[col_right]}") + pass + return df + + +def process_psi(df_filled: pd.DataFrame, categorical_cols: list, psi_select_col: str, psi_select_base: int, + psi_select_thresh: float, psi_select_bins: int): + """ + Preprocesses the data by calculating the Population Stability Index (PSI) for a given column. + + Args: + df_filled (pd.DataFrame): The input DataFrame with missing values filled. + categorical_cols (list): A list of column names that are categorical variables. + psi_select_col (str): The name of the column for which PSI is calculated. + psi_select_base (int): The base period for calculating PSI. + psi_select_thresh (float): The threshold value for PSI. Columns with PSI above this value will be selected. + psi_select_bins (int): The number of bins to use for calculating PSI. + + Returns: + df_filled (pd.DataFrame): The input DataFrame with the PSI values calculated. + """ + # TODO: 需要验证计算psi的正确性 当为空值时 公式中没有讲如何处理 这里先按照github上的代码处理 + + # 最终所有保留的列 + psi_selected_cols = [] + + for col_select in df_filled.columns: + if col_select == psi_select_col: + # 如果是psi选择的列 则一定不保留 + continue + elif col_select in categorical_cols: + # 如果是特征列 则一定保留 + psi_selected_cols.append(col_select) + else: + # 如果是数值列 则计算psi 判断是否保留 + # 先提出base和select的数据 + psi_select_col_base_value = df_filled[col_select][df_filled[psi_select_col] + == psi_select_base].values + max_psi = 0 + for col_base in set(df_filled[psi_select_col]): + if col_base == psi_select_base: + continue + else: + col_value = df_filled[col_select][df_filled[psi_select_col] + == col_base].values + + col_psi = calculate_psi(psi_select_col_base_value, col_value, buckettype='quantiles', + buckets=psi_select_bins, axis=1) + # 如果psi值大于阈值 则保留 + if col_psi > max_psi: + max_psi = col_psi + # 如果小于阈值则保留 + if max_psi < psi_select_thresh: + psi_selected_cols.append(col_select) + + df_filled = df_filled[psi_selected_cols] + log.info(f"process_psi psi_selected_cols:{psi_selected_cols}") + return df_filled, psi_selected_cols + + +def union_column_info(column_info1: pd.DataFrame, column_info2: pd.DataFrame): + """ + union the column_info1 with the column_info2. + + Args: + column_info1 (DataFrame): The column_info1 to be merged. + column_info2 (DataFrame): The column_info2 to be merged. + + Returns: + column_info_merge (DataFrame): The union column_info. + """ + # 将column_info1和column_info2按照left_index=True, right_index=True的方式进行合并 如果列有缺失则赋值为None 行的顺序按照column_info1 + column_info_conbine = column_info1.merge( + column_info2, how='outer', left_index=True, right_index=True, sort=False) + col1_index_list = column_info1.index.to_list() + col2_index_list = column_info2.index.to_list() + merged_list = col1_index_list + \ + [item for item in col2_index_list if item not in col1_index_list] + column_info_conbine = column_info_conbine.reindex(merged_list) + return column_info_conbine diff --git a/python/ppc_model/preprocessing/local_processing/psi_select.py b/python/ppc_model/preprocessing/local_processing/psi_select.py new file mode 100644 index 00000000..3a3db8c7 --- /dev/null +++ b/python/ppc_model/preprocessing/local_processing/psi_select.py @@ -0,0 +1,95 @@ +import numpy as np + + +def scale_range(input, min, max): + input += -(np.min(input)) + input /= np.max(input) / (max - min) + input += min + return input + + +def sub_psi(e_perc, a_perc): + """ + Calculate the actual PSI value from comparing the values. + Update the actual value to a very small number if equal to zero + """ + if a_perc == 0: + a_perc = 0.0001 + if e_perc == 0: + e_perc = 0.0001 + + value = (e_perc - a_perc) * np.log(e_perc / a_perc) + return value + + +def calculate_psi(expected, actual, buckettype='bins', buckets=10, axis=0): + """ + Calculate the PSI (population stability index) across all variables + + Args: + expected: numpy matrix of original values + actual: numpy matrix of new values + buckettype: type of strategy for creating buckets, bins splits into even splits, quantiles splits into quantile buckets + buckets: number of quantiles to use in bucketing variables + axis: axis by which variables are defined, 0 for vertical, 1 for horizontal + + Returns: + psi_values: ndarray of engine values for each variable + + Author: + Matthew Burke + github.com/mwburke + mwburke.github.io.com + """ + + def psi(expected_array, actual_array, buckets): + """ + Calculate the PSI for a single variable + + Args: + expected_array: numpy array of original values + actual_array: numpy array of new values, same size as expected + buckets: number of percentile ranges to bucket the values into + + Returns: + psi_value: calculated PSI value + """ + + breakpoints = np.arange(0, buckets + 1) / (buckets) * 100 + + if buckettype == 'bins': + breakpoints = scale_range(breakpoints, np.min( + expected_array), np.max(expected_array)) + elif buckettype == 'quantiles': + breakpoints = np.stack( + [np.percentile(expected_array, b) for b in breakpoints]) + + expected_fractions = np.histogram(expected_array, breakpoints)[ + 0] / len(expected_array) + actual_fractions = np.histogram(actual_array, breakpoints)[ + 0] / len(actual_array) + psi_value = sum(sub_psi(expected_fractions[i], actual_fractions[i]) for i in range( + 0, len(expected_fractions))) + + return psi_value + + if len(actual.shape) == 1: + psi_values = np.empty(len(actual.shape)) + else: + psi_values = np.empty(actual.shape[1 - axis]) + + for i in range(0, len(psi_values)): + if len(psi_values) == 1: + psi_values = psi(expected, actual, buckets) + elif axis == 0: + if len(expected.shape) == 1: + psi_values[i] = psi(expected, actual[:, i], buckets) + else: + psi_values[i] = psi(expected[:, i], actual[:, i], buckets) + elif axis == 1: + if len(expected.shape) == 1: + psi_values[i] = psi(expected, actual[i, :], buckets) + else: + psi_values[i] = psi(expected[i, :], actual[i, :], buckets) + + return psi_values diff --git a/python/ppc_model/preprocessing/local_processing/standard_type_enum.py b/python/ppc_model/preprocessing/local_processing/standard_type_enum.py new file mode 100644 index 00000000..118e2528 --- /dev/null +++ b/python/ppc_model/preprocessing/local_processing/standard_type_enum.py @@ -0,0 +1,7 @@ +from enum import Enum, unique + + +@unique +class standardType(Enum): + min_max = "min-max" + z_score = "z-score" diff --git a/python/ppc_model/preprocessing/preprocessing_engine.py b/python/ppc_model/preprocessing/preprocessing_engine.py new file mode 100644 index 00000000..8d9a5ee5 --- /dev/null +++ b/python/ppc_model/preprocessing/preprocessing_engine.py @@ -0,0 +1,20 @@ +from ppc_model.preprocessing.local_processing.local_processing_party import LocalProcessingParty + +from ppc_model.common.global_context import components +from ppc_model.common.protocol import ModelTask +from ppc_model.interface.task_engine import TaskEngine +from ppc_model.preprocessing.processing_context import ProcessingContext + + +class PreprocessingEngine(TaskEngine): + task_type = ModelTask.PREPROCESSING + + @staticmethod + def run(task_id, args): + context = ProcessingContext( + task_id=task_id, + args=args, + components=components, + ) + lpp = LocalProcessingParty(context) + lpp.processing() diff --git a/python/ppc_model/preprocessing/processing_context.py b/python/ppc_model/preprocessing/processing_context.py new file mode 100644 index 00000000..37b5dfae --- /dev/null +++ b/python/ppc_model/preprocessing/processing_context.py @@ -0,0 +1,27 @@ +import os + +from ppc_model.common.context import Context +from ppc_model.common.initializer import Initializer +from ppc_common.ppc_utils import common_func +from ppc_model.common.model_setting import ModelSetting + + +class ProcessingContext(Context): + def __init__(self, + task_id, + args, + components: Initializer): + super().__init__(job_id=args['job_id'], + task_id=task_id, + components=components, + role=None, + user=args["user"]) + self.dataset_path = args['dataset_path'] + self.dataset_file_path = os.path.join( + self.workspace, args['dataset_id']) + self.job_algorithm_type = args['algorithm_type'] + self.need_run_psi = args['need_run_psi'] + self.model_dict = args['model_dict'] + if "psi_result_path" in args: + self.remote_psi_result_path = args["psi_result_path"] + self.model_setting = ModelSetting(self.model_dict) diff --git a/python/ppc_model/preprocessing/tests/test_preprocessing.py b/python/ppc_model/preprocessing/tests/test_preprocessing.py new file mode 100644 index 00000000..244c6a41 --- /dev/null +++ b/python/ppc_model/preprocessing/tests/test_preprocessing.py @@ -0,0 +1,675 @@ +from ppc_common.ppc_utils import utils +from local_processing.preprocessing import union_column_info, process_na_dataframe, process_na_fill_dataframe, process_outliers, one_hot_encode_and_merge, normalize_dataframe, process_train_dataframe, remove_high_correlation_features, process_psi, process_dataframe +import pandas as pd +import numpy as np +import pytest +import json +import sys + +from ppc_model.preprocessing.local_processing.standard_type_enum import standardType +# import pytest +import numpy as np +import pandas as pd +from ppc_model.preprocessing.local_processing.preprocessing import union_column_info, process_na_dataframe, process_na_fill_dataframe, process_outliers, one_hot_encode_and_merge, normalize_dataframe, process_train_dataframe, remove_high_correlation_features, process_psi, process_dataframe +from ppc_common.ppc_utils import utils + + +def test_process_na_dataframe(): + # Create a sample DataFrame with missing values + df = pd.DataFrame({ + 'col1': [1, 2, None, 4, 5], + 'col2': [None, 2, None, 4, None], + 'col3': [1, 2, 3, 4, 5], + 'col4': [1, None, 3, 4, 5], + 'col5': [1, 2, None, None, None], + 'y': [0, 1, 0, 1, 0] + }) + + # Define the expected output DataFrame + expected_output = pd.DataFrame({ + 'col1': [1, 2, 3.0, 4, 5], + 'col3': [1, 2, 3, 4, 5], + 'col4': [1, 6.0, 3, 4, 5], + 'y': [0, 1, 0, 1, 0] + }) + expected_column_info = {'col1': {'missing_ratio': 0.2, 'na_selected': 1, 'isExisted': True}, + 'col2': {'missing_ratio': 0.6, 'na_selected': 0, 'isExisted': False}, + 'col3': {'missing_ratio': 0.0, 'na_selected': 1, 'isExisted': True}, + 'col4': {'missing_ratio': 0.2, 'na_selected': 1, 'isExisted': True}, + 'col5': {'missing_ratio': 0.6, 'na_selected': 0, 'isExisted': False}, + 'y': {'missing_ratio': 0.0, 'na_selected': 1, 'isExisted': True}} + + # Call the function under test + processed_df, column_info = process_na_dataframe(df, 0.5) + assert column_info == expected_column_info + processed_df = process_na_fill_dataframe(processed_df, ['col2', 'col4']) + + # Assert that the processed DataFrame matches the expected output + assert processed_df.equals(expected_output) + + +def test_process_nan_dataframe(): + # Create a sample DataFrame with missing values + df = pd.DataFrame({ + 'col1': [1, 2, None, 4, 5], + 'col2': [None, 2, None, 4, None], + 'col3': [1, 2, 3, 4, 5], + 'col4': [1, None, 3, 4, 5], + 'col5': [1, 2, None, None, None], + 'y': [0, 1, 0, 1, 0] + }) + + # Define the expected output DataFrame + expected_output = pd.DataFrame({ + 'col1': [1, 2, np.nan, 4, 5], + 'col2': [np.nan, 2, np.nan, 4, np.nan], + 'col3': [1, 2, 3, 4, 5], + 'col4': [1, np.nan, 3, 4, 5], + 'col5': [1, 2, np.nan, np.nan, np.nan], + 'y': [0, 1, 0, 1, 0] + }) + + # Call the function under test + processed_df = df.replace('None', np.nan) + + # Assert that the processed DataFrame matches the expected output + assert processed_df.equals(expected_output) + + +def test_process_outliers(): + # Create a sample DataFrame with outliers + df = pd.DataFrame({ + 'col3': [100, 200, None, 400, 500, 100, 200, 300, 400, 500, 100, 200, None, 400, 500], + 'col5': [100000, None, 1, -1, 1, -1, 1, -1, 1, 1, -1, None, None, None, 1], + }) + # + # outlier = np.random.normal(df['col5'].mean() + 3 * df['col5'].std(), df['col5'].std()) + # df.at[1, 'col5'] = outlier + + # Define the expected output DataFrame + expected_output = pd.DataFrame({ + 'col3': [100, 200, None, 400, 500, 100, 200, 300, 400, 500, 100, 200, None, 400, 500], + 'col5': [df['col5'].mean(), None, 1, -1, 1, -1, 1, -1, 1, 1, -1, None, None, None, 1], + }) + + # Call the function under test + processed_df = process_outliers(df, []) + + # Assert that the processed DataFrame matches the expected output + assert processed_df.equals(expected_output) + + +def test_one_hot_encode_and_merge(): + # Create a sample DataFrame + df = pd.DataFrame({ + 'col1': [1, 2, 3, 4, 5], + 'col2': ['A', 'B', 'C', 'A', 'B'], + 'col3': ['X', 'Y', 'Z', 'X', 'Y'], + 'y': [0, 1, 0, 1, 0] + }) + + # Define the expected output DataFrame + expected_output = pd.DataFrame({ + 'col1': [1, 2, 3, 4, 5], + 'y': [0, 1, 0, 1, 0], + 'col2_A': [True, False, False, True, False], + 'col2_B': [False, True, False, False, True], + 'col2_C': [False, False, True, False, False], + 'col3_X': [True, False, False, True, False], + 'col3_Y': [False, True, False, False, True], + 'col3_Z': [False, False, True, False, False] + }) + + # Call the function under test + processed_df = one_hot_encode_and_merge(df, ['col2', 'col3']) + + # Assert that the processed DataFrame matches the expected output + assert processed_df.equals(expected_output) + + +def test_normalize_dataframe(): + # Create a sample DataFrame + df = pd.DataFrame({ + 'col1': [1, 2, None, 4, 5], + 'col2': ['A', 'B', 'C', 'A', 'B'], + 'col3': ['X', 'Y', 'Z', 'X', 'Y'], + 'col4': [10, 20, 30, 40, 50], + 'col5': [100, 200, None, 400, 500] + }) + + # Define the expected output DataFrame + expected_output = pd.DataFrame({ + 'col1': [0.0, 0.25, None, 0.75, 1.0], + 'col2': ['A', 'B', 'C', 'A', 'B'], + 'col3': ['X', 'Y', 'Z', 'X', 'Y'], + 'col4': [0.0, 0.25, 0.5, 0.75, 1.0], + 'col5': [0.0, 0.25, None, 0.75, 1.0] + }) + + # Call the function under test + processed_df = normalize_dataframe( + df, ['col2', 'col3'], standardType.min_max.value) + assert processed_df.equals(expected_output) + + # Define the expected output DataFrame + expected_output = pd.DataFrame({ + 'col1': [-1.265, -0.632, None, 0.632, 1.265], + 'col2': ['A', 'B', 'C', 'A', 'B'], + 'col3': ['X', 'Y', 'Z', 'X', 'Y'], + 'col4': [-1.414, -0.707, 0.0, 0.707, 1.414], + 'col5': [-1.265, -0.632, None, 0.632, 1.265] + }) + # Call the function under test + processed_df = normalize_dataframe( + df, ['col2', 'col3'], standardType.z_score.value) + # Assert that the processed DataFrame matches the expected output + print(expected_output) + print(processed_df) + assert processed_df.round(3).equals(expected_output) + + +def test_remove_high_correlation_features(): + # Create a sample DataFrame + df = pd.DataFrame({ + 'col1': [1, 2, 3, 4, 5], + 'col2': [2, 4, 6, 8, 10], + 'col3': [3, 6, 9, 12, 15], + 'col4': [4, 8, 12, 16, 20], + 'col5': [5, 10, 15, 20, 25], + 'y': [0, 1, 0, 1, 0] + }) + + # Define the expected output DataFrame + expected_output = pd.DataFrame({ + 'col1': [1, 2, 3, 4, 5], + 'y': [0, 1, 0, 1, 0] + }) + + # Call the function under test + processed_df = remove_high_correlation_features(df, ['y'], 0.8) + + df = pd.DataFrame({ + 'col1': [1, 2, 3, 4, 5], + 'col2': [2, 4, None, 8, 10], + 'col3': [3, 6, 9, 12, 15], + 'col4': [4, None, 12, 16, 20], + 'col5': [5, 10, None, 20, 25], + 'y': [0, 1, 0, 1, 0] + }) + + # Define the expected output DataFrame + expected_output = pd.DataFrame({ + 'col1': [1, 2, 3, 4, 5], + 'y': [0, 1, 0, 1, 0] + }) + processed_df = remove_high_correlation_features(df, ['y'], 0.8) + print(f"processed_df:{processed_df}") + print(f"expected_output:{expected_output}") + # Assert that the processed DataFrame matches the expected output + assert processed_df.equals(expected_output) + + df = pd.DataFrame({ + 'col1': [-1, 222, 3.4, -22, 5.1], + 'col2': [2, None, 6, 8, 10], + 'col3': [3, 6, 9, 12, 15], + 'col4': [4, None, 12, 16, 20], + 'col5': [5, 10, None, 20, 25], + 'y': [0, 1, 0, 1, 0] + }) + + # Define the expected output DataFrame + expected_output = pd.DataFrame({ + 'col1': [-1, 222, 3.4, -22, 5.1], + 'col2': [2, None, 6, 8, 10], + 'y': [0, 1, 0, 1, 0] + }) + processed_df = remove_high_correlation_features(df, ['y'], 0.8) + + print(processed_df) + + # Assert that the processed DataFrame matches the expected output + assert processed_df.equals(expected_output) + + +def test_process_psi(): + # Create a sample DataFrame + df_filled = pd.DataFrame({ + # 'col1': [0, 1, 0, 1, 0], + 'col1': [1, 2, 3, 4, 5], + 'col2': ['A', 'B', 'C', 'A', 'B'], + 'col3': ['X', 'Y', 'Z', 'X', 'Y'], + 'col4': [10, 20, 30, 40, 50], + 'col5': [100, 200, 300, 400, 500], + 'y': [0, 1, 0, 1, 0] + }) + + # Define the expected output DataFrame + expected_output = pd.DataFrame({ + 'col2': ['A', 'B', 'C', 'A', 'B'], + 'col3': ['X', 'Y', 'Z', 'X', 'Y'], + 'y': [0, 1, 0, 1, 0] + }) + + # Call the function under test + processed_df, _ = process_psi( + df_filled, ['col2', 'col3', 'y'], 'col1', 1, 0.9, 5) + + # Assert that the processed DataFrame matches the expected output + assert processed_df.equals(expected_output) + + # read test csv as DataFrame + test_file_path = "./癌症纵向训练数据集psi.csv" + df_filled = pd.read_csv(test_file_path) + expected_output_col = ['id', 'y', 'x1', 'x5', + 'x6', 'x9', 'x10', 'x11', 'x12', 'x14'] + processed_df, _ = process_psi( + df_filled, ['id', 'y', 'x1', 'x5', 'x23'], 'x15', 0, 0.3, 4) + + assert processed_df.columns.tolist() == expected_output_col + + +def test_process_dataframe(): + # Create a sample DataFrame + test_file_path = "./癌症纵向训练数据集psi.csv" + df_filled = pd.read_csv(test_file_path) + + # Create a mock JobContext object + xgb_model = { + "algorithm_subtype": "HeteroXGB", + "participants": 2, # 提供数据集机构数 + # XGBoost参数 + "use_psi": 0, # 0否,1是 + "use_goss": 0, # 0否,1是 + "test_dataset_percentage": 0.3, + "learning_rate": 0.1, + "num_trees": 6, + "max_depth": 3, + "max_bin": 4, # 分箱数(计算XGB直方图) + "threads": 8, + # 调度服务各方预处理 + "na_select": 0.8, # 缺失值筛选阈值,缺失值比例超过阈值则移除该特征(0表示只要有缺失值就移除,1表示仅移除全为缺失值的列) + "fillna": 0, # 是否缺失值填充(均值) + "psi_select_col": "x15", # PSI稳定性筛选时间列名称(0代表不进行PSI筛选,例如:"month") + "psi_select_base": 1, # PSI稳定性筛选时间基期(例如以0为基期,统计其他时间的psi,时间按照周/月份/季度等提前处理为0,1,2,...,n格式) + "psi_select_thresh": 0.3, # 若最大的逐月PSI>0.1,则剔除该特征 + "psi_select_bins": 4, # 计算逐月PSI时分箱数 + "filloutlier": 1, # 是否异常值处理(+-3倍标准差使用均值填充) + "normalized": 1, # 是否归一化,每个值减去最小值,然后除以最大值与最小值的差 + "standardized": 1, # 是否标准化,计算每个数据点与均值的差,然后除以标准差 + "one_hot": 0, # 是否进行onehot + # 指定分类特征索引,例如"x1,x12,x23" ("0"代表无分类特征)(分类特征需要在此处标注,使用onehot预处理/建模) + "categorical": "id,y,x1,x5,x23", + # 建模节点特征工程 + "use_iv": 0, # 是否计算woe/iv,并使用iv进行特征筛选 + 'group_num': 3, # 分箱数(计算woe分箱,等频) + 'iv_thresh': 0.1, # 使用iv进行特征筛选的阈值(仅保留iv大于阈值的特征) + 'corr_select': 0.8 # 计算特征相关性,相关性大于阈值特征仅保留iv最大的(如use_iv=0,则随机保留一个)(corr_select=0时不进行相关性筛选) + } + + xgb_dict = dict() + # 根据xgb_model 生成xgb_dict + for key, value in xgb_model.items(): + xgb_dict[key] = value + + # Call the function under test + column_info1 = process_dataframe( + df_filled, xgb_dict, "./xgb_data_file_path", utils.AlgorithmType.Train.name, "j-123456") + + xgb_model = { + "algorithm_subtype": "HeteroXGB", + "participants": 2, # 提供数据集机构数 + # XGBoost参数 + "use_psi": 0, # 0否,1是 + "use_goss": 0, # 0否,1是 + "test_dataset_percentage": 0.3, + "learning_rate": 0.1, + "num_trees": 6, + "max_depth": 3, + "max_bin": 4, # 分箱数(计算XGB直方图) + "threads": 8, + # 调度服务各方预处理 + "na_select": 0.8, # 缺失值筛选阈值,缺失值比例超过阈值则移除该特征(0表示只要有缺失值就移除,1表示仅移除全为缺失值的列) + "fillna": 1, # 是否缺失值填充(均值) + "psi_select_col": "x15", # PSI稳定性筛选时间列名称(0代表不进行PSI筛选,例如:"month") + "psi_select_base": 1, # PSI稳定性筛选时间基期(例如以0为基期,统计其他时间的psi,时间按照周/月份/季度等提前处理为0,1,2,...,n格式) + "psi_select_thresh": 0.3, # 若最大的逐月PSI>0.1,则剔除该特征 + "psi_select_bins": 4, # 计算逐月PSI时分箱数 + "filloutlier": 1, # 是否异常值处理(+-3倍标准差使用均值填充) + "normalized": 1, # 是否归一化,每个值减去最小值,然后除以最大值与最小值的差 + "standardized": 1, # 是否标准化,计算每个数据点与均值的差,然后除以标准差 + "one_hot": 0, # 是否进行onehot + # 指定分类特征索引,例如"x1,x12,x23" ("0"代表无分类特征)(分类特征需要在此处标注,使用onehot预处理/建模) + "categorical": "id,y,x1,x5,x23", + # 建模节点特征工程 + "use_iv": 0, # 是否计算woe/iv,并使用iv进行特征筛选 + 'group_num': 3, # 分箱数(计算woe分箱,等频) + 'iv_thresh': 0.1, # 使用iv进行特征筛选的阈值(仅保留iv大于阈值的特征) + 'corr_select': 0.8 # 计算特征相关性,相关性大于阈值特征仅保留iv最大的(如use_iv=0,则随机保留一个)(corr_select=0时不进行相关性筛选) + } + for key, value in xgb_model.items(): + xgb_dict[key] = value + column_info2 = process_dataframe( + df_filled, xgb_dict, "./xgb_data_file_path2", utils.AlgorithmType.Train.name, "j-123456") + assert column_info1 == column_info2 + expected_column_info = {'y': {'missing_ratio': 0.0, + 'na_selected': 1, + 'psi_selected': 1, + 'corr_selected': 1, + 'isExisted': True + }, + 'x0': {'missing_ratio': 0.0, + 'na_selected': 1, + 'psi_selected': 1, + 'corr_selected': 1, + 'isExisted': True + }, + 'x1': {'missing_ratio': 0.0, + 'na_selected': 1, + 'psi_selected': 1, + 'corr_selected': 1, + 'isExisted': True + }, + 'x2': {'missing_ratio': 0.0, + 'na_selected': 1, + 'psi_selected': 1, + 'corr_selected': 0, + 'isExisted': False + }, + 'x3': {'missing_ratio': 0.0, + 'na_selected': 1, + 'psi_selected': 1, + 'corr_selected': 0, + 'isExisted': False + }, + 'x4': {'missing_ratio': 0.0, + 'na_selected': 1, + 'psi_selected': 0, + 'corr_selected': 0, + 'isExisted': False + }, + 'x5': {'missing_ratio': 0.0, + 'na_selected': 1, + 'psi_selected': 1, + 'corr_selected': 1, + 'isExisted': True + }, + 'x6': {'missing_ratio': 0.018, + 'na_selected': 1, + 'psi_selected': 1, + 'corr_selected': 1, + 'isExisted': True + }, + 'x7': {'missing_ratio': 0.0, + 'na_selected': 1, + 'psi_selected': 0, + 'corr_selected': 0, + 'isExisted': False + }, + 'x8': {'missing_ratio': 0.0, + 'na_selected': 1, + 'psi_selected': 1, + 'corr_selected': 1, + 'isExisted': True + }, + 'x9': {'missing_ratio': 0.0, + 'na_selected': 1, + 'psi_selected': 1, + 'corr_selected': 1, + 'isExisted': True + }, + 'x10': {'missing_ratio': 0.012, + 'na_selected': 1, + 'psi_selected': 1, + 'corr_selected': 1, + 'isExisted': True + }, + 'x11': {'missing_ratio': 0.998, + 'na_selected': 0, + 'psi_selected': 0, + 'corr_selected': 0, + 'isExisted': False + }, + 'x12': {'missing_ratio': 0.0, + 'na_selected': 1, + 'psi_selected': 1, + 'corr_selected': 0, + 'isExisted': False + }, + 'x13': {'missing_ratio': 0.0, + 'na_selected': 1, + 'psi_selected': 1, + 'corr_selected': 0, + 'isExisted': False + }, + 'x14': {'missing_ratio': 0.0, + 'na_selected': 1, + 'psi_selected': 1, + 'corr_selected': 1, + 'isExisted': True + }, + 'x15': {'missing_ratio': 0.0, + 'na_selected': 1, + 'psi_selected': 0, + 'corr_selected': 0, + 'isExisted': False + } + } + # 转成python字典 + expected_column_info_dict = dict(expected_column_info) + assert column_info1 == expected_column_info_dict + + +def test_process_train_dataframe(): + # Create a sample DataFrame + df = pd.DataFrame({ + 'id': [1, 2, 3, 4, 5], + 'x1': [10, 20, 30, 40, 50], + 'x2': [100, 200, 300, 400, 500], + 'x3': [1000, 2000, 3000, 4000, 5000], + 'x4': [10000, 20000, 30000, 40000, 50000], + 'x5': [100000, 200000, 300000, 400000, 500000], + 'y': [0, 1, 0, 1, 0] + }) + + # Define the expected output DataFrame + expected_output = pd.DataFrame({ + 'id': [1, 2, 3, 4, 5], + 'x2': [100, 200, 300, 400, 500], + 'x3': [1000, 2000, 3000, 4000, 5000] + }) + + # Define the column_info dictionary + column_info = { + 'id': {'isExisted': True}, + 'x1': {'isExisted': False}, + 'x2': {'isExisted': True}, + 'x3': {'isExisted': True}, + 'x4': {'isExisted': False}, + 'x5': {'isExisted': False}, + 'y': {'isExisted': False}, + } + + # Call the function under test + processed_df = process_train_dataframe(df, column_info) + + # Assert that the processed DataFrame matches the expected output + assert processed_df.equals(expected_output) + + +def test_process_train_dataframe_with_additional_columns(): + # Create a sample DataFrame + df = pd.DataFrame({ + 'id': [1, 2, 3, 4, 5], + 'x1': [10, 20, 30, 40, 50], + 'x2': [100, 200, 300, 400, 500], + 'x3': [1000, 2000, 3000, 4000, 5000], + 'x4': [10000, 20000, 30000, 40000, 50000], + 'x5': [100000, 200000, 300000, 400000, 500000], + 'y': [0, 1, 0, 1, 0] + }) + + # Define the expected output DataFrame + expected_output = pd.DataFrame({ + 'id': [1, 2, 3, 4, 5], + 'x1': [10, 20, 30, 40, 50], + 'x3': [1000, 2000, 3000, 4000, 5000], + 'x4': [10000, 20000, 30000, 40000, 50000], + 'x5': [100000, 200000, 300000, 400000, 500000] + }) + + # Define the column_info dictionary + column_info = { + 'id': {'isExisted': True}, + 'x1': {'isExisted': True}, + 'x2': {'isExisted': False}, + 'x3': {'isExisted': True}, + 'x4': {'isExisted': True}, + 'x5': {'isExisted': True}, + 'y': {'isExisted': False}, + } + + # Call the function under test + processed_df = process_train_dataframe(df, column_info) + + # Assert that the processed DataFrame matches the expected output + assert processed_df.equals(expected_output) + + +def test_merge_column_info_from_file(): + col_info_file_path = "./test_column_info_merge.csv" + iv_info_file_path = "./test_column_info_iv.csv" + column_info_fm = pd.read_csv(col_info_file_path, index_col=0) + column_info_iv = pd.read_csv(iv_info_file_path, index_col=0) + union_df = union_column_info(column_info_fm, column_info_iv) + + col_str_expected = '{"y": {"missing_ratio": 0.0, "na_selected": 1, "isExisted": true, "psi_selected": 1, "corr_selected": 1}, "x0": {"missing_ratio": 0.0, "na_selected": 1, "isExisted": true, "psi_selected": 1, "corr_selected": 1}, "x1": {"missing_ratio": 0.0, "na_selected": 1, "isExisted": true, "psi_selected": 1, "corr_selected": 1}, "x2": {"missing_ratio": 0.0, "na_selected": 1, "isExisted": false, "psi_selected": 1, "corr_selected": 0}, "x3": {"missing_ratio": 0.0, "na_selected": 1, "isExisted": false, "psi_selected": 1, "corr_selected": 0}, "x4": {"missing_ratio": 0.0, "na_selected": 1, "isExisted": false, "psi_selected": 0, "corr_selected": 0}, "x5": {"missing_ratio": 0.0, "na_selected": 1, "isExisted": true, "psi_selected": 1, "corr_selected": 1}, "x6": {"missing_ratio": 0.018, "na_selected": 1, "isExisted": true, "psi_selected": 1, "corr_selected": 1}, "x7": {"missing_ratio": 0.0, "na_selected": 1, "isExisted": false, "psi_selected": 0, "corr_selected": 0}, "x8": {"missing_ratio": 0.0, "na_selected": 1, "isExisted": true, "psi_selected": 1, "corr_selected": 1}, "x9": {"missing_ratio": 0.0, "na_selected": 1, "isExisted": true, "psi_selected": 1, "corr_selected": 1}, "x10": {"missing_ratio": 0.012, "na_selected": 1, "isExisted": true, "psi_selected": 1, "corr_selected": 1}, "x11": {"missing_ratio": 0.998, "na_selected": 0, "isExisted": false, "psi_selected": 0, "corr_selected": 0}, "x12": {"missing_ratio": 0.0, "na_selected": 1, "isExisted": false, "psi_selected": 1, "corr_selected": 0}, "x13": {"missing_ratio": 0.0, "na_selected": 1, "isExisted": false, "psi_selected": 1, "corr_selected": 0}, "x14": {"missing_ratio": 0.0, "na_selected": 1, "isExisted": true, "psi_selected": 1, "corr_selected": 1}, "x15": {"missing_ratio": 0.0, "na_selected": 1, "isExisted": false, "psi_selected": 0, "corr_selected": 0}}' + + # expected_df_file_path = './test_union_column.csv' + # expected_df = pd.read_csv(expected_df_file_path, index_col=0) + # assert expected_df.equals(union_df) + column_info_str = json.dumps(column_info_fm.to_dict(orient='index')) + assert column_info_str == col_str_expected + + +def construct_dataset(num_samples, num_features, file_path): + np.random.seed(0) + # 生成标签列 + labels = np.random.choice([0, 1], size=num_samples) + # 生成特征列 + features = np.random.rand(num_samples, num_features) + # 将标签转换为DataFrame + labels_df = pd.DataFrame(labels, columns=['Label']) + + # 将特征转换为DataFrame + features_df = pd.DataFrame(features) + + # 合并标签和特征DataFrame + dataset_df = pd.concat([labels_df, features_df], axis=1) + + # 将DataFrame写入CSV文件 + dataset_df.to_csv(file_path, index=False) + + return labels, features + + +def test_gen_file(): + num_samples = 400000 + num_features = 100 + file_path = "./dataset-{}-{}.csv".format(num_samples, num_features) + construct_dataset(num_samples, num_features, file_path) + + +def test_large_process_train_dataframe(): + num_samples = 400000 + num_features = 100 + test_file_path = "./dataset-{}-{}.csv".format(num_samples, num_features) + df_filled = pd.read_csv(test_file_path) + + # Create a mock JobContext object + xgb_model = { + "algorithm_subtype": "HeteroXGB", + "participants": 2, # 提供数据集机构数 + # XGBoost参数 + "use_psi": 0, # 0否,1是 + "use_goss": 0, # 0否,1是 + "test_dataset_percentage": 0.3, + "learning_rate": 0.1, + "num_trees": 6, + "max_depth": 3, + "max_bin": 4, # 分箱数(计算XGB直方图) + "threads": 8, + # 调度服务各方预处理 + "na_select": 0.8, # 缺失值筛选阈值,缺失值比例超过阈值则移除该特征(0表示只要有缺失值就移除,1表示仅移除全为缺失值的列) + "fillna": 0, # 是否缺失值填充(均值) + "psi_select_col": 0, # PSI稳定性筛选时间列名称(0代表不进行PSI筛选,例如:"month") + "psi_select_base": 1, # PSI稳定性筛选时间基期(例如以0为基期,统计其他时间的psi,时间按照周/月份/季度等提前处理为0,1,2,...,n格式) + "psi_select_thresh": 0.3, # 若最大的逐月PSI>0.1,则剔除该特征 + "psi_select_bins": 4, # 计算逐月PSI时分箱数 + "filloutlier": 1, # 是否异常值处理(+-3倍标准差使用均值填充) + "normalized": 1, # 是否归一化,每个值减去最小值,然后除以最大值与最小值的差 + "standardized": 1, # 是否标准化,计算每个数据点与均值的差,然后除以标准差 + "one_hot": 0, # 是否进行onehot + # 指定分类特征索引,例如"x1,x12,x23" ("0"代表无分类特征)(分类特征需要在此处标注,使用onehot预处理/建模) + "categorical": "id,y,1,5,23", + # 建模节点特征工程 + "use_iv": 0, # 是否计算woe/iv,并使用iv进行特征筛选 + 'group_num': 3, # 分箱数(计算woe分箱,等频) + 'iv_thresh': 0.1, # 使用iv进行特征筛选的阈值(仅保留iv大于阈值的特征) + 'corr_select': 0.8 # 计算特征相关性,相关性大于阈值特征仅保留iv最大的(如use_iv=0,则随机保留一个)(corr_select=0时不进行相关性筛选) + } + + xgb_dict = dict() + # 根据xgb_model 生成xgb_dict + for key, value in xgb_model.items(): + xgb_dict[key] = value + + # Call the function under test + start_time = time.time() + column_info1 = process_dataframe( + df_filled, xgb_dict, "./xgb_data_file_path", utils.AlgorithmType.Train.name, "j-123456") + end_time = time.time() + print( + f"test_large_process_train_dataframe time cost:{end_time-start_time}, num_samples: {num_samples}, num_features: {num_features}") + + +# Run the tests +# pytest.main() +if __name__ == "__main__": + import time + # test_large_process_train_dataframe() + time1 = time.time() + test_process_na_dataframe() + time2 = time.time() + test_process_nan_dataframe() + time3 = time.time() + test_process_outliers() + time4 = time.time() + test_one_hot_encode_and_merge() + time5 = time.time() + test_normalize_dataframe() + time6 = time.time() + test_remove_high_correlation_features() + time7 = time.time() + test_process_psi() + time8 = time.time() + test_process_dataframe() + time9 = time.time() + test_process_train_dataframe() + time10 = time.time() + test_process_train_dataframe_with_additional_columns() + time11 = time.time() + test_merge_column_info_from_file() + time12 = time.time() + print(f"test_process_na_dataframe time cost: {time2-time1}") + print(f"test_process_nan_dataframe time cost: {time3-time2}") + print(f"test_process_outliers time cost: {time4-time3}") + print(f"test_one_hot_encode_and_merge time cost: {time5-time4}") + print(f"test_normalize_dataframe time cosy: {time6-time5}") + print(f"test_remove_high_correlation_features time cost: {time7-time6}") + print(f"test_process_psi time cost: {time8-time7}") + print(f"test_process_dataframe time cost: {time9-time8}") + print(f"test_process_train_dataframe time cost: {time10-time9}") + print( + f"test_process_train_dataframe_with_additional_columns time cost: {time11-time10}") + print(f"test_merge_column_info_from_file time cost: {time12-time11}") + print("All tests pass!") diff --git a/python/ppc_model/secure_lgbm/__init__.py b/python/ppc_model/secure_lgbm/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/python/ppc_model/secure_lgbm/monitor/__init__.py b/python/ppc_model/secure_lgbm/monitor/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/python/ppc_model/secure_lgbm/monitor/callback.py b/python/ppc_model/secure_lgbm/monitor/callback.py new file mode 100644 index 00000000..cd145668 --- /dev/null +++ b/python/ppc_model/secure_lgbm/monitor/callback.py @@ -0,0 +1,85 @@ +from abc import ABC +from typing import ( + Callable, + Optional, + Sequence +) + +import numpy as np + +from ppc_model.secure_lgbm.monitor.core import _Model + + +class TrainingCallback(ABC): + def __init__(self) -> None: + pass + + def before_training(self, model: _Model) -> _Model: + """Run before training starts.""" + return model + + def after_training(self, model: _Model) -> _Model: + """Run after training is finished.""" + return model + + def before_iteration(self, model: _Model, epoch: int) -> bool: + """Run before each iteration. Returns True when training should stop.""" + return False + + def after_iteration(self, model: _Model, epoch: int) -> bool: + """Run after each iteration. Returns `True` when training should stop.""" + return False + + +class CallbackContainer: + """A special internal callback for invoking a list of other callbacks.""" + + def __init__( + self, + callbacks: Sequence[TrainingCallback], + feval: Optional[Callable] = None + ) -> None: + self.callbacks = set(callbacks) + for cb in callbacks: + if not isinstance(cb, TrainingCallback): + raise TypeError( + "callback must be an instance of `TrainingCallback`.") + + msg = ( + "feval must be callable object for monitoring. For builtin metrics" + ", passing them in training parameter invokes monitor automatically." + ) + if feval is not None and not callable(feval): + raise TypeError(msg) + + self.feval = feval + + def before_training(self, model: _Model) -> _Model: + for c in self.callbacks: + model = c.before_training(model=model) + return model + + def after_training(self, model: _Model) -> _Model: + for c in self.callbacks: + model = c.after_training(model=model) + return model + + def before_iteration( + self, + model: _Model + ) -> bool: + return any( + c.before_iteration(model, model.get_epoch()) for c in self.callbacks + ) + + def after_iteration( + self, + model: _Model, + pred: np.ndarray, + eval_on_test: bool = True + ) -> bool: + model.after_iteration(pred, eval_on_test) + model.eval(self.feval) + ret = any(c.after_iteration(model, model.get_epoch()) + for c in self.callbacks) + return ret diff --git a/python/ppc_model/secure_lgbm/monitor/core.py b/python/ppc_model/secure_lgbm/monitor/core.py new file mode 100644 index 00000000..5c66ad8a --- /dev/null +++ b/python/ppc_model/secure_lgbm/monitor/core.py @@ -0,0 +1,147 @@ +import collections +from typing import Dict, Any, Union, Tuple, List, Callable +from ppc_model.common.base_context import BaseContext +import numpy as np +from sklearn import metrics + +_Score = Union[float, Tuple[float, float]] +_ScoreList = Union[List[float], List[Tuple[float, float]]] + +_BoosterParams = Dict[str, Any] +_Metric = Callable[[np.ndarray, np.ndarray], Dict[str, _Score]] + +""" +A dictionary containing the evaluation history: +{"metric_name": [0.5, ...]} +""" +_EvalsLog = Dict[str, _ScoreList] + + +class Booster: + """A Booster of XGBoost. + + Booster is the model of xgboost, that contains low level routines for + training, prediction and evaluation. + """ + + def __init__( + self, + y_true: np.ndarray, + test_y_true: np.ndarray, + ctx: BaseContext = None, + workspace: str = None, + job_id: str = None, + storage_client: str = None + ) -> None: + self.params: _BoosterParams = {} + self.ctx = ctx + self.y_true = y_true + self.test_y_true = test_y_true + self.y_pred = None + self.test_y_pred = None + self.eval_on_test = True + self.epoch = 0 + self.workspace = workspace + self.job_id = job_id + + self.storage_client = storage_client + self.history: _EvalsLog = collections.OrderedDict() + + def get_y_true(self) -> np.ndarray: + return self.y_true + + def get_test_y_true(self) -> np.ndarray: + return self.test_y_true + + def get_y_pred(self) -> np.ndarray: + return self.y_pred + + def get_test_y_pred(self) -> np.ndarray: + return self.test_y_pred + + def get_epoch(self) -> int: + return self.epoch + + def get_workspace(self) -> str: + return self.workspace + + def get_job_id(self) -> str: + return self.job_id + + def get_storage_client(self): + return self.storage_client + + def set_param( + self, + key: str, + value: Any, + ) -> None: + self.params[key] = value + + def get_param( + self, + key: str + ) -> Any: + return self.params[key] + + def get_history(self) -> _EvalsLog: + return self.history + + def after_iteration( + self, + pred: np.ndarray, + eval_on_test: bool = True + ) -> None: + if eval_on_test: + self.test_y_pred = pred + else: + self.y_pred = pred + self.eval_on_test = eval_on_test + self.epoch += 1 + + def _update_history( + self, + scores: Dict[str, _Score] + ) -> None: + for key, value in scores.items(): + if key in self.history: + self.history[key].append(value) + else: + self.history[key] = [value] + + def eval( + self, + feval: _Metric + ) -> Dict[str, _Score]: + if self.eval_on_test: + scores = feval(self.test_y_true, self.test_y_pred) + else: + scores = feval(self.y_true, self.y_pred) + self._update_history(scores) + return scores + + +_Model = Booster + + +def fevaluation( + y_true: np.ndarray, + y_pred: np.ndarray, + decimal_num: int = 4 +) -> Dict[str, _Score]: + auc = metrics.roc_auc_score(y_true, y_pred) + + y_pred_label = [0 if p <= 0.5 else 1 for p in y_pred] + acc = metrics.accuracy_score(y_true, y_pred_label) + recall = metrics.recall_score(y_true, y_pred_label) + precision = metrics.precision_score(y_true, y_pred_label) + + scores_dict = { + 'auc': auc, + 'acc': acc, + 'recall': recall, + 'precision': precision + } + for metric_name in scores_dict: + scores_dict[metric_name] = round(scores_dict[metric_name], decimal_num) + return scores_dict diff --git a/python/ppc_model/secure_lgbm/monitor/early_stopping.py b/python/ppc_model/secure_lgbm/monitor/early_stopping.py new file mode 100644 index 00000000..c6140680 --- /dev/null +++ b/python/ppc_model/secure_lgbm/monitor/early_stopping.py @@ -0,0 +1,123 @@ +from typing import Optional, cast + +import numpy + +from ppc_model.secure_lgbm.monitor.callback import TrainingCallback +from ppc_model.secure_lgbm.monitor.core import _Score, _ScoreList, _Model, _EvalsLog + + +class EarlyStopping(TrainingCallback): + """Callback function for early stopping + Parameters + ---------- + rounds : + Early stopping rounds. + metric_name : + Name of metric that is used for early stopping. + maximize : + Whether to maximize evaluation metric. None means auto (discouraged). + min_delta : + Minimum absolute change in score to be qualified as an improvement. + """ + + def __init__( + self, + rounds: int, + metric_name: str, + maximize: Optional[bool] = None, + save_best: Optional[bool] = True, + min_delta: float = 0.0, + ) -> None: + self.metric_name = metric_name + assert self.metric_name in ['auc', 'acc', 'recall', 'precision'] + self.rounds = rounds + self.maximize = maximize + self.save_best = save_best + self._min_delta = min_delta + if self._min_delta < 0: + raise ValueError("min_delta must be greater or equal to 0.") + self.stopping_history: _EvalsLog = {} + self.current_rounds: int = 0 + self.best_scores: dict = {} + super().__init__() + + def before_training(self, model: _Model) -> _Model: + return model + + def _update_rounds( + self, score: _Score, metric_name: str, model: _Model, epoch: int + ) -> bool: + def get_s(value: _Score) -> float: + """get score if it's cross validation history.""" + return value[0] if isinstance(value, tuple) else value + + def maximize(new: _Score, best: _Score) -> bool: + """New score should be greater than the old one.""" + return numpy.greater(get_s(new) - self._min_delta, get_s(best)) + + def minimize(new: _Score, best: _Score) -> bool: + """New score should be lesser than the old one.""" + return numpy.greater(get_s(best) - self._min_delta, get_s(new)) + + if self.maximize is None: + maximize_metrics = ( + "auc", + "aucpr", + "pre", + "pre@", + "map", + "ndcg", + "auc@", + "aucpr@", + "map@", + "ndcg@", + ) + if metric_name != "mape" and any(metric_name.startswith(x) for x in maximize_metrics): + self.maximize = True + else: + self.maximize = False + + if self.maximize: + improve_op = maximize + else: + improve_op = minimize + + if not self.stopping_history: # First round + self.current_rounds = 0 + self.stopping_history[metric_name] = cast(_ScoreList, [score]) + self.best_scores[metric_name] = cast(_ScoreList, [score]) + if self.save_best: + model.set_param('best_score', score) + model.set_param('best_iteration', epoch) + elif not improve_op(score, self.best_scores[metric_name][-1]): + # Not improved + self.stopping_history[metric_name].append(score) # type: ignore + self.current_rounds += 1 + else: # Improved + self.stopping_history[metric_name].append(score) # type: ignore + self.best_scores[metric_name].append(score) + self.current_rounds = 0 # reset + if self.save_best: + model.set_param('best_score', score) + model.set_param('best_iteration', epoch) + + if self.current_rounds >= self.rounds: + # Should stop + return True + return False + + def after_iteration( + self, model: _Model, epoch: int + ) -> bool: + history = model.get_history() + if len(history.keys()) < 1: + raise ValueError( + "Must have at least 1 validation dataset for early stopping.") + + metric_name = self.metric_name + # The latest score + score = history[metric_name][-1] + return self._update_rounds(score, metric_name, model, epoch) + + def after_training(self, model: _Model) -> _Model: + return model diff --git a/python/ppc_model/secure_lgbm/monitor/evaluation_monitor.py b/python/ppc_model/secure_lgbm/monitor/evaluation_monitor.py new file mode 100644 index 00000000..1529381c --- /dev/null +++ b/python/ppc_model/secure_lgbm/monitor/evaluation_monitor.py @@ -0,0 +1,127 @@ +import os +import time +import random +import traceback +from typing import Optional + +import matplotlib.pyplot as plt + +from ppc_common.ppc_utils.utils import METRICS_OVER_ITERATION_FILE +from ppc_model.secure_lgbm.monitor.callback import TrainingCallback +from ppc_model.secure_lgbm.monitor.core import _Model + + +def _draw_figure(model: _Model): + scores = model.get_history() + path = model.get_workspace() + + iterations = [i + 1 for i in range(len(next(iter(scores.values()))))] + + # plt.cla() + plt.figure(figsize=(int(10 + len(iterations) / 5), 10)) + + for metric, values in scores.items(): + plt.plot(iterations, values, label=metric) + max_index = values.index(max(values)) + plt.scatter(max_index + 1, values[max_index], color='green') + plt.text(max_index + 1, values[max_index], + f'{values[max_index]:.4f}', fontsize=9, ha='right') + + plt.legend() + plt.title('Metrics Over Iterations') + plt.xlabel('Iteration') + plt.ylabel('Metric Value') + plt.grid(True) + if len(iterations) <= 60: + plt.xticks(iterations, fontsize=10, rotation=45) + else: + plt.xticks(range(0, len(iterations), 5), fontsize=10, rotation=45) + plt.yticks(fontsize=12) + + plt.savefig(model.ctx.get_local_file_path( + METRICS_OVER_ITERATION_FILE), format='svg', dpi=300) + plt.close('all') + + +def _upload_figure(model: _Model): + storage_client = model.get_storage_client() + if storage_client is not None: + job_id = model.get_job_id() + local_metrics_file_path = model.ctx.get_local_file_path( + METRICS_OVER_ITERATION_FILE) + remote_unique_file_path = model.ctx.get_remote_file_path( + METRICS_OVER_ITERATION_FILE) + user = None + if model.ctx is not None: + user = model.ctx.user + storage_client.upload_file( + local_metrics_file_path, remote_unique_file_path, user) + + +def _fmt_metric( + metric_name: str, score: float +) -> str: + msg = f"\t{metric_name}:{score:.5f}" + return msg + + +class EvaluationMonitor(TrainingCallback): + """Print the evaluation result after each period iteration. + Parameters + ---------- + period : + How many epoches between printing. + """ + + def __init__(self, logger, period: int = 1) -> None: + self.logger = logger + self.period = period + assert period > 0 + # last error message, useful when early stopping and period are used together. + self._latest: Optional[str] = None + super().__init__() + + def after_iteration( + self, model: _Model, epoch: int + ) -> bool: + history = model.get_history() + if not history: + return False + + msg: str = f"[{model.get_job_id()}, epoch(iter): {epoch}]" + for metric_name, scores in history.items(): + if isinstance(scores[-1], tuple): + score = scores[-1][0] + else: + score = scores[-1] + msg += _fmt_metric(metric_name, score) + msg += "\n" + + if (epoch % self.period) == 0 or self.period == 1: + self.logger.info(msg) + self._latest = None + else: + # There is skipped message + self._latest = msg + + return False + + def after_training(self, model: _Model) -> _Model: + if self._latest is not None: + self.logger.info(self._latest) + max_retry = 3 + retry_num = 0 + while retry_num < max_retry: + retry_num += 1 + try: + _draw_figure(model) + except: + self.logger.info(f'scores = {model.get_history()}') + self.logger.info(f'path = {model.get_workspace()}') + err = traceback.format_exc().replace('\n', ' ; error ') + # self.logger.exception(err) + self.logger.info( + f'plot moniter in times-{retry_num} failed, traceback: {err}.') + time.sleep(random.uniform(0.1, 3)) + _upload_figure(model) + return model diff --git a/python/ppc_model/secure_lgbm/monitor/feature/__init__.py b/python/ppc_model/secure_lgbm/monitor/feature/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/python/ppc_model/secure_lgbm/monitor/feature/feature_evaluation_info.py b/python/ppc_model/secure_lgbm/monitor/feature/feature_evaluation_info.py new file mode 100644 index 00000000..b3c097af --- /dev/null +++ b/python/ppc_model/secure_lgbm/monitor/feature/feature_evaluation_info.py @@ -0,0 +1,90 @@ +# -*- coding: utf-8 -*- +from enum import Enum +import pandas as pd + + +class EvaluationType(Enum): + """the evaluation type + """ + TRAIN = "train", + VALIDATION = "validation", + + +class EvaluationMetric: + """the evaluation metric + """ + + def __init__(self, value, desc): + self.value = value + self.desc = desc + + def set_desc(self, desc): + self.desc = desc + + +class FeatureEvaluationResult: + DEFAULT_SAMPLE_STAT_DESC = "总样本" + DEFAULT_POSITIVE_SAMPLE_STAT_DESC = "正样本" + DEFAULT_KS_STAT_DESC = "KS" + DEFAULT_AUC_STAT_DESC = "AUC" + + DEFAULT_TRAIN_EVALUATION_DESC = "训练集" + DEFAULT_VALIDATION_EVALUATION_DESC = "验证集" + DEFAULT_ROW_INDEX_LABEL_DESC = "分类" + + def __init__(self, type, type_desc=None, ks_value=0, auc_value=0, label_list=None): + self.type = type + self.type_desc = type_desc + if self.type_desc is None: + if self.type == EvaluationType.TRAIN: + self.type_desc = FeatureEvaluationResult.DEFAULT_TRAIN_EVALUATION_DESC + elif self.type == EvaluationType.VALIDATION: + self.type_desc = FeatureEvaluationResult.DEFAULT_VALIDATION_EVALUATION_DESC + else: + raise Exception( + f"Create FeatureEvaluationResult for unsupported evaluation type: {type}") + self.ks = EvaluationMetric( + ks_value, FeatureEvaluationResult.DEFAULT_KS_STAT_DESC) + self.auc = EvaluationMetric( + auc_value, FeatureEvaluationResult.DEFAULT_AUC_STAT_DESC) + self.positive_samples = EvaluationMetric( + 0, FeatureEvaluationResult.DEFAULT_POSITIVE_SAMPLE_STAT_DESC) + self.samples = EvaluationMetric( + 0, FeatureEvaluationResult.DEFAULT_SAMPLE_STAT_DESC) + + if label_list is not None: + self.set_sample_info(label_list) + + def set_sample_info(self, label_list): + self.samples.value = len(label_list) + for label in label_list: + self.positive_samples.value += label + + def columns(self): + return [FeatureEvaluationResult.DEFAULT_ROW_INDEX_LABEL_DESC, self.samples.desc, self.positive_samples.desc, self.ks.desc, self.auc.desc] + + def to_dict(self): + return {FeatureEvaluationResult.DEFAULT_ROW_INDEX_LABEL_DESC: self.type_desc, + self.samples.desc: self.samples.value, + self.positive_samples.desc: self.positive_samples.value, + self.ks.desc: self.ks.value, + self.auc.desc: self.auc.value} + + @staticmethod + def summary(evaluation_result_list): + if evaluation_result_list is None or len(evaluation_result_list) == 0: + return None + columns = None + rows = [] + for evaluation_metric in evaluation_result_list: + rows.append(evaluation_metric.to_dict()) + if columns is None: + columns = evaluation_metric.columns() + return pd.DataFrame(rows, columns=columns) + + @staticmethod + def store_and_upload_summary(evaluation_result_list, local_file_path, remote_file_path, storage_client, user=None): + df = FeatureEvaluationResult.summary(evaluation_result_list) + df.to_csv(local_file_path, index=False) + if storage_client is not None: + storage_client.upload_file(local_file_path, remote_file_path, user) diff --git a/python/ppc_model/secure_lgbm/monitor/feature/test/__init__.py b/python/ppc_model/secure_lgbm/monitor/feature/test/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/python/ppc_model/secure_lgbm/monitor/feature/test/feature_evalution_info_test.py b/python/ppc_model/secure_lgbm/monitor/feature/test/feature_evalution_info_test.py new file mode 100644 index 00000000..ff6f0061 --- /dev/null +++ b/python/ppc_model/secure_lgbm/monitor/feature/test/feature_evalution_info_test.py @@ -0,0 +1,73 @@ +# -*- coding: utf-8 -*- +import unittest +import numpy as np +from ppc_model.secure_lgbm.monitor.feature.feature_evaluation_info import FeatureEvaluationResult +from ppc_model.secure_lgbm.monitor.feature.feature_evaluation_info import EvaluationMetric +from ppc_model.secure_lgbm.monitor.feature.feature_evaluation_info import EvaluationType + + +def check_result(ut_obj, evaluation_result, expected_ks, expected_auc, expected_sample): + ut_obj.assertEqual(evaluation_result.ks.value, expected_ks) + ut_obj.assertEqual(evaluation_result.auc.value, expected_auc) + ut_obj.assertEqual(evaluation_result.samples.value, expected_sample) + + +class TestFeatureEvaluationResult(unittest.TestCase): + def test_default_table_meta(self): + sample_num = 1000000 + train_label_list = np.random.randint(0, 2, sample_num) + train_evaluation_result = FeatureEvaluationResult( + type=EvaluationType.TRAIN, label_list=train_label_list) + ks_value = 0.4126 + auc_value = 0.7685 + (train_evaluation_result.ks.value, + train_evaluation_result.auc.value) = (ks_value, auc_value) + check_result(self, train_evaluation_result, + ks_value, auc_value, sample_num) + + sample_num = 2000000 + validation_label_list = np.random.randint(0, 2, sample_num) + validation_evaluation_result = FeatureEvaluationResult( + type=EvaluationType.VALIDATION, label_list=validation_label_list) + ks_value = 0.3116 + auc_value = 0.6676 + (validation_evaluation_result.ks.value, + validation_evaluation_result.auc.value) = (ks_value, auc_value) + check_result(self, validation_evaluation_result, + ks_value, auc_value, sample_num) + + local_path = "evaluation_result_case_1.csv" + FeatureEvaluationResult.store_and_upload_summary( + [train_evaluation_result, validation_evaluation_result], local_path, None, None) + + def test_with_given_table_meta(self): + ks_value = 0.4126 + auc_value = 0.7685 + sample_num = 1000000 + train_label_list = np.random.randint(0, 2, sample_num) + train_evaluation_result = FeatureEvaluationResult( + type=EvaluationType.TRAIN, label_list=train_label_list, ks_value=ks_value, auc_value=auc_value) + check_result(self, train_evaluation_result, + ks_value, auc_value, sample_num) + train_evaluation_result.ks.desc = "KS值" + train_evaluation_result.auc.desc = "AUC值" + + ks_value = 0.3116 + auc_value = 0.6676 + sample_num = 2000000 + validation_label_list = np.random.randint(0, 2, sample_num) + validation_evaluation_result = FeatureEvaluationResult( + type=EvaluationType.VALIDATION, label_list=validation_label_list, ks_value=ks_value, auc_value=auc_value) + validation_evaluation_result.ks.desc = "KS值" + validation_evaluation_result.auc.desc = "AUC值" + check_result(self, validation_evaluation_result, + ks_value, auc_value, sample_num) + + local_path = "evaluation_result_case_2.csv" + + FeatureEvaluationResult.store_and_upload_summary( + [train_evaluation_result, validation_evaluation_result], local_path, None, None) + + +if __name__ == '__main__': + unittest.main() diff --git a/python/ppc_model/secure_lgbm/monitor/train_callback_unittest.py b/python/ppc_model/secure_lgbm/monitor/train_callback_unittest.py new file mode 100644 index 00000000..6d995868 --- /dev/null +++ b/python/ppc_model/secure_lgbm/monitor/train_callback_unittest.py @@ -0,0 +1,109 @@ +import time +import unittest + +import numpy as np + +from ppc_model_service import config +from ppc_model.secure_lgbm.monitor.callback import CallbackContainer +from ppc_model.secure_lgbm.monitor.core import Booster, fevaluation +from ppc_model.secure_lgbm.monitor.early_stopping import EarlyStopping +from ppc_model.secure_lgbm.monitor.evaluation_monitor import EvaluationMonitor + +log = config.get_logger() + + +class TestBooster(unittest.TestCase): + def setUp(self): + np.random.seed(int(time.time())) + self.y_true = np.random.randint(0, 2, 10000) + self.test_y_true = np.random.randint(0, 2, 10000) + self.y_pred = np.random.rand(10000) + self.booster = Booster(self.y_true, self.test_y_true) + + def test_set_get_param(self): + self.booster.set_param('learning_rate', 0.1) + self.assertEqual(self.booster.get_param('learning_rate'), 0.1) + + def test_after_iteration(self): + self.booster.after_iteration(self.y_pred, False) + np.testing.assert_array_equal(self.booster.get_y_pred(), self.y_pred) + self.assertEqual(self.booster.get_epoch(), 1) + + def test_eval(self): + self.booster.after_iteration(self.y_pred) + results = self.booster.eval(fevaluation) + self.assertIn('auc', results) + self.assertIn('acc', results) + self.assertIn('recall', results) + self.assertIn('precision', results) + self.assertIsInstance(results['auc'], float) + self.assertIsInstance(results['acc'], float) + self.assertIsInstance(results['recall'], float) + self.assertIsInstance(results['precision'], float) + + +class TestEarlyStopping(unittest.TestCase): + def setUp(self): + np.random.seed(int(time.time())) + self.y_true = np.random.randint(0, 2, 10000) + self.test_y_true = np.random.randint(0, 2, 10000) + self.y_pred = np.random.rand(10000) + self.model = Booster(self.y_true, self.test_y_true) + self.early_stopping = EarlyStopping( + rounds=4, metric_name='auc', maximize=True) + + def test_early_stopping(self): + stop = False + while not stop: + np.random.seed(int(time.time()) + self.model.epoch) + y_pred = np.random.rand(10000) + self.model.after_iteration(y_pred) + self.model.eval(fevaluation) + stop = self.early_stopping.after_iteration( + self.model, self.model.epoch) + print(self.model.epoch, stop) + + +class TestEvaluationMonitor(unittest.TestCase): + def setUp(self): + np.random.seed(int(time.time())) + self.y_true = np.random.randint(0, 2, 10000) + self.test_y_true = np.random.randint(0, 2, 10000) + self.y_pred = np.random.rand(10000) + self.model = Booster(self.y_true, self.test_y_true, '/tmp/') + self.monitor = EvaluationMonitor(log, period=2) + + def test_after_training(self): + np.random.seed(int(time.time())) + for i in range(10): + np.random.seed(int(time.time()) + self.model.epoch) + y_pred = np.random.rand(10000) + self.model.after_iteration(y_pred) + self.model.eval(fevaluation) + self.monitor.after_training(self.model) + + +class TestCallbackContainer(unittest.TestCase): + def setUp(self): + np.random.seed(int(time.time())) + self.y_true = np.random.randint(0, 2, 10000) + self.test_y_true = np.random.randint(0, 2, 10000) + self.y_pred = np.random.rand(10000) + self.model = Booster(self.y_true, self.test_y_true, 'tmp') + self.early_stopping = EarlyStopping( + rounds=4, metric_name='auc', maximize=True) + self.monitor = EvaluationMonitor(log, period=2) + self.container = CallbackContainer( + [self.early_stopping, self.monitor], fevaluation) + + def test_callback_container(self): + stop = False + while not stop: + np.random.seed(int(time.time()) + self.model.epoch) + y_pred = np.random.rand(10000) + stop = self.container.after_iteration(self.model, y_pred, True) + print(self.model.epoch, stop) + + +if __name__ == '__main__': + unittest.main() diff --git a/python/ppc_model/secure_lgbm/secure_lgbm_context.py b/python/ppc_model/secure_lgbm/secure_lgbm_context.py new file mode 100644 index 00000000..a6d7d301 --- /dev/null +++ b/python/ppc_model/secure_lgbm/secure_lgbm_context.py @@ -0,0 +1,181 @@ + +import os +from enum import Enum +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.initializer import Initializer +from ppc_model.common.protocol import TaskRole +from ppc_common.ppc_utils import common_func +from ppc_model.common.model_setting import ModelSetting +from ppc_model.secure_model_base.secure_model_context import SecureModel +from ppc_model.secure_model_base.secure_model_context import SecureModelContext + + +class LGBMModel(SecureModel): + + def __init__( + self, + boosting_type: str = 'gbdt', + num_leaves: int = 31, + max_depth: int = -1, + learning_rate: float = 0.1, + n_estimators: int = 100, + subsample_for_bin: int = 200000, + objective: str = None, + min_split_gain: float = 0., + min_child_weight: float = 1e-3, + min_child_samples: int = 20, + subsample: float = 1., + subsample_freq: int = 0, + colsample_bytree: float = 1., + reg_alpha: float = 0., + reg_lambda: float = 0., + random_state: int = None, + n_jobs: int = None, + importance_type: str = 'split', + **kwargs + ): + self.boosting_type = boosting_type + self.objective = objective + self.num_leaves = num_leaves + self.max_depth = max_depth + self.learning_rate = learning_rate + self.n_estimators = n_estimators + self.subsample_for_bin = subsample_for_bin + self.min_split_gain = min_split_gain + self.min_child_weight = min_child_weight + self.min_child_samples = min_child_samples + self.subsample = subsample + self.subsample_freq = subsample_freq + self.colsample_bytree = colsample_bytree + self.reg_alpha = reg_alpha + self.reg_lambda = reg_lambda + self.random_state = random_state + self.n_jobs = n_jobs + self.importance_type = importance_type + super().__init__(**kwargs) + + +class ModelTaskParams(LGBMModel): + def __init__( + self, + test_size: float = 0.3, + max_bin: int = 10, + use_goss: bool = False, + top_rate: float = 0.2, + other_rate: float = 0.1, + feature_rate: float = 1.0, + colsample_bylevel: float = 1.0, + gamma: float = 0, + loss_type: str = 'logistic', + eval_set_column: str = None, + train_set_value: str = None, + eval_set_value: str = None, + train_feats: str = None, + early_stopping_rounds: int = 5, + eval_metric: str = 'auc', + verbose_eval: int = 1, + categorical_feature: list = [], + silent: bool = False + ): + + super().__init__() + + self.test_size = test_size + self.max_bin = max_bin + self.use_goss = use_goss + self.top_rate = top_rate + self.other_rate = other_rate + self.feature_rate = feature_rate + self.colsample_bylevel = colsample_bylevel + self.gamma = gamma + self.loss_type = loss_type + self.eval_set_column = eval_set_column + self.train_set_value = train_set_value + self.eval_set_value = eval_set_value + self.train_feature = train_feats + self.early_stopping_rounds = early_stopping_rounds + self.eval_metric = eval_metric + self.verbose_eval = verbose_eval + self.silent = silent + self.λ = self.reg_lambda + self.lr = self.learning_rate + self.categorical_feature = categorical_feature + self.categorical_idx = [] + self.my_categorical_idx = [] + + +class SecureLGBMParams(ModelTaskParams): + + def __init__(self): + super().__init__() + + def _get_params(self): + """返回LGBMClassifier所有参数""" + return LGBMModel().get_params() + + +class SecureLGBMContext(SecureModelContext): + + def __init__(self, + task_id, + args, + components: Initializer + ): + super().__init__(task_id, args, components) + + self.phe = PheCipherFactory.build_phe( + components.homo_algorithm, components.public_key_length) + self.codec = PheCipherFactory.build_codec(components.homo_algorithm) + + def create_model_param(self): + return SecureLGBMParams() + + def get_model_params(self): + """获取lgbm参数""" + return self.model_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" + INSTANCE = "INSTANCE" + ENC_GH_LIST = "ENC_GH_LIST" + ENC_GH_HIST = "ENC_GH_HIST" + SPLIT_INFO = 'SPLIT_INFO' + INSTANCE_MASK = "INSTANCE_MASK" + PREDICT_LEAF_MASK = "PREDICT_LEAF_MASK" + TEST_LEAF_MASK = "PREDICT_TEST_LEAF_MASK" + VALID_LEAF_MASK = "PREDICT_VALID_LEAF_MASK" + STOP_ITERATION = "STOP_ITERATION" + PREDICT_PRABA = "PREDICT_PRABA" + MODEL_DATA = "MODEL_DATA" diff --git a/python/ppc_model/secure_lgbm/secure_lgbm_prediction_engine.py b/python/ppc_model/secure_lgbm/secure_lgbm_prediction_engine.py new file mode 100644 index 00000000..09912342 --- /dev/null +++ b/python/ppc_model/secure_lgbm/secure_lgbm_prediction_engine.py @@ -0,0 +1,38 @@ +from ppc_common.ppc_utils.exception import PpcException, PpcErrorCode +from ppc_model.common.protocol import TaskRole, ModelTask +from ppc_model.common.global_context import components +from ppc_model.interface.task_engine import TaskEngine +from ppc_model.datasets.dataset import SecureDataset +from ppc_model.metrics.evaluation import Evaluation +from ppc_model.common.model_result import ResultFileHandling +from ppc_model.secure_lgbm.secure_lgbm_context import SecureLGBMContext +from ppc_model.secure_lgbm.vertical import VerticalLGBMActiveParty, VerticalLGBMPassiveParty + + +class SecureLGBMPredictionEngine(TaskEngine): + task_type = ModelTask.XGB_PREDICTING + + @staticmethod + def run(task_id, args): + + task_info = SecureLGBMContext(task_id, args, components) + secure_dataset = SecureDataset(task_info) + + if task_info.role == TaskRole.ACTIVE_PARTY: + booster = VerticalLGBMActiveParty(task_info, secure_dataset) + elif task_info.role == TaskRole.PASSIVE_PARTY: + booster = VerticalLGBMPassiveParty(task_info, secure_dataset) + else: + raise PpcException(PpcErrorCode.ROLE_TYPE_ERROR.get_code(), + PpcErrorCode.ROLE_TYPE_ERROR.get_message()) + + booster.load_model() + booster.predict() + + # 获取测试集的预测概率值 + test_praba = booster.get_test_praba() + + # 获取测试集的预测值评估指标 + Evaluation(task_info, secure_dataset, test_praba=test_praba) + + ResultFileHandling(task_info) diff --git a/python/ppc_model/secure_lgbm/secure_lgbm_training_engine.py b/python/ppc_model/secure_lgbm/secure_lgbm_training_engine.py new file mode 100644 index 00000000..5c9c78e2 --- /dev/null +++ b/python/ppc_model/secure_lgbm/secure_lgbm_training_engine.py @@ -0,0 +1,40 @@ +from ppc_common.ppc_utils.exception import PpcException, PpcErrorCode +from ppc_model.common.protocol import TaskRole, ModelTask +from ppc_model.common.global_context import components +from ppc_model.interface.task_engine import TaskEngine +from ppc_model.datasets.dataset import SecureDataset +from ppc_model.metrics.evaluation import Evaluation +from ppc_model.metrics.model_plot import ModelPlot +from ppc_model.common.model_result import ResultFileHandling +from ppc_model.secure_lgbm.secure_lgbm_context import SecureLGBMContext +from ppc_model.secure_lgbm.vertical import VerticalLGBMActiveParty, VerticalLGBMPassiveParty + + +class SecureLGBMTrainingEngine(TaskEngine): + task_type = ModelTask.XGB_TRAINING + + @staticmethod + def run(task_id, args): + + task_info = SecureLGBMContext(task_id, args, components) + secure_dataset = SecureDataset(task_info) + + if task_info.role == TaskRole.ACTIVE_PARTY: + booster = VerticalLGBMActiveParty(task_info, secure_dataset) + elif task_info.role == TaskRole.PASSIVE_PARTY: + booster = VerticalLGBMPassiveParty(task_info, secure_dataset) + else: + raise PpcException(PpcErrorCode.ROLE_TYPE_ERROR.get_code(), + PpcErrorCode.ROLE_TYPE_ERROR.get_message()) + + booster.fit() + booster.save_model() + + # 获取训练集和验证集的预测概率值 + train_praba = booster.get_train_praba() + test_praba = booster.get_test_praba() + + # 获取训练集和验证集的预测值评估指标 + Evaluation(task_info, secure_dataset, train_praba, test_praba) + ModelPlot(booster) + ResultFileHandling(task_info) diff --git a/python/ppc_model/secure_lgbm/test/__init__.py b/python/ppc_model/secure_lgbm/test/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/python/ppc_model/secure_lgbm/test/test_cipher_packing.py b/python/ppc_model/secure_lgbm/test/test_cipher_packing.py new file mode 100644 index 00000000..1120c6b3 --- /dev/null +++ b/python/ppc_model/secure_lgbm/test/test_cipher_packing.py @@ -0,0 +1,67 @@ +import time +import unittest +import numpy as np + +from ppc_common.ppc_crypto.paillier_cipher import PaillierCipher +from ppc_common.ppc_crypto.paillier_codec import PaillierCodec +from ppc_common.ppc_protos.generated.ppc_model_pb2 import CipherList, ModelCipher + + +paillier = PaillierCipher() + + +class TestCipherPacking: + + def test_cipher_list(self): + + data_list = np.random.randint(1, 10001, size=1000) + + start_time = time.time() + ciphers = paillier.encrypt_batch_parallel(data_list) + # ciphers = paillier.encrypt_batch(data_list) + print("enc:", time.time() - start_time, "seconds") + + start_time = time.time() + enc_data_pb = CipherList() + enc_data_pb.public_key = PaillierCodec.encode_enc_key( + paillier.public_key) + for cipher in ciphers: + paillier_cipher = ModelCipher() + paillier_cipher.ciphertext, paillier_cipher.exponent = PaillierCodec.encode_cipher( + cipher) + enc_data_pb.cipher_list.append(paillier_cipher) + print("pack ciphers:", time.time() - start_time, "seconds") + + ciphers2 = [] + for i in range(100): + ciphers2.append(np.array(ciphers[10*i:10*(i+1)]).sum()) + + start_time = time.time() + enc_data_pb2 = CipherList() + enc_data_pb2.public_key = PaillierCodec.encode_enc_key( + paillier.public_key) + for cipher in ciphers2: + paillier_cipher2 = ModelCipher() + paillier_cipher2.ciphertext, paillier_cipher2.exponent = PaillierCodec.encode_cipher( + cipher, be_secure=False) + enc_data_pb2.cipher_list.append(paillier_cipher2) + print("pack ciphers:", time.time() - start_time, "seconds") + + ciphers3 = [] + for i in range(100): + ciphers3.append(np.array(ciphers[10*i:10*(i+1)]).sum()) + + start_time = time.time() + enc_data_pb3 = CipherList() + enc_data_pb3.public_key = PaillierCodec.encode_enc_key( + paillier.public_key) + for cipher in ciphers3: + paillier_cipher3 = ModelCipher() + paillier_cipher3.ciphertext, paillier_cipher3.exponent = PaillierCodec.encode_cipher( + cipher) + enc_data_pb3.cipher_list.append(paillier_cipher3) + print("pack ciphers:", time.time() - start_time, "seconds") + + +if __name__ == '__main__': + unittest.main() diff --git a/python/ppc_model/secure_lgbm/test/test_pack_gh.py b/python/ppc_model/secure_lgbm/test/test_pack_gh.py new file mode 100644 index 00000000..798de369 --- /dev/null +++ b/python/ppc_model/secure_lgbm/test/test_pack_gh.py @@ -0,0 +1,43 @@ +import unittest +import numpy as np + +from ppc_model.secure_lgbm.vertical.booster import VerticalBooster + + +class TestPackGH(unittest.TestCase): + + def test_pack_gh(self): + + g_list = np.array([-4, 2, -1.3, 0, 0, -15.3544564544]) + h_list = np.array([2, 1.5, -1.4, 0, -1.68, 1.2356564564]) + + gh_list = VerticalBooster.packing_gh(g_list, h_list) + + result_array = np.array( + [429496329600000000000000002000, 200000000000000000001500, + 429496599600000000004294965896, 0, + 4294965616, 429495194200000000000000001235], dtype=object) + + assert np.array_equal(gh_list, result_array) + + def test_unpack_gh(self): + + gh_list = np.array( + [429496329600000000000000002000, 200000000000000000001500, + 429496599600000000004294965896, 0, + 4294965616, 429495194200000000000000001235], dtype=object) + + gh_sum_list = np.array([sum(gh_list), sum(gh_list)*2]) + g_hist, h_hist = VerticalBooster.unpacking_gh(gh_sum_list) + + g_list = np.array([-4, 2, -1.3, 0, 0, -15.3544564544]) + h_list = np.array([2, 1.5, -1.4, 0, -1.68, 1.2356564564]) + result_g_hist = np.array([-18.654, -37.308]) + result_h_hist = np.array([1.655, 3.31]) + + assert np.array_equal(g_hist, result_g_hist) + assert np.array_equal(h_hist, result_h_hist) + + +if __name__ == '__main__': + unittest.main() diff --git a/python/ppc_model/secure_lgbm/test/test_save_load_model.py b/python/ppc_model/secure_lgbm/test/test_save_load_model.py new file mode 100644 index 00000000..dbf8a433 --- /dev/null +++ b/python/ppc_model/secure_lgbm/test/test_save_load_model.py @@ -0,0 +1,92 @@ +import unittest +import numpy as np + +from ppc_model.common.initializer import Initializer +from ppc_common.ppc_mock.mock_objects import MockLogger +from ppc_common.ppc_protos.generated.ppc_model_pb2 import BestSplitInfo +from ppc_model.secure_lgbm.secure_lgbm_context import SecureLGBMContext +from ppc_model.secure_lgbm.vertical.booster import VerticalBooster + + +class TestSaveLoadModel(unittest.TestCase): + + n_estimators = 2 + max_depth = 3 + np.random.seed(2024) + + ACTIVE_PARTY = 'ACTIVE_PARTY' + PASSIVE_PARTY = 'PASSIVE_PARTY' + + job_id = 'j-123' + task_id = 't-123' + + model_dict = {} + + args = { + 'job_id': job_id, + 'task_id': task_id, + 'is_label_holder': True, + 'result_receiver_id_list': [ACTIVE_PARTY, PASSIVE_PARTY], + 'participant_id_list': [ACTIVE_PARTY, PASSIVE_PARTY], + 'model_predict_algorithm': None, + 'algorithm_type': 'Train', + 'algorithm_subtype': 'HeteroXGB', + 'model_dict': model_dict + } + + components = Initializer(log_config_path='', config_path='') + components.config_data = {'JOB_TEMP_DIR': '/tmp'} + components.mock_logger = MockLogger() + + def test_save_load_model(self): + + x_split = [[1, 2, 3, 5], [1, 2], [1.23, 3.45, 5.23]] + + trees = [] + for i in range(self.n_estimators): + tree = self._build_tree(self.max_depth) + trees.append(tree) + # print(trees) + + task_info = SecureLGBMContext(self.args['task_id'], self.args, self.components) + booster = VerticalBooster(task_info, dataset=None) + booster._X_split = x_split + booster._trees = trees + booster.save_model() + + booster_predict = VerticalBooster(task_info, dataset=None) + booster_predict.load_model() + + assert x_split == booster_predict._X_split + assert trees == booster_predict._trees + + @staticmethod + def _build_tree(max_depth, depth=0, weight=0): + + if depth == max_depth: + return weight + + best_split_info = BestSplitInfo( + feature=np.random.randint(0, 10), + value=np.random.randint(0, 4), + best_gain=np.random.rand(), + w_left=np.random.rand(), + w_right=np.random.rand(), + agency_idx=np.random.randint(0, 2), + agency_feature=np.random.randint(0, 5) + ) + # print(best_split_info) + + if best_split_info.best_gain > 0.2: + left_tree = TestSaveLoadModel._build_tree( + max_depth, depth + 1, best_split_info.w_left) + right_tree = TestSaveLoadModel._build_tree( + max_depth, depth + 1, best_split_info.w_right) + + return [(best_split_info, left_tree, right_tree)] + else: + return weight + + +if __name__ == '__main__': + unittest.main() diff --git a/python/ppc_model/secure_lgbm/test/test_secure_lgbm_context.py b/python/ppc_model/secure_lgbm/test/test_secure_lgbm_context.py new file mode 100644 index 00000000..8ad9be7c --- /dev/null +++ b/python/ppc_model/secure_lgbm/test/test_secure_lgbm_context.py @@ -0,0 +1,77 @@ +import unittest + +from ppc_model.common.initializer import Initializer +from ppc_common.ppc_mock.mock_objects import MockLogger +from ppc_model.secure_lgbm.secure_lgbm_context import SecureLGBMContext + + +class TestSecureLGBMContext(unittest.TestCase): + + components = Initializer(log_config_path='', config_path='') + components.config_data = {'JOB_TEMP_DIR': '/tmp'} + components.mock_logger = MockLogger() + + def test_get_model_params(self): + + args = { + 'job_id': 'j-123', + 'task_id': '1', + 'is_label_holder': True, + 'result_receiver_id_list': [], + 'participant_id_list': [], + 'model_predict_algorithm': None, + 'algorithm_type': None, + 'algorithm_subtype': None, + 'model_dict': {} + } + + task_info = SecureLGBMContext(args['task_id'], args, self.components) + model_params = task_info.get_model_params() + # 打印LGBMModel默认参数 + print(model_params._get_params()) + + # 默认自定义参数为空字典 + assert model_params.get_params() == {} + # assert model_params.get_all_params() != model_params._get_params() + + def test_set_model_params(self): + + args = { + 'job_id': 'j-123', + 'task_id': '1', + 'is_label_holder': True, + 'result_receiver_id_list': [], + 'participant_id_list': [], + 'model_predict_algorithm': None, + 'algorithm_type': None, + 'algorithm_subtype': None, + 'model_dict': { + 'objective': 'regression', + 'n_estimators': 6, + 'max_depth': 3, + 'test_dataset_percentage': 0.2, + 'use_goss': 1 + } + } + + task_info = SecureLGBMContext(args['task_id'], args, self.components) + model_params = task_info.get_model_params() + # 打印SecureLGBMParams自定义参数 + print(model_params.get_params()) + # 打印SecureLGBMParams所有参数 + print(model_params.get_all_params()) + + # assert model_params.get_params() == args['model_dict'] + self.assertEqual(model_params.get_all_params()[ + 'learning_rate'], model_params._get_params()['learning_rate']) + self.assertEqual(model_params.learning_rate, + model_params._get_params()['learning_rate']) + self.assertEqual(model_params.n_estimators, + args['model_dict']['n_estimators']) + self.assertEqual(model_params.test_size, + args['model_dict']['test_dataset_percentage']) + self.assertEqual(model_params.use_goss, args['model_dict']['use_goss']) + + +if __name__ == "__main__": + unittest.main() 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 new file mode 100644 index 00000000..bde18cdb --- /dev/null +++ b/python/ppc_model/secure_lgbm/test/test_secure_lgbm_performance_training.py @@ -0,0 +1,163 @@ +import unittest +import threading +import traceback + +from ppc_model.common.initializer import Initializer +from ppc_common.ppc_mock.mock_objects import MockLogger +from ppc_common.ppc_async_executor.thread_event_manager import ThreadEventManager +from ppc_model.datasets.dataset import SecureDataset +from ppc_model.metrics.evaluation import Evaluation +from ppc_model.metrics.model_plot import ModelPlot +from ppc_model.common.model_result import ResultFileHandling +from ppc_model.common.mock.mock_model_transport import MockModelRouterApi +from ppc_model.secure_lgbm.secure_lgbm_context import SecureLGBMContext +from ppc_model.secure_lgbm.vertical import VerticalLGBMActiveParty, VerticalLGBMPassiveParty + + +ACTIVE_PARTY = 'ACTIVE_PARTY' +PASSIVE_PARTY = 'PASSIVE_PARTY' + +data_size = 1000 +feature_dim = 20 + + +def mock_args(): + job_id = 'j-111' + task_id = 't-111' + + model_dict = { + 'objective': 'regression', + 'categorical_feature': [], + 'train_features': "", + 'max_bin': 10, + 'n_estimators': 2, + 'max_depth': 3, + 'feature_rate': 1.0, + 'random_state': 2024 + } + + args_a = { + 'job_id': job_id, + 'task_id': task_id, + 'is_label_holder': True, + 'result_receiver_id_list': [ACTIVE_PARTY, PASSIVE_PARTY], + 'participant_id_list': [ACTIVE_PARTY, PASSIVE_PARTY], + 'model_predict_algorithm': None, + 'algorithm_type': 'Train', + 'algorithm_subtype': 'HeteroXGB', + 'model_dict': model_dict + } + + args_b = { + 'job_id': job_id, + 'task_id': task_id, + 'is_label_holder': False, + 'result_receiver_id_list': [ACTIVE_PARTY, PASSIVE_PARTY], + 'participant_id_list': [ACTIVE_PARTY, PASSIVE_PARTY], + 'model_predict_algorithm': None, + 'algorithm_type': 'Train', + 'algorithm_subtype': 'HeteroXGB', + 'model_dict': model_dict + } + + return args_a, args_b + + +class TestXgboostTraining(unittest.TestCase): + + def setUp(self): + participants = [PASSIVE_PARTY, ACTIVE_PARTY] + self._active_transport = MockModelRouterApi(participants) + self._passive_transport = MockModelRouterApi(participants) + + def test_fit(self): + args_a, args_b = mock_args() + + active_components = Initializer(log_config_path='', config_path='') + active_components.transport = self._active_transport + active_components.config_data = { + 'JOB_TEMP_DIR': '/tmp/active', 'AGENCY_ID': ACTIVE_PARTY} + active_components.mock_logger = MockLogger() + task_info_a = SecureLGBMContext(args_a['task_id'], args_a, active_components) + model_data = SecureDataset.simulate_dataset( + data_size, feature_dim, has_label=True) + secure_dataset_a = SecureDataset(task_info_a, model_data) + booster_a = VerticalLGBMActiveParty(task_info_a, secure_dataset_a) + print(secure_dataset_a.feature_name) + print(secure_dataset_a.train_idx.shape) + print(secure_dataset_a.train_X.shape) + print(secure_dataset_a.train_y.shape) + print(secure_dataset_a.test_idx.shape) + print(secure_dataset_a.test_X.shape) + print(secure_dataset_a.test_y.shape) + + passive_components = Initializer(log_config_path='', config_path='') + passive_components.transport = self._passive_transport + passive_components.config_data = { + 'JOB_TEMP_DIR': '/tmp/passive', 'AGENCY_ID': PASSIVE_PARTY} + passive_components.mock_logger = MockLogger() + task_info_b = SecureLGBMContext(args_b['task_id'], args_b, passive_components) + model_data = SecureDataset.simulate_dataset( + data_size, feature_dim, has_label=False) + secure_dataset_b = SecureDataset(task_info_b, model_data) + booster_b = VerticalLGBMPassiveParty(task_info_b, secure_dataset_b) + print(secure_dataset_b.feature_name) + print(secure_dataset_b.train_idx.shape) + print(secure_dataset_b.train_X.shape) + print(secure_dataset_b.test_idx.shape) + print(secure_dataset_b.test_X.shape) + + def active_worker(): + try: + booster_a.fit() + booster_a.save_model() + train_praba = booster_a.get_train_praba() + test_praba = booster_a.get_test_praba() + Evaluation(task_info_a, secure_dataset_a, + train_praba, test_praba) + # ModelPlot(booster_a) + ResultFileHandling(task_info_a) + booster_a.load_model() + booster_a.predict() + test_praba = booster_a.get_test_praba() + 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) + except Exception as e: + task_info_a.components.logger().info(traceback.format_exc()) + + def passive_worker(): + try: + booster_b.fit() + booster_b.save_model() + train_praba = booster_b.get_train_praba() + test_praba = booster_b.get_test_praba() + Evaluation(task_info_b, secure_dataset_b, + train_praba, test_praba) + # ModelPlot(booster_b) + ResultFileHandling(task_info_b) + booster_b.load_model() + booster_b.predict() + test_praba = booster_b.get_test_praba() + 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) + except Exception as e: + task_info_b.components.logger().info(traceback.format_exc()) + + thread_lgbm_active = threading.Thread(target=active_worker, args=()) + thread_lgbm_active.start() + + thread_lgbm_passive = threading.Thread(target=passive_worker, args=()) + thread_lgbm_passive.start() + + thread_lgbm_active.join() + thread_lgbm_passive.join() + + +if __name__ == '__main__': + unittest.main() 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 new file mode 100644 index 00000000..d0812e1e --- /dev/null +++ b/python/ppc_model/secure_lgbm/test/test_secure_lgbm_training.py @@ -0,0 +1,169 @@ +import unittest +import threading +import traceback +from sklearn.datasets import load_breast_cancer + +from ppc_model.common.initializer import Initializer +from ppc_common.ppc_mock.mock_objects import MockLogger +from ppc_common.ppc_async_executor.thread_event_manager import ThreadEventManager +from ppc_model.datasets.dataset import SecureDataset +from ppc_model.metrics.evaluation import Evaluation +from ppc_model.metrics.model_plot import ModelPlot +from ppc_model.common.model_result import ResultFileHandling +from ppc_model.common.mock.mock_model_transport import MockModelRouterApi +from ppc_model.secure_lgbm.secure_lgbm_context import SecureLGBMContext +from ppc_model.secure_lgbm.vertical import VerticalLGBMActiveParty, VerticalLGBMPassiveParty + + +ACTIVE_PARTY = 'ACTIVE_PARTY' +PASSIVE_PARTY = 'PASSIVE_PARTY' + + +def mock_args(): + job_id = 'j-123' + task_id = 't-123' + + model_dict = { + 'objective': 'regression', + 'categorical_feature': [], + 'train_features': "", + 'max_bin': 10, + 'n_estimators': 2, + 'max_depth': 3, + 'use_goss': 1, + 'feature_rate': 0.8, + 'random_state': 2024 + } + + args_a = { + 'job_id': job_id, + 'task_id': task_id, + 'is_label_holder': True, + 'result_receiver_id_list': [ACTIVE_PARTY, PASSIVE_PARTY], + 'participant_id_list': [ACTIVE_PARTY, PASSIVE_PARTY], + 'model_predict_algorithm': None, + 'algorithm_type': 'Train', + 'algorithm_subtype': 'HeteroXGB', + 'model_dict': model_dict + } + + args_b = { + 'job_id': job_id, + 'task_id': task_id, + 'is_label_holder': False, + 'result_receiver_id_list': [ACTIVE_PARTY, PASSIVE_PARTY], + 'participant_id_list': [ACTIVE_PARTY, PASSIVE_PARTY], + 'model_predict_algorithm': None, + 'algorithm_type': 'Train', + 'algorithm_subtype': 'HeteroXGB', + 'model_dict': model_dict + } + + return args_a, args_b + + +class TestXgboostTraining(unittest.TestCase): + + cancer = load_breast_cancer() + X = cancer.data + y = cancer.target + + df = SecureDataset.assembling_dataset(X, y) + df_with_y, df_without_y = SecureDataset.hetero_split_dataset(df) + + def setUp(self): + self._thread_event_manager = ThreadEventManager() + participants = [PASSIVE_PARTY, ACTIVE_PARTY] + self._active_transport = MockModelRouterApi(participants) + self._passive_transport = MockModelRouterApi(participants) + + def test_fit(self): + args_a, args_b = mock_args() + plot_lock = threading.Lock() + + active_components = Initializer( + log_config_path='', config_path='', plot_lock=plot_lock) + active_components.transport = self._active_transport + active_components.config_data = { + 'JOB_TEMP_DIR': '/tmp/active', 'AGENCY_ID': ACTIVE_PARTY} + active_components.mock_logger = MockLogger() + task_info_a = SecureLGBMContext(args_a['task_id'], args_a, active_components) + secure_dataset_a = SecureDataset(task_info_a, self.df_with_y) + booster_a = VerticalLGBMActiveParty(task_info_a, secure_dataset_a) + print(secure_dataset_a.feature_name) + print(secure_dataset_a.train_idx.shape) + print(secure_dataset_a.train_X.shape) + print(secure_dataset_a.train_y.shape) + print(secure_dataset_a.test_idx.shape) + print(secure_dataset_a.test_X.shape) + print(secure_dataset_a.test_y.shape) + + passive_components = Initializer( + log_config_path='', config_path='', plot_lock=plot_lock) + passive_components.transport = self._passive_transport + passive_components.config_data = { + 'JOB_TEMP_DIR': '/tmp/passive', 'AGENCY_ID': PASSIVE_PARTY} + passive_components.mock_logger = MockLogger() + task_info_b = SecureLGBMContext(args_b['task_id'], args_b, passive_components) + secure_dataset_b = SecureDataset(task_info_b, self.df_without_y) + booster_b = VerticalLGBMPassiveParty(task_info_b, secure_dataset_b) + print(secure_dataset_b.feature_name) + print(secure_dataset_b.train_idx.shape) + print(secure_dataset_b.train_X.shape) + print(secure_dataset_b.test_idx.shape) + print(secure_dataset_b.test_X.shape) + + def active_worker(): + try: + booster_a.fit() + booster_a.save_model() + train_praba = booster_a.get_train_praba() + test_praba = booster_a.get_test_praba() + Evaluation(task_info_a, secure_dataset_a, + train_praba, test_praba) + ModelPlot(booster_a) + ResultFileHandling(task_info_a) + booster_a.load_model() + booster_a.predict() + test_praba = booster_a.get_test_praba() + 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) + except Exception as e: + task_info_a.components.logger().info(traceback.format_exc()) + + def passive_worker(): + try: + booster_b.fit() + booster_b.save_model() + train_praba = booster_b.get_train_praba() + test_praba = booster_b.get_test_praba() + Evaluation(task_info_b, secure_dataset_b, + train_praba, test_praba) + ModelPlot(booster_b) + ResultFileHandling(task_info_b) + booster_b.load_model() + booster_b.predict() + test_praba = booster_b.get_test_praba() + 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) + except Exception as e: + task_info_b.components.logger().info(traceback.format_exc()) + + thread_lgbm_active = threading.Thread(target=active_worker, args=()) + thread_lgbm_active.start() + + thread_lgbm_passive = threading.Thread(target=passive_worker, args=()) + thread_lgbm_passive.start() + + thread_lgbm_active.join() + thread_lgbm_passive.join() + + +if __name__ == '__main__': + unittest.main() diff --git a/python/ppc_model/secure_lgbm/vertical/__init__.py b/python/ppc_model/secure_lgbm/vertical/__init__.py new file mode 100644 index 00000000..7a33ec6e --- /dev/null +++ b/python/ppc_model/secure_lgbm/vertical/__init__.py @@ -0,0 +1,4 @@ +from ppc_model.secure_lgbm.vertical.active_party import VerticalLGBMActiveParty +from ppc_model.secure_lgbm.vertical.passive_party import VerticalLGBMPassiveParty + +__all__ = ["VerticalLGBMActiveParty", "VerticalLGBMPassiveParty"] diff --git a/python/ppc_model/secure_lgbm/vertical/active_party.py b/python/ppc_model/secure_lgbm/vertical/active_party.py new file mode 100644 index 00000000..9a54e7ec --- /dev/null +++ b/python/ppc_model/secure_lgbm/vertical/active_party.py @@ -0,0 +1,500 @@ +import itertools +import time +import json + +import numpy as np +from pandas import DataFrame + +from ppc_common.deps_services.serialize_type import SerializeType +from ppc_common.ppc_ml.feature.feature_importance import FeatureImportanceStore +from ppc_common.ppc_ml.feature.feature_importance import FeatureImportanceType +from ppc_common.ppc_protos.generated.ppc_model_pb2 import BestSplitInfo, IterationRequest +from ppc_common.ppc_utils import utils +from ppc_model.datasets.data_reduction.feature_selection import FeatureSelection +from ppc_model.datasets.data_reduction.sampling import Sampling +from ppc_model.datasets.dataset import SecureDataset +from ppc_model.datasets.feature_binning.feature_binning import FeatureBinning +from ppc_model.metrics.evaluation import Evaluation +from ppc_model.metrics.loss import BinaryLoss +from ppc_model.secure_lgbm.secure_lgbm_context import SecureLGBMContext, LGBMMessage +from ppc_model.secure_lgbm.monitor.callback import CallbackContainer +from ppc_model.secure_lgbm.monitor.core import Booster +from ppc_model.secure_lgbm.monitor.early_stopping import EarlyStopping +from ppc_model.secure_lgbm.monitor.evaluation_monitor import EvaluationMonitor +from ppc_model.secure_lgbm.vertical.booster import VerticalBooster + + +class VerticalLGBMActiveParty(VerticalBooster): + + def __init__(self, ctx: SecureLGBMContext, dataset: SecureDataset) -> None: + super().__init__(ctx, dataset) + self.params = ctx.model_params + self._loss_func = BinaryLoss(self.params.objective) + self._all_feature_name = [dataset.feature_name] + self._all_feature_num = len(dataset.feature_name) + self.log = ctx.components.logger() + self.storage_client = ctx.components.storage_client + self.feature_importance_store = FeatureImportanceStore( + FeatureImportanceStore.DEFAULT_IMPORTANCE_LIST, None, self.log) + self.log.info( + f'task {self.ctx.task_id}: print all params: {self.params.get_all_params()}') + + def fit( + self, + *args, + **kwargs, + ) -> None: + self.log.info( + f'task {self.ctx.task_id}: Starting the lgbm on the active party.') + + self._init_active_data() + self._init_valid_data() + self._init_early_stop() + + for _ in range(self.params.n_estimators): + self._tree_id += 1 + start_time = time.time() + self.log.info( + f'task {self.ctx.task_id}: Starting n_estimators-{self._tree_id} in active party.') + + # 初始化 + feature_select, instance, used_glist, used_hlist = self._init_each_tree() + self.log.info(f'task {self.ctx.task_id}: Sampling number: {len(instance)}, ' + f'feature select: {len(feature_select)}, {feature_select}.') + + # 构建 + tree = self._build_tree( + feature_select, instance, used_glist, used_hlist) + self._trees.append(tree) + # print('tree', tree) + + # 预测 + self._train_weights += self._predict_tree( + tree, self._X_bin, np.ones(self._X_bin.shape[0], dtype=bool), LGBMMessage.PREDICT_LEAF_MASK.value) + self._train_praba = self._loss_func.sigmoid(self._train_weights) + # print('train_praba', set(self._train_praba)) + + # 评估 + if not self.params.silent and self.dataset.train_y is not None: + auc = Evaluation.fevaluation( + self.dataset.train_y, self._train_praba)['auc'] + self.log.info( + f'task {self.ctx.task_id}: n_estimators-{self._tree_id}, auc: {auc}.') + self.log.info(f'task {self.ctx.task_id}: Ending n_estimators-{self._tree_id}, ' + f'time_costs: {time.time() - start_time}s.') + + # 预测验证集 + self._test_weights += self._predict_tree( + tree, self._test_X_bin, np.ones( + self._test_X_bin.shape[0], dtype=bool), + LGBMMessage.TEST_LEAF_MASK.value) + self._test_praba = self._loss_func.sigmoid(self._test_weights) + if not self.params.silent and self.dataset.test_y is not None: + auc = Evaluation.fevaluation( + self.dataset.test_y, self._test_praba)['auc'] + self.log.info( + f'task {self.ctx.task_id}: n_estimators-{self._tree_id}, test auc: {auc}.') + if self._iteration_early_stop(): + self.log.info( + f"task {self.ctx.task_id}: lgbm early stop after {self._tree_id} iterations.") + break + + self._end_active_data() + + def transform(self, transform_data: DataFrame) -> DataFrame: + ... + + def predict(self, dataset: SecureDataset = None) -> np.ndarray: + start_time = time.time() + if dataset is None: + dataset = self.dataset + + self.params.my_categorical_idx = self._get_categorical_idx( + dataset.feature_name, self.params.categorical_feature) + + test_weights = self._init_weight(dataset.test_X.shape[0]) + test_X_bin = self._split_test_data( + self.ctx, dataset.test_X, self._X_split) + + for tree in self._trees: + test_weights += self._predict_tree( + tree, test_X_bin, np.ones(test_X_bin.shape[0], dtype=bool), LGBMMessage.VALID_LEAF_MASK.value) + test_praba = self._loss_func.sigmoid(test_weights) + self._test_praba = test_praba + + if dataset.test_y is not None: + auc = Evaluation.fevaluation(dataset.test_y, test_praba)['auc'] + self.log.info(f'task {self.ctx.task_id}: predict test auc: {auc}.') + self.log.info( + f'task {self.ctx.task_id}: Ending predict, time_costs: {time.time() - start_time}s.') + + self._end_active_data(is_train=False) + + def _init_active_data(self): + + # 初始化预测值和权重 + self._train_praba = self._init_praba(self.dataset.train_X.shape[0]) + self._train_weights = self._init_weight(self.dataset.train_X.shape[0]) + self._tree_id = 0 + + # 初始化所有参与方的特征 + for i in range(1, len(self.ctx.participant_id_list)): + feature_name_bytes = self._receive_byte_data( + self.ctx, LGBMMessage.FEATURE_NAME.value, i) + self._all_feature_name.append( + [s.decode('utf-8') for s in feature_name_bytes.split(b' ') if s]) + self._all_feature_num += len([s.decode('utf-8') + for s in feature_name_bytes.split(b' ') if s]) + for i in range(1, len(self.ctx.participant_id_list)): + self._send_byte_data(self.ctx, LGBMMessage.FEATURE_NAME.value, + json.dumps(self._all_feature_name).encode('utf-8'), i) + + self.log.info(f'task {self.ctx.task_id}: total feature number:{self._all_feature_num}, ' + f'total feature name: {self._all_feature_name}.') + self.params.categorical_idx = self._get_categorical_idx( + list(itertools.chain(*self._all_feature_name)), self.params.categorical_feature) + self.params.my_categorical_idx = self._get_categorical_idx( + self.dataset.feature_name, self.params.categorical_feature) + + # 更新feature_importance中的特征列表 + self.feature_importance_store.set_init( + list(itertools.chain(*self._all_feature_name))) + + # 初始化分桶数据集 + feat_bin = FeatureBinning(self.ctx) + self._X_bin, self._X_split = feat_bin.data_binning( + self.dataset.train_X) + + def _init_each_tree(self): + + if self.callback_container: + self.callback_container.before_iteration(self.model) + + gradient = self._loss_func.compute_gradient( + self.dataset.train_y, self._train_praba) + hessian = self._loss_func.compute_hessian(self._train_praba) + + feature_select = FeatureSelection.feature_selecting( + list(itertools.chain(*self._all_feature_name)), + self.params.train_feature, self.params.feature_rate) + instance, used_glist, used_hlist = Sampling.sample_selecting( + gradient, hessian, self.params.subsample, + self.params.use_goss, self.params.top_rate, self.params.other_rate) + self._send_gh_instance_list(instance, used_glist, used_hlist) + + return feature_select, instance, used_glist, used_hlist + + def _send_gh_instance_list(self, instance, glist, hlist): + + self._leaf_id = 0 + gh_list = self.packing_gh(glist, hlist) + + start_time = time.time() + self.log.info(f'task {self.ctx.task_id}: Starting n_estimators-{self._tree_id} ' + f'encrypt g & h in active party.') + enc_ghlist = self.ctx.phe.encrypt_batch_parallel( + (gh_list).astype('object')) + self.log.info(f'task {self.ctx.task_id}: Finished n_estimators-{self._tree_id} ' + f'encrypt gradient & hessian time_costs: {time.time() - start_time}.') + + for partner_index in range(1, len(self.ctx.participant_id_list)): + self._send_byte_data(self.ctx, f'{LGBMMessage.INSTANCE.value}_{self._tree_id}', + instance.astype('int64').tobytes(), partner_index) + self._send_enc_data(self.ctx, f'{LGBMMessage.ENC_GH_LIST.value}_{self._tree_id}', + enc_ghlist, partner_index) + + def _build_tree(self, feature_select, instance, glist, hlist, depth=0, weight=0): + + if depth == self.params.max_depth: + return weight + if self.params.max_depth < 0 and self._leaf_id >= self.params.num_leaves: + return weight + + self._leaf_id += 1 + if self.params.colsample_bylevel > 0 and self.params.colsample_bylevel < 1: + feature_select_level = sorted(np.random.choice( + feature_select, size=int(len(feature_select) * self.params.colsample_bylevel), replace=False)) + best_split_info = self._find_best_split( + feature_select_level, instance, glist, hlist) + else: + best_split_info = self._find_best_split( + feature_select, instance, glist, hlist) + + if best_split_info.best_gain > 0 and best_split_info.best_gain > self.params.min_split_gain: + gain_list = {FeatureImportanceType.GAIN: best_split_info.best_gain, + FeatureImportanceType.WEIGHT: 1} + self.feature_importance_store.update_feature_importance( + best_split_info.feature, gain_list) + left_mask, right_mask = self._get_leaf_mask( + best_split_info, instance) + + if (abs(best_split_info.w_left) * sum(left_mask) / self.params.lr) < self.params.min_child_weight or \ + (abs(best_split_info.w_right) * sum(right_mask) / self.params.lr) < self.params.min_child_weight: + return weight + if sum(left_mask) < self.params.min_child_samples or sum(right_mask) < self.params.min_child_samples: + return weight + + left_tree = self._build_tree( + feature_select, instance[left_mask], glist[left_mask], + hlist[left_mask], depth + 1, best_split_info.w_left) + right_tree = self._build_tree( + feature_select, instance[right_mask], glist[right_mask], + hlist[right_mask], depth + 1, best_split_info.w_right) + + return [(best_split_info, left_tree, right_tree)] + else: + return weight + + def _predict_tree(self, tree, X_bin, leaf_mask, key_type): + if not isinstance(tree, list): + return tree * leaf_mask + else: + best_split_info, left_subtree, right_subtree = tree[0] + if self.ctx.participant_id_list[best_split_info.agency_idx] == \ + self.ctx.components.config_data['AGENCY_ID']: + if best_split_info.agency_feature in self.params.my_categorical_idx: + left_mask = X_bin[:, + best_split_info.agency_feature] == best_split_info.value + else: + left_mask = X_bin[:, + best_split_info.agency_feature] <= best_split_info.value + else: + left_mask = np.frombuffer( + self._receive_byte_data( + self.ctx, + f'{key_type}_{best_split_info.tree_id}_{best_split_info.leaf_id}', + best_split_info.agency_idx), dtype='bool') + right_mask = ~left_mask + left_weight = self._predict_tree( + left_subtree, X_bin, leaf_mask * left_mask, key_type) + right_weight = self._predict_tree( + right_subtree, X_bin, leaf_mask * right_mask, key_type) + return left_weight + right_weight + + def _find_best_split(self, feature_select, instance, glist, hlist): + + self.log.info(f'task {self.ctx.task_id}: Starting n_estimators-{self._tree_id} ' + f'leaf-{self._leaf_id} in active party.') + grad_hist, hess_hist = self._get_gh_hist(instance, glist, hlist) + best_split_info = self._get_best_split_point( + feature_select, glist, hlist, grad_hist, hess_hist) + # print('grad_hist_sum', [sum(sublist) for sublist in grad_hist]) + + best_split_info.tree_id = self._tree_id + best_split_info.leaf_id = self._leaf_id + if best_split_info.best_gain > 0: + agency_idx, agency_feature = self._get_best_split_agency( + self._all_feature_name, best_split_info.feature) + best_split_info.agency_idx = agency_idx + best_split_info.agency_feature = agency_feature + + for partner_index in range(1, len(self.ctx.participant_id_list)): + self._send_byte_data( + ctx=self.ctx, + key_type=f'{LGBMMessage.SPLIT_INFO.value}_{self._tree_id}_{self._leaf_id}', + byte_data=utils.pb_to_bytes(best_split_info), + partner_index=partner_index) + self.log.info(f'task {self.ctx.task_id}: Ending n_estimators-{self._tree_id} ' + f'leaf-{self._leaf_id} in active party.') + # print('best_split_info', best_split_info) + return best_split_info + + def _get_gh_hist(self, instance, glist, hlist): + ghist, hhist = self._calculate_hist( + self._X_bin, instance, glist, hlist) + + for partner_index in range(1, len(self.ctx.participant_id_list)): + partner_feature_name = self._all_feature_name[partner_index] + + partner_ghist = [None] * len(partner_feature_name) + partner_hhist = [None] * len(partner_feature_name) + _, gh_hist = self._receive_enc_data( + self.ctx, f'{LGBMMessage.ENC_GH_HIST.value}_{self._tree_id}_{self._leaf_id}', + partner_index, matrix_data=True) + + for feature_index in range(len(partner_feature_name)): + ghk_hist = np.array(self.ctx.phe.decrypt_batch( + gh_hist[feature_index]), dtype='object') + gk_hist, hk_hist = self.unpacking_gh(ghk_hist) + partner_ghist[feature_index] = gk_hist + partner_hhist[feature_index] = hk_hist + + ghist.extend(partner_ghist) + hhist.extend(partner_hhist) + + return ghist, hhist + + @staticmethod + def _calculate_hist(X_bin, instance, used_glist, used_hlist): + + g_hist = [] + h_hist = [] + for k in range(X_bin.shape[1]): + Xk_bin = X_bin[instance, k] + gk_hist = [] + hk_hist = [] + sorted_x = sorted(set(X_bin[:, k])) + for v in sorted_x: + gk_hist.append(used_glist[Xk_bin == v].sum()) + hk_hist.append(used_hlist[Xk_bin == v].sum()) + g_hist.append(gk_hist) + h_hist.append(hk_hist) + + return g_hist, h_hist + + def _get_best_split_point(self, feature_select, glist, hlist, grad_hist, hess_hist): + + beat_feature, best_value, best_gain, best_wl, best_wr = None, None, 0, None, None + g = np.sum(glist) + h = np.sum(hlist) + + for feature in feature_select: + gl = 0 + hl = 0 + for value in range(len(grad_hist[feature])): + gl, hl = self._compute_gh_sum( + feature, value, self.params.categorical_idx, gl, hl, grad_hist, hess_hist) + gr = g - gl + hr = h - hl + + gain = self._compute_gain(g, h, gl, hl, gr, hr, self.params.λ) + wl, wr = self._compute_leaf_weight( + self.params.lr, self.params.λ, gl, hl, gr, hr, self.params.reg_alpha) + compare = bool(gain > best_gain) + # print('f', feature, 'v', value, 'gl', gl, 'gr', gr, 'hl', hl, 'hr', hr, + # 'gain', gain, 'wl', wl, 'wr', wr, 'compare', compare) + + if compare: + beat_feature = feature + best_value = value + best_wl = wl + best_wr = wr + best_gain = gain + + return BestSplitInfo(feature=beat_feature, + value=best_value, + best_gain=best_gain, + w_left=best_wl, + w_right=best_wr) + + @staticmethod + def _get_best_split_agency(all_feature_name, feature): + """Get the agency index and feature index of the best split point. + + Parameters + ---------- + all_feature_name : two-dimensional list + Feature list of all participating agency. + feature : int + Best split point global feature index. + + Returns + ------- + sublist_index : int + Agency index. + position_in_sublist : int + Feature index. + """ + count = 0 + for sublist_index, sublist in enumerate(all_feature_name): + if count + len(sublist) > feature: + position_in_sublist = feature - count + return sublist_index, position_in_sublist + count += len(sublist) + return None + + def _init_valid_data(self): + self._test_weights = self._init_weight(self.dataset.test_X.shape[0]) + self._test_X_bin = self._split_test_data( + self.ctx, self.dataset.test_X, self._X_split) + + def _init_early_stop(self): + + callbacks = [] + early_stopping_rounds = self.params.early_stopping_rounds + if early_stopping_rounds != 0: + eval_metric = self.params.eval_metric + early_stopping = EarlyStopping( + rounds=early_stopping_rounds, metric_name=eval_metric, save_best=True) + callbacks.append(early_stopping) + + verbose_eval = self.params.verbose_eval + if verbose_eval != 0: + evaluation_monitor = EvaluationMonitor( + logger=self.log, period=verbose_eval) + callbacks.append(evaluation_monitor) + + callback_container = None + if len(callbacks) != 0: + callback_container = CallbackContainer( + callbacks=callbacks, feval=Evaluation.fevaluation) + + model = Booster(y_true=self.dataset.train_y, test_y_true=self.dataset.test_y, + workspace=self.ctx.workspace, job_id=self.ctx.job_id, + ctx=self.ctx, + storage_client=self.storage_client) + + if callback_container: + callback_container.before_training(model) + + self.model = model + self.callback_container = callback_container + + def _iteration_early_stop(self): + # check early stopping + early_stopping_rounds = self.params.early_stopping_rounds + if early_stopping_rounds != 0: + # evaluate the model using test sets + eval_on_test = True + pred = self._test_praba + else: + eval_on_test = False + pred = self._train_praba + stop = False + if self.callback_container: + stop = self.callback_container.after_iteration(model=self.model, + pred=pred, + eval_on_test=eval_on_test) + self.log.info( + f"task {self.ctx.task_id}: after iteration {self._tree_id} iterations, stop: {stop}.") + + iteration_request = IterationRequest() + iteration_request.epoch = self._tree_id - 1 + iteration_request.stop = stop + + # send stop to passive + for partner_index in range(1, len(self.ctx.participant_id_list)): + self._send_byte_data( + ctx=self.ctx, + key_type=f'{LGBMMessage.STOP_ITERATION.value}_{self._tree_id}', + byte_data=utils.pb_to_bytes(iteration_request), + partner_index=partner_index) + + return stop + + def _end_active_data(self, is_train=True): + if is_train: + self.feature_importance_store.store( + serialize_type=SerializeType.CSV, local_file_path=self.ctx.feature_importance_file, + remote_file_path=self.ctx.remote_feature_importance_file, storage_client=self.storage_client, + user=self.ctx.user) + + if self.callback_container: + 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: + self._send_byte_data(self.ctx, f'{LGBMMessage.PREDICT_PRABA.value}_train', + self._train_praba.astype('float').tobytes(), partner_index) + + 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: + self._send_byte_data(self.ctx, f'{LGBMMessage.PREDICT_PRABA.value}_test', + self._test_praba.astype('float').tobytes(), partner_index) + + else: + 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: + self._send_byte_data(self.ctx, f'{LGBMMessage.PREDICT_PRABA.value}_predict', + self._test_praba.astype('float').tobytes(), partner_index) diff --git a/python/ppc_model/secure_lgbm/vertical/booster.py b/python/ppc_model/secure_lgbm/vertical/booster.py new file mode 100644 index 00000000..8eb94f44 --- /dev/null +++ b/python/ppc_model/secure_lgbm/vertical/booster.py @@ -0,0 +1,391 @@ +import os +import time +import random +import json +import numpy as np + +from ppc_common.ppc_protos.generated.ppc_model_pb2 import BestSplitInfo +from ppc_common.ppc_utils.utils import AlgorithmType +from ppc_model.model_crypto.crypto_aes import encrypt_data, decrypt_data, cipher_to_base64, base64_to_cipher +from ppc_model.interface.model_base import VerticalModel +from ppc_model.datasets.dataset import SecureDataset +from ppc_model.common.protocol import PheMessage +from ppc_model.common.model_result import ResultFileHandling +from ppc_model.datasets.feature_binning.feature_binning import FeatureBinning +from ppc_model.secure_model_base.secure_model_booster import SecureModelBooster +from ppc_model.secure_lgbm.secure_lgbm_context import SecureLGBMContext, LGBMMessage + +# 抽离sgb的公共部分 + + +class VerticalBooster(SecureModelBooster): + def __init__(self, ctx: SecureLGBMContext, dataset: SecureDataset) -> None: + super().__init__(ctx) + self.dataset = dataset + self._tree_id = None + self._leaf_id = None + self._X_bin = None + self._X_split = None + self._trees = [] + + self._train_weights = None + self._train_praba = None + self._test_weights = None + self._test_praba = None + random.seed(ctx.model_params.random_state) + np.random.seed(ctx.model_params.random_state) + + def _build_tree(self, *args, **kwargs): + + raise NotImplementedError + + def _predict_tree(self, *args, **kwargs): + + raise NotImplementedError + + def _init_praba(self, n): + return np.full(n, 0.5) + + def _init_weight(self, n): + return np.zeros(n, dtype=float) + + @staticmethod + def _get_categorical_idx(feature_name, categorical_feature=[]): + categorical_idx = [] + if len(categorical_feature) > 0: + for i in categorical_feature: + if i in feature_name: + categorical_idx.append(feature_name.index(i)) + return categorical_idx + + @staticmethod + def _compute_gh_sum(feature, value, categorical_idx, gl, hl, grad_hist, hess_hist): + if feature in categorical_idx: + gl = grad_hist[feature][value] + hl = hess_hist[feature][value] + else: + gl = gl + grad_hist[feature][value] + hl = hl + hess_hist[feature][value] + return gl, hl + + @staticmethod + def _compute_gain(g, h, gl, hl, gr, hr, λ): + if (h + λ) != 0 and (hl + λ) != 0 and (hr + λ) != 0: + return gl**2 / (hl + λ) + gr**2 / (hr + λ) - g**2 / (h + λ) + else: + return 0 + + @staticmethod + def _compute_leaf_weight(lr, λ, gl, hl, gr, hr, reg_alpha): + + weight_l = VerticalBooster._calulate_weight(lr, λ, gl, hl, reg_alpha) + weight_r = VerticalBooster._calulate_weight(lr, λ, gr, hr, reg_alpha) + + return weight_l, weight_r + + @staticmethod + def _calulate_weight(lr, λ, g, h, reg_alpha): + + # weight = lr * - g / (h + λ) + if (h + λ) != 0 and g > reg_alpha: + weight = lr * - (g - reg_alpha) / (h + λ) + elif (h + λ) != 0 and g < -reg_alpha: + weight = lr * - (g + reg_alpha) / (h + λ) + else: + weight = 0 + + return weight + + @staticmethod + def _get_leaf_instance(X, instance, feature, value, my_categorical_idx): + + if feature in my_categorical_idx: + left_mask = X[instance, feature] == value + right_mask = ~left_mask + else: + left_mask = X[instance, feature] <= value + right_mask = ~left_mask + + return left_mask, right_mask + + def _get_leaf_mask(self, split_info, instance): + + if self.ctx.participant_id_list[split_info.agency_idx] == self.ctx.components.config_data['AGENCY_ID']: + left_mask, right_mask = self._get_leaf_instance( + self._X_bin, instance, split_info.agency_feature, split_info.value, self.params.my_categorical_idx) + for partner_index in range(0, len(self.ctx.participant_id_list)): + if self.ctx.participant_id_list[partner_index] != self.ctx.components.config_data['AGENCY_ID']: + self._send_byte_data( + self.ctx, f'{LGBMMessage.INSTANCE_MASK.value}_{self._tree_id}_{self._leaf_id}', + left_mask.astype('bool').tobytes(), partner_index) + else: + left_mask = np.frombuffer( + self._receive_byte_data( + self.ctx, f'{LGBMMessage.INSTANCE_MASK.value}_{self._tree_id}_{self._leaf_id}', + split_info.agency_idx), dtype='bool') + right_mask = ~left_mask + + return left_mask, right_mask + + def _send_enc_data(self, ctx, key_type, enc_data, partner_index, matrix_data=False): + start_time = time.time() + partner_id = ctx.participant_id_list[partner_index] + + if matrix_data: + payload = PheMessage.packing_2dim_data( + ctx.codec, ctx.phe.public_key, enc_data) + else: + payload = PheMessage.packing_data( + ctx.codec, ctx.phe.public_key, enc_data) + self.ctx.model_router.push( + task_id=ctx.task_id, task_type=key_type, dst_agency=partner_id, payload=payload) + + self.logger.info( + f"task {ctx.task_id}: Sending {key_type} to {partner_id} finished, " + f"data_length: {len(enc_data)}, time_costs: {time.time() - start_time}s") + + def _receive_enc_data(self, ctx, key_type, partner_index, matrix_data=False): + start_time = time.time() + partner_id = ctx.participant_id_list[partner_index] + # send without payload + byte_data = self.ctx.model_router.pop( + task_id=ctx.task_id, task_type=key_type, from_inst=partner_id) + if matrix_data: + public_key, enc_data = PheMessage.unpacking_2dim_data( + ctx.codec, byte_data) + else: + public_key, enc_data = PheMessage.unpacking_data( + ctx.codec, byte_data) + + self.logger.info( + f"task {ctx.task_id}: Received {key_type} from {partner_id} finished, " + f"data_size: {len(byte_data) / 1024}KB, time_costs: {time.time() - start_time}s") + return public_key, enc_data + + def _send_byte_data(self, ctx, key_type, byte_data, partner_index): + start_time = time.time() + partner_id = ctx.participant_id_list[partner_index] + + self.ctx.model_router.push( + task_id=ctx.task_id, task_type=key_type, dst_agency=partner_id, payload=byte_data) + self.logger.info( + f"task {ctx.task_id}: Sending {key_type} to {partner_id} finished, " + f"data_size: {len(byte_data) / 1024}KB, time_costs: {time.time() - start_time}s") + + def _receive_byte_data(self, ctx, key_type, partner_index): + start_time = time.time() + partner_id = ctx.participant_id_list[partner_index] + + byte_data = self.ctx.model_router.pop( + task_id=ctx.task_id, task_type=key_type, from_inst=partner_id) + self.logger.info( + f"task {ctx.task_id}: Received {key_type} from {partner_id} finished, " + f"data_size: {len(byte_data) / 1024}KB, time_costs: {time.time() - start_time}s") + return byte_data + + @staticmethod + def _split_test_data(ctx, test_X, X_split): + feat_bin = FeatureBinning(ctx) + return feat_bin.data_binning(test_X, X_split)[0] + + def save_model(self): + super().save_model("lgbm_model") + + def save_model_hook(self): + # save the feature_bin + if self._X_split is not None and not os.path.exists(self.ctx.feature_bin_file): + X_split_dict = {k: v for k, v in zip( + self.dataset.feature_name, self._X_split)} + with open(self.ctx.feature_bin_file, 'w') as f: + json.dump(X_split_dict, f) + ResultFileHandling._upload_file(self.ctx.components.storage_client, + self.ctx.feature_bin_file, + self.ctx.remote_feature_bin_file, + self.ctx.user) + self.logger.info( + f"task {self.ctx.task_id}: Saved x_split to {self.ctx.feature_bin_file} finished, split size: {len(X_split_dict.keys())}") + if not os.path.exists(self.ctx.model_data_file): + serial_trees = [self._serial_tree(tree) for tree in self._trees] + with open(self.ctx.model_data_file, 'w') as f: + json.dump(serial_trees, f) + ResultFileHandling._upload_file(self.ctx.components.storage_client, + self.ctx.model_data_file, + self.ctx.remote_model_data_file, + self.ctx.user) + self.logger.info( + f"task {self.ctx.task_id}: Saved serial_trees to {self.ctx.model_data_file} finished.") + + def merge_model_file(self, lgbm_model): + # 加密文件 + model_text = {} + with open(self.ctx.feature_bin_file, 'rb') as f: + feature_bin_data = f.read() + with open(self.ctx.model_data_file, 'rb') as f: + model_data = f.read() + feature_bin_enc = encrypt_data(self.ctx.key, feature_bin_data) + model_data_enc = encrypt_data(self.ctx.key, model_data) + + my_agency_id = self.ctx.components.config_data['AGENCY_ID'] + model_text[my_agency_id] = [cipher_to_base64( + feature_bin_enc), cipher_to_base64(model_data_enc)] + + # 发送&接受文件 + for partner_index in range(0, len(self.ctx.participant_id_list)): + if self.ctx.participant_id_list[partner_index] != my_agency_id: + self._send_byte_data( + self.ctx, f'{LGBMMessage.MODEL_DATA.value}_feature_bin', + feature_bin_enc, partner_index) + self._send_byte_data( + self.ctx, f'{LGBMMessage.MODEL_DATA.value}_model_data', + model_data_enc, partner_index) + for partner_index in range(0, len(self.ctx.participant_id_list)): + if self.ctx.participant_id_list[partner_index] != my_agency_id: + feature_bin_enc = self._receive_byte_data( + self.ctx, f'{LGBMMessage.MODEL_DATA.value}_feature_bin', partner_index) + model_data_enc = self._receive_byte_data( + self.ctx, f'{LGBMMessage.MODEL_DATA.value}_model_data', partner_index) + model_text[self.ctx.participant_id_list[partner_index]] = \ + [cipher_to_base64(feature_bin_enc), + cipher_to_base64(model_data_enc)] + lgbm_model['model_text'] = model_text + + # 上传密文模型 + with open(self.ctx.model_enc_file, 'w') as f: + json.dump(lgbm_model, f) + ResultFileHandling._upload_file(self.ctx.components.storage_client, + self.ctx.model_enc_file, + self.ctx.remote_model_enc_file, + self.ctx.user) + self.logger.info( + f"task {self.ctx.task_id}: Saved enc model to {self.ctx.model_enc_file} finished.") + + def split_model_file(self): + + # 传入模型 + my_agency_id = self.ctx.components.config_data['AGENCY_ID'] + model_text = self.ctx.model_predict_algorithm['model_text'] + feature_bin_enc, model_data_enc = [ + base64_to_cipher(i) for i in model_text[my_agency_id]] + + # 解密文件 + feature_bin_data = decrypt_data(self.ctx.key, feature_bin_enc) + model_data = decrypt_data(self.ctx.key, model_data_enc) + with open(self.ctx.feature_bin_file, 'wb') as f: + f.write(feature_bin_data) + with open(self.ctx.model_data_file, 'wb') as f: + f.write(model_data) + + def load_model(self, file_path=None): + if file_path is not None: + self.ctx.feature_bin_file = os.path.join( + file_path, self.ctx.FEATURE_BIN_FILE) + self.ctx.model_data_file = os.path.join( + file_path, self.ctx.MODEL_DATA_FILE) + + try: + ResultFileHandling._download_file(self.ctx.components.storage_client, + self.ctx.feature_bin_file, self.ctx.remote_feature_bin_file) + ResultFileHandling._download_file(self.ctx.components.storage_client, + self.ctx.model_data_file, self.ctx.remote_model_data_file) + except: + self.split_model_file() + + with open(self.ctx.feature_bin_file, 'r') as f: + X_split_dict = json.load(f) + feature_name = list(X_split_dict.keys()) + x_split = list(X_split_dict.values()) + self.logger.info( + f"task {self.ctx.task_id}: Load x_split from {self.ctx.feature_bin_file} finished.") + assert len(feature_name) == len(self.dataset.feature_name) + + with open(self.ctx.model_data_file, 'r') as f: + serial_trees = json.load(f) + self.logger.info( + f"task {self.ctx.task_id}: Load serial_trees from {self.ctx.model_data_file} finished.") + + trees = [self._deserial_tree(tree) for tree in serial_trees] + self._X_split = x_split + # self.my_feature_name = feature_name + self._trees = trees + + @staticmethod + def _serial_tree(tree): + if isinstance(tree, list): + best_split_info, left_tree, right_tree = tree[0] + best_split_info_list = [] + for field in best_split_info.DESCRIPTOR.fields: + best_split_info_list.append( + getattr(best_split_info, field.name)) + left_tree = VerticalBooster._serial_tree(left_tree) + right_tree = VerticalBooster._serial_tree(right_tree) + best_split_info_list.extend([left_tree, right_tree]) + return best_split_info_list + else: + return tree + + @staticmethod + def _deserial_tree(tree_list): + if isinstance(tree_list, list): + best_split_info_list = tree_list[:-2] + left_tree, right_tree = tree_list[-2:] + best_split_info = BestSplitInfo() + for i, field in enumerate(best_split_info.DESCRIPTOR.fields): + setattr(best_split_info, field.name, best_split_info_list[i]) + left_tree = VerticalBooster._deserial_tree(left_tree) + right_tree = VerticalBooster._deserial_tree(right_tree) + return [(best_split_info, left_tree, right_tree)] + else: + return tree_list + + def get_trees(self): + return self._trees + + def get_x_split(self): + return self._X_split + + def get_train_praba(self): + return self._train_praba + + def get_test_praba(self): + return self._test_praba + + @staticmethod + def packing_gh(g_list: np.ndarray, h_list: np.ndarray, expand=1000, mod_length=32, pack_length=20): + ''' + 1. 转正整数 + g和h的梯度值为浮点数, 取值范围: [-1 ~ 1] + 浮点数转整数默乘以 1000(取3位小数) + 按照最高数据量100w样本, g/h求和值上限为 1000 * 10**6 = 10**9 + 基于g/h上限, 负数模运算转正数需要加上 2**32 (4.29*10**9) + + 2. packing + g/h负数模运算转为正数后最大值为 2**32-1, 100w样本求和需要预留10**6位 + packing g和h时, 对g乘以10**20, 为h预留总计20位长度。 + ''' + mod_n = 2 ** mod_length + pos_int_glist = ((g_list * expand).astype('int64') + mod_n) % mod_n + pos_int_hlist = ((h_list * expand).astype('int64') + mod_n) % mod_n + + gh_list = pos_int_glist.astype( + 'object') * 10**pack_length + pos_int_hlist.astype('object') + + return gh_list + + @staticmethod + def unpacking_gh(gh_sum_list: np.ndarray, expand=1000, mod_length=32, pack_length=20): + ''' + 1. 拆解g_pos_int_sum和h_pos_int_sum + 2. 还原g_sum和h_sum + ''' + + mod_n = 2 ** mod_length + g_pos_int_sum = (gh_sum_list // 10**pack_length) % mod_n + h_pos_int_sum = (gh_sum_list % 10**pack_length) % mod_n + + g_pos_int_sum[g_pos_int_sum > 2**(mod_length-1)] -= mod_n + h_pos_int_sum[g_pos_int_sum > 2**(mod_length-1)] -= mod_n + + g_hist = (g_pos_int_sum / expand).astype('float') + h_hist = (h_pos_int_sum / expand).astype('float') + + return g_hist, h_hist diff --git a/python/ppc_model/secure_lgbm/vertical/passive_party.py b/python/ppc_model/secure_lgbm/vertical/passive_party.py new file mode 100644 index 00000000..0a3d773f --- /dev/null +++ b/python/ppc_model/secure_lgbm/vertical/passive_party.py @@ -0,0 +1,286 @@ +import multiprocessing +import time +import json +import numpy as np +from pandas import DataFrame + +from ppc_common.ppc_utils import utils +from ppc_common.ppc_protos.generated.ppc_model_pb2 import BestSplitInfo, IterationRequest +from ppc_model.datasets.dataset import SecureDataset +from ppc_model.datasets.feature_binning.feature_binning import FeatureBinning +from ppc_model.secure_lgbm.secure_lgbm_context import SecureLGBMContext, LGBMMessage +from ppc_model.secure_lgbm.vertical.booster import VerticalBooster + + +class VerticalLGBMPassiveParty(VerticalBooster): + + def __init__(self, ctx: SecureLGBMContext, dataset: SecureDataset) -> None: + super().__init__(ctx, dataset) + self.params = ctx.model_params + self._all_feature_name = [] + self.log = ctx.components.logger() + self.log.info( + f'task {self.ctx.task_id}: print all params: {self.params.get_all_params()}') + + def fit( + self, + *args, + **kwargs, + ) -> None: + self.log.info( + f'task {self.ctx.task_id}: Starting the lgbm on the passive party.') + self._init_passive_data() + self._test_X_bin = self._split_test_data( + self.ctx, self.dataset.test_X, self._X_split) + + for _ in range(self.params.n_estimators): + self._tree_id += 1 + start_time = time.time() + self.log.info( + f'task {self.ctx.task_id}: Starting n_estimators-{self._tree_id} in passive party.') + + # 初始化 + instance, used_ghlist, public_key = self._receive_gh_instance_list() + self.ctx.phe.public_key = public_key + self.log.info( + f'task {self.ctx.task_id}: Sampling number: {len(instance)}.') + + # 构建 + tree = self._build_tree(instance, used_ghlist) + self._trees.append(tree) + + # 预测 + self._predict_tree(tree, self._X_bin, + LGBMMessage.PREDICT_LEAF_MASK.value) + self.log.info(f'task {self.ctx.task_id}: Ending n_estimators-{self._tree_id}, ' + f'time_costs: {time.time() - start_time}s.') + + # 预测验证集 + self._predict_tree(tree, self._test_X_bin, + LGBMMessage.TEST_LEAF_MASK.value) + if self._iteration_early_stop(): + self.log.info( + f"task {self.ctx.task_id}: lgbm early stop after {self._tree_id} iterations.") + break + + self._end_passive_data() + + def transform(self, transform_data: DataFrame) -> DataFrame: + ... + + def predict(self, dataset: SecureDataset = None) -> np.ndarray: + start_time = time.time() + if dataset is None: + dataset = self.dataset + + self.params.my_categorical_idx = self._get_categorical_idx( + dataset.feature_name, self.params.categorical_feature) + + test_X_bin = self._split_test_data( + self.ctx, dataset.test_X, self._X_split) + + [self._predict_tree( + tree, test_X_bin, LGBMMessage.VALID_LEAF_MASK.value) for tree in self._trees] + self.log.info( + f'task {self.ctx.task_id}: Ending predict, time_costs: {time.time() - start_time}s.') + + self._end_passive_data(is_train=False) + + def _init_passive_data(self): + + # 初始化tree id + self._tree_id = 0 + + # 初始化参与方特征 + self._send_byte_data(self.ctx, LGBMMessage.FEATURE_NAME.value, + b''.join(s.encode('utf-8') + b' ' for s in self.dataset.feature_name), 0) + self.params.my_categorical_idx = self._get_categorical_idx( + self.dataset.feature_name, self.params.categorical_feature) + feature_name_bytes = self._receive_byte_data( + self.ctx, LGBMMessage.FEATURE_NAME.value, 0) + self._all_feature_name = json.loads(feature_name_bytes.decode('utf-8')) + + # 初始化分桶数据集 + feat_bin = FeatureBinning(self.ctx) + self._X_bin, self._X_split = feat_bin.data_binning( + self.dataset.train_X) + + def _receive_gh_instance_list(self): + + self._leaf_id = 0 + + instance = np.frombuffer( + self._receive_byte_data( + self.ctx, f'{LGBMMessage.INSTANCE.value}_{self._tree_id}', 0), dtype=np.int64) + public_key, gh = self._receive_enc_data( + self.ctx, f'{LGBMMessage.ENC_GH_LIST.value}_{self._tree_id}', 0) + + return instance, np.array(gh), public_key + + def _build_tree(self, instance, ghlist, depth=0, weight=0): + + if depth == self.params.max_depth: + return weight + if self.params.max_depth < 0 and self._leaf_id >= self.params.num_leaves: + return weight + + self._leaf_id += 1 + best_split_info = self._find_best_split(instance, ghlist) + + if best_split_info.best_gain > 0 and best_split_info.best_gain > self.params.min_split_gain: + left_mask, right_mask = self._get_leaf_mask( + best_split_info, instance) + + if (abs(best_split_info.w_left) * sum(left_mask) / self.params.lr) < self.params.min_child_weight or \ + (abs(best_split_info.w_right) * sum(right_mask) / self.params.lr) < self.params.min_child_weight: + return weight + if sum(left_mask) < self.params.min_child_samples or sum(right_mask) < self.params.min_child_samples: + return weight + + left_tree = self._build_tree( + instance[left_mask], ghlist[left_mask], + depth + 1, best_split_info.w_left) + right_tree = self._build_tree( + instance[right_mask], ghlist[right_mask], + depth + 1, best_split_info.w_right) + + return [(best_split_info, left_tree, right_tree)] + else: + return weight + + def _predict_tree(self, tree, X_bin, key_type): + if not isinstance(tree, list): + return None + else: + best_split_info, left_subtree, right_subtree = tree[0] + if self.ctx.participant_id_list[best_split_info.agency_idx] == \ + self.ctx.components.config_data['AGENCY_ID']: + if best_split_info.agency_feature in self.params.my_categorical_idx: + left_mask = X_bin[:, + best_split_info.agency_feature] == best_split_info.value + else: + left_mask = X_bin[:, + best_split_info.agency_feature] <= best_split_info.value + self._send_byte_data( + self.ctx, + f'{key_type}_{best_split_info.tree_id}_{best_split_info.leaf_id}', + left_mask.astype('bool').tobytes(), 0) + else: + pass + left_weight = self._predict_tree(left_subtree, X_bin, key_type) + right_weight = self._predict_tree(right_subtree, X_bin, key_type) + return [left_weight, right_weight] + + def _find_best_split(self, instance, ghlist): + + self.log.info(f'task {self.ctx.task_id}: Starting n_estimators-{self._tree_id} ' + f'leaf-{self._leaf_id} in passive party.') + if len(instance) > 200000: + self._get_gh_hist_parallel(instance, ghlist) + else: + self._get_gh_hist(instance, ghlist) + + best_split_info_byte = self._receive_byte_data( + self.ctx, f'{LGBMMessage.SPLIT_INFO.value}_{self._tree_id}_{self._leaf_id}', 0) + best_split_info = BestSplitInfo() + utils.bytes_to_pb(best_split_info, best_split_info_byte) + + self.log.info(f'task {self.ctx.task_id}: Ending n_estimators-{self._tree_id} ' + f'leaf-{self._leaf_id} in passive party.') + return best_split_info + + def _get_gh_hist_parallel(self, instance, ghlist): + + params = [] + for i in range(len(self.dataset.feature_name)): + params.append({ + 'bins': self._X_bin[:, i], + 'xk_bin': self._X_bin[:, i][instance], + 'enc_gh_list': ghlist, + 'phe': self.ctx.phe + }) + + start_time = time.time() + self.log.info(f'task {self.ctx.task_id}: Start n_estimators-{self._tree_id} ' + f'leaf-{self._leaf_id} calculate hist in passive party.') + + # gh_hist = [] + # with ProcessPoolExecutor() as executor: + # futures = [executor.submit(self._calculate_hist, context) for context in params] + # for future in as_completed(futures): + # gh_hist.append(future.result()) + + pool = multiprocessing.Pool() + gh_hist = pool.map(self._calculate_hist, params) + pool.close() + pool.join() + + self.log.info(f'task {self.ctx.task_id}: End n_estimators-{self._tree_id} ' + f'leaf-{self._leaf_id} calculate hist time_costs: {time.time() - start_time}s.') + self._send_enc_data(self.ctx, + f'{LGBMMessage.ENC_GH_HIST.value}_{self._tree_id}_{self._leaf_id}', + gh_hist, 0, matrix_data=True) + + def _get_gh_hist(self, instance, ghlist): + + gh_hist = [] + start_time = time.time() + self.log.info(f'task {self.ctx.task_id}: Start n_estimators-{self._tree_id} ' + f'leaf-{self._leaf_id} calculate hist in passive party.') + + for i in range(len(self.dataset.feature_name)): + param = { + 'bins': self._X_bin[:, i], + 'xk_bin': self._X_bin[:, i][instance], + 'enc_gh_list': ghlist, + 'phe': self.ctx.phe + } + gh_hist.append(self._calculate_hist(param)) + + self.log.info(f'task {self.ctx.task_id}: Start n_estimators-{self._tree_id} ' + f'leaf-{self._leaf_id} calculate hist time_costs: {time.time() - start_time}s.') + self._send_enc_data(self.ctx, + f'{LGBMMessage.ENC_GH_HIST.value}_{self._tree_id}_{self._leaf_id}', + gh_hist, 0, matrix_data=True) + + @staticmethod + def _calculate_hist(param): + bins = param['bins'] + gh_list = param['enc_gh_list'] + phe = param['phe'] + xk_bin = param['xk_bin'] + ghk_hist = [] + sorted_bins = sorted(set(bins)) + for v in sorted_bins: + # 处理gk_hist中部分分桶没有样本,直接结算值为明文0的情况 + if len(gh_list[xk_bin == v]) == 0: + ghk_hist.append(phe.encrypt(0)) + else: + ghk_hist.append(gh_list[xk_bin == v].sum()) + return ghk_hist + + def _iteration_early_stop(self): + + iteration_request_byte = self._receive_byte_data( + self.ctx, f'{LGBMMessage.STOP_ITERATION.value}_{self._tree_id}', 0) + iteration_request = IterationRequest() + utils.bytes_to_pb(iteration_request, iteration_request_byte) + + return iteration_request.stop + + def _end_passive_data(self, is_train=True): + + if self.ctx.components.config_data['AGENCY_ID'] in self.ctx.result_receiver_id_list: + if is_train: + self._train_praba = np.frombuffer( + self._receive_byte_data( + self.ctx, f'{LGBMMessage.PREDICT_PRABA.value}_train', 0), dtype=np.float) + + self._test_praba = np.frombuffer( + self._receive_byte_data( + self.ctx, f'{LGBMMessage.PREDICT_PRABA.value}_test', 0), dtype=np.float) + + else: + self._test_praba = np.frombuffer( + self._receive_byte_data( + self.ctx, f'{LGBMMessage.PREDICT_PRABA.value}_predict', 0), dtype=np.float) diff --git a/python/ppc_model/secure_lr/__init__.py b/python/ppc_model/secure_lr/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/python/ppc_model/secure_lr/secure_lr_context.py b/python/ppc_model/secure_lr/secure_lr_context.py new file mode 100644 index 00000000..a3fa20a6 --- /dev/null +++ b/python/ppc_model/secure_lr/secure_lr_context.py @@ -0,0 +1,127 @@ +import os +from enum import Enum +from ppc_common.ppc_utils.utils import AlgorithmType +from ppc_common.ppc_crypto.phe_factory import PheCipherFactory +from ppc_model.common.initializer import Initializer +from ppc_model.common.protocol import TaskRole +from ppc_common.ppc_utils import common_func +from ppc_model.common.model_setting import ModelSetting +from ppc_model.secure_model_base.secure_model_context import SecureModel +from ppc_model.secure_model_base.secure_model_context import SecureModelContext + + +class LRModel(SecureModel): + + def __init__( + self, + epochs: int = 10, + batch_size: int = 8, + learning_rate: float = 0.1, + random_state: int = None, + n_jobs: int = None, + **kwargs + ): + + self.epochs = epochs + self.batch_size = batch_size + self.learning_rate = learning_rate + self.random_state = random_state + self.n_jobs = n_jobs + super().__init__(**kwargs) + + +class ModelTaskParams(LRModel): + def __init__( + self, + test_size: float = 0.3, + feature_rate: float = 1.0, + eval_set_column: str = None, + train_set_value: str = None, + eval_set_value: str = None, + train_feats: str = None, + verbose_eval: int = 1, + categorical_feature: list = [], + silent: bool = False + ): + + super().__init__() + + self.test_size = test_size + self.feature_rate = feature_rate + self.eval_set_column = eval_set_column + self.train_set_value = train_set_value + self.eval_set_value = eval_set_value + self.train_feature = train_feats + self.verbose_eval = verbose_eval + self.silent = silent + self.lr = self.learning_rate + self.categorical_feature = categorical_feature + self.categorical_idx = [] + self.my_categorical_idx = [] + + +class SecureLRParams(ModelTaskParams): + + def __init__(self): + super().__init__() + + def _get_params(self): + """返回LRClassifier所有参数""" + return LRModel().get_params() + + +class SecureLRContext(SecureModelContext): + + def __init__(self, + task_id, + args, + components: Initializer + ): + super().__init__(task_id, args, components) + + self.phe = PheCipherFactory.build_phe( + components.homo_algorithm, components.public_key_length) + self.codec = PheCipherFactory.build_codec(components.homo_algorithm) + + def create_model_param(self): + return SecureLRParams() + + def get_model_params(self): + """获取lr参数""" + return self.model_params + + def set_sync_file(self): + 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 LRMessage(Enum): + FEATURE_NAME = "FEATURE_NAME" + ENC_D_LIST = "ENC_D_LIST" + ENC_D_HIST = "ENC_D_HIST" + D_MATMUL = "D_MATMUL" + PREDICT_LEAF_MASK = "PREDICT_LEAF_MASK" + TEST_LEAF_MASK = "PREDICT_TEST_LEAF_MASK" + VALID_LEAF_MASK = "PREDICT_VALID_LEAF_MASK" + PREDICT_PRABA = "PREDICT_PRABA" + MODEL_DATA = "MODEL_DATA" diff --git a/python/ppc_model/secure_lr/secure_lr_prediction_engine.py b/python/ppc_model/secure_lr/secure_lr_prediction_engine.py new file mode 100644 index 00000000..853b698c --- /dev/null +++ b/python/ppc_model/secure_lr/secure_lr_prediction_engine.py @@ -0,0 +1,38 @@ +from ppc_common.ppc_utils.exception import PpcException, PpcErrorCode +from ppc_model.common.protocol import TaskRole, ModelTask +from ppc_model.common.global_context import components +from ppc_model.interface.task_engine import TaskEngine +from ppc_model.datasets.dataset import SecureDataset +from ppc_model.metrics.evaluation import Evaluation +from ppc_model.common.model_result import ResultFileHandling +from ppc_model.secure_lr.secure_lr_context import SecureLRContext +from ppc_model.secure_lr.vertical import VerticalLRActiveParty, VerticalLRPassiveParty + + +class SecureLRPredictionEngine(TaskEngine): + task_type = ModelTask.LR_PREDICTING + + @staticmethod + def run(task_id, args): + + task_info = SecureLRContext(task_id, args, components) + secure_dataset = SecureDataset(task_info) + + if task_info.role == TaskRole.ACTIVE_PARTY: + booster = VerticalLRActiveParty(task_info, secure_dataset) + elif task_info.role == TaskRole.PASSIVE_PARTY: + booster = VerticalLRPassiveParty(task_info, secure_dataset) + else: + raise PpcException(PpcErrorCode.ROLE_TYPE_ERROR.get_code(), + PpcErrorCode.ROLE_TYPE_ERROR.get_message()) + + booster.load_model() + booster.predict() + + # 获取测试集的预测概率值 + test_praba = booster.get_test_praba() + + # 获取测试集的预测值评估指标 + Evaluation(task_info, secure_dataset, test_praba=test_praba) + + ResultFileHandling(task_info) diff --git a/python/ppc_model/secure_lr/secure_lr_training_engine.py b/python/ppc_model/secure_lr/secure_lr_training_engine.py new file mode 100644 index 00000000..21cef8d2 --- /dev/null +++ b/python/ppc_model/secure_lr/secure_lr_training_engine.py @@ -0,0 +1,39 @@ +from ppc_common.ppc_utils.exception import PpcException, PpcErrorCode +from ppc_model.common.protocol import TaskRole, ModelTask +from ppc_model.common.global_context import components +from ppc_model.interface.task_engine import TaskEngine +from ppc_model.datasets.dataset import SecureDataset +from ppc_model.metrics.evaluation import Evaluation +from ppc_model.metrics.model_plot import ModelPlot +from ppc_model.common.model_result import ResultFileHandling +from ppc_model.secure_lr.secure_lr_context import SecureLRContext +from ppc_model.secure_lr.vertical import VerticalLRActiveParty, VerticalLRPassiveParty + + +class SecureLRTrainingEngine(TaskEngine): + task_type = ModelTask.LR_TRAINING + + @staticmethod + def run(task_id, args): + + task_info = SecureLRContext(task_id, args, components) + secure_dataset = SecureDataset(task_info) + + if task_info.role == TaskRole.ACTIVE_PARTY: + booster = VerticalLRActiveParty(task_info, secure_dataset) + elif task_info.role == TaskRole.PASSIVE_PARTY: + booster = VerticalLRPassiveParty(task_info, secure_dataset) + else: + raise PpcException(PpcErrorCode.ROLE_TYPE_ERROR.get_code(), + PpcErrorCode.ROLE_TYPE_ERROR.get_message()) + + booster.fit() + booster.save_model() + + # 获取训练集和验证集的预测概率值 + train_praba = booster.get_train_praba() + test_praba = booster.get_test_praba() + + # 获取训练集和验证集的预测值评估指标 + Evaluation(task_info, secure_dataset, train_praba, test_praba) + ResultFileHandling(task_info) diff --git a/python/ppc_model/secure_lr/test/__init__.py b/python/ppc_model/secure_lr/test/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/python/ppc_model/secure_lr/test/test_enc_matmul.py b/python/ppc_model/secure_lr/test/test_enc_matmul.py new file mode 100644 index 00000000..4b78b0eb --- /dev/null +++ b/python/ppc_model/secure_lr/test/test_enc_matmul.py @@ -0,0 +1,64 @@ +import unittest +import numpy as np + +from ppc_model.common.initializer import Initializer +from ppc_model.secure_lr.secure_lr_context import SecureLRContext +from ppc_model.secure_lr.vertical.booster import VerticalBooster + + +ACTIVE_PARTY = 'ACTIVE_PARTY' + +job_id = 'j-1234' +task_id = 't-1234' + +model_dict = { + 'objective': 'regression', + 'categorical_feature': [], + 'train_features': "", + 'epochs': 1, + 'batch_size': 8, + 'feature_rate': 0.8, + 'random_state': 2024 +} + +args = { + 'job_id': job_id, + 'task_id': task_id, + 'is_label_holder': True, + 'result_receiver_id_list': [], + 'participant_id_list': [], + 'model_predict_algorithm': None, + 'algorithm_type': 'Train', + 'algorithm_subtype': 'HeteroXGB', + 'model_dict': model_dict +} + + +class TestEncMatmul(unittest.TestCase): + + def test_enc_matmul(self): + active_components = Initializer(log_config_path='', config_path='') + active_components.config_data = { + 'JOB_TEMP_DIR': '/tmp/active', 'AGENCY_ID': ACTIVE_PARTY} + task_info = SecureLRContext(args['task_id'], args, active_components) + + # 15个特征,batch_size: 8 + arr = np.array([2, 4, -5, 0, 9, -7, 12, 3]) + np.random.seed(0) + # x = np.random.randint(-10, 10, size=(15, 8)) + x = np.random.randint(0, 10, size=(15, 8)) + enc_arr = task_info.phe.encrypt_batch_parallel((arr).astype('object')) + enc_x_d = VerticalBooster.enc_matmul(x, enc_arr) + x_d_rec = np.array(task_info.phe.decrypt_batch(enc_x_d), dtype='object') + x_d_rec[x_d_rec > 2**(task_info.phe.key_length-1)] -= 2**(task_info.phe.key_length) + + assert (np.matmul(x, arr) == x_d_rec).all() + + arr_ = VerticalBooster.rounding_d(arr) + x_ = VerticalBooster.rounding_d(x) + enc_arr = task_info.phe.encrypt_batch_parallel((arr_).astype('object')) + enc_x_d = VerticalBooster.enc_matmul(x_, enc_arr) + x_d_rec = np.array(task_info.phe.decrypt_batch(enc_x_d), dtype='object') + x_d_rec = VerticalBooster.recover_d(task_info, x_d_rec, is_square=True) + + assert (np.matmul(x, arr) == x_d_rec).all() diff --git a/python/ppc_model/secure_lr/test/test_lr.py b/python/ppc_model/secure_lr/test/test_lr.py new file mode 100644 index 00000000..397d0b07 --- /dev/null +++ b/python/ppc_model/secure_lr/test/test_lr.py @@ -0,0 +1,202 @@ +from sklearn.preprocessing import StandardScaler +from sklearn.preprocessing import MinMaxScaler +import unittest +import threading +import traceback +import numpy as np +from sklearn.datasets import load_breast_cancer + +from ppc_model.common.initializer import Initializer +from ppc_common.ppc_mock.mock_objects import MockLogger +from ppc_model.datasets.dataset import SecureDataset +from ppc_model.metrics.evaluation import Evaluation +from ppc_model.metrics.loss import BinaryLoss +from ppc_model.secure_lr.secure_lr_context import SecureLRContext +from ppc_model.secure_lr.vertical.booster import VerticalBooster + + +ACTIVE_PARTY = 'ACTIVE_PARTY' +PASSIVE_PARTY = 'PASSIVE_PARTY' + + +def mock_args(): + job_id = 'j-1234' + task_id = 't-1234' + + model_dict = { + 'objective': 'regression', + 'categorical_feature': [], + 'train_features': "", + 'epochs': 1, + 'batch_size': 8, + 'feature_rate': 0.8, + 'random_state': 2024 + } + + args_a = { + 'job_id': job_id, + 'task_id': task_id, + 'is_label_holder': True, + 'result_receiver_id_list': [ACTIVE_PARTY, PASSIVE_PARTY], + 'participant_id_list': [ACTIVE_PARTY, PASSIVE_PARTY], + 'model_predict_algorithm': None, + 'algorithm_type': 'Train', + 'algorithm_subtype': 'HeteroXGB', + 'model_dict': model_dict + } + + args_b = { + 'job_id': job_id, + 'task_id': task_id, + 'is_label_holder': False, + 'result_receiver_id_list': [ACTIVE_PARTY, PASSIVE_PARTY], + 'participant_id_list': [ACTIVE_PARTY, PASSIVE_PARTY], + 'model_predict_algorithm': None, + 'algorithm_type': 'Train', + 'algorithm_subtype': 'HeteroXGB', + 'model_dict': model_dict + } + + return args_a, args_b + + +cancer = load_breast_cancer() +X = cancer.data +y = cancer.target + +df = SecureDataset.assembling_dataset(X, y) +df_with_y, df_without_y = SecureDataset.hetero_split_dataset(df) + +args_a, args_b = mock_args() + +active_components = Initializer(log_config_path='', config_path='') +active_components.config_data = { + 'JOB_TEMP_DIR': '/tmp/active', 'AGENCY_ID': ACTIVE_PARTY} +active_components.mock_logger = MockLogger() +task_info_a = SecureLRContext(args_a['task_id'], args_a, active_components) + +# df --------------------------------------------- +secure_dataset = SecureDataset(task_info_a, df) +max_iter = VerticalBooster._init_iter( + secure_dataset.train_X.shape[0], 3, 8) + +train_praba = VerticalBooster._init_praba(secure_dataset.train_X.shape[0]) +train_weights = VerticalBooster._init_weight(secure_dataset.train_X.shape[1]) +bias = 0 + +# for _ in range(max_iter): +for i in range(1): + idx = VerticalBooster._get_sample_idx( + i, secure_dataset.train_X.shape[0], size=8) + x_, y_ = secure_dataset.train_X[idx], secure_dataset.train_y[idx] + + g = BinaryLoss.dot_product(x_, train_weights) + bias + # h = 0.5 + BinaryLoss.inference(g) + h = BinaryLoss.sigmoid(g) + d = h - y_ + deriv = np.matmul(x_.T, d) / x_.shape[0] + deriv_bias = np.sum(d) / x_.shape[0] + print(deriv) + + train_weights -= 0.1 * deriv.astype('float') + bias -= 0.1 * deriv_bias + print(train_weights) + print(bias) + +g = BinaryLoss.dot_product(secure_dataset.train_X, train_weights) + bias +train_praba = BinaryLoss.sigmoid(g) +auc = Evaluation.fevaluation(secure_dataset.train_y, train_praba)['auc'] +print(auc) + + +# df --------------------------------------------- +# not bias +train_praba = VerticalBooster._init_praba(secure_dataset.train_X.shape[0]) +train_weights = VerticalBooster._init_weight(secure_dataset.train_X.shape[1]) + +# for _ in range(max_iter): +for i in range(2): + idx = VerticalBooster._get_sample_idx( + i, secure_dataset.train_X.shape[0], size=8) + x_, y_ = secure_dataset.train_X[idx], secure_dataset.train_y[idx] + + g = BinaryLoss.dot_product(x_, train_weights) + h = 0.5 + BinaryLoss.inference(g) + # h = BinaryLoss.sigmoid(g) + d = h - y_ + deriv = np.matmul(x_.T, d) / x_.shape[0] + print(deriv) + + train_weights -= 0.1 * deriv.astype('float') + print(train_weights) + +g = BinaryLoss.dot_product(secure_dataset.train_X, train_weights) +# train_praba = 0.5 + BinaryLoss.inference(g) +train_praba = BinaryLoss.sigmoid(g) +auc = Evaluation.fevaluation(secure_dataset.train_y, train_praba)['auc'] +print(auc) + + +# df --------------------------------------------- +# MinMaxScaler + +# 创建MinMaxScaler对象 +scaler = MinMaxScaler() + +# 拟合并转换数据 +train_X = scaler.fit_transform(secure_dataset.train_X) + +train_praba = VerticalBooster._init_praba(secure_dataset.train_X.shape[0]) +train_weights = VerticalBooster._init_weight(secure_dataset.train_X.shape[1]) + +for i in range(2): + idx = VerticalBooster._get_sample_idx(i, train_X.shape[0], size=8) + x_, y_ = train_X[idx], secure_dataset.train_y[idx] + + g = BinaryLoss.dot_product(x_, train_weights) + h = 0.5 + BinaryLoss.inference(g) + # h = BinaryLoss.sigmoid(g) + d = h - y_ + deriv = np.matmul(x_.T, d) / x_.shape[0] + print(deriv) + + train_weights -= 0.1 * deriv.astype('float') + print(train_weights) + +g = BinaryLoss.dot_product(train_X, train_weights) +# train_praba = 0.5 + BinaryLoss.inference(g) +train_praba = BinaryLoss.sigmoid(g) +auc = Evaluation.fevaluation(secure_dataset.train_y, train_praba)['auc'] +print(auc) + + +# StandardScaler + +# 创建MinMaxScaler对象 +scaler = StandardScaler() + +# 拟合并转换数据 +train_X = scaler.fit_transform(secure_dataset.train_X) + +train_praba = VerticalBooster._init_praba(secure_dataset.train_X.shape[0]) +train_weights = VerticalBooster._init_weight(secure_dataset.train_X.shape[1]) + +for i in range(2): + idx = VerticalBooster._get_sample_idx(i, train_X.shape[0], size=8) + x_, y_ = train_X[idx], secure_dataset.train_y[idx] + + g = BinaryLoss.dot_product(x_, train_weights) + h = 0.5 + BinaryLoss.inference(g) + # h = BinaryLoss.sigmoid(g) + d = h - y_ + deriv = np.matmul(x_.T, d) / x_.shape[0] + print(deriv) + + train_weights -= 0.1 * deriv.astype('float') + print(train_weights) + +g = BinaryLoss.dot_product(train_X, train_weights) +# train_praba = 0.5 + BinaryLoss.inference(g) +train_praba = BinaryLoss.sigmoid(g) +auc = Evaluation.fevaluation(secure_dataset.train_y, train_praba)['auc'] +print(auc) diff --git a/python/ppc_model/secure_lr/test/test_secure_lr_performance_training.py b/python/ppc_model/secure_lr/test/test_secure_lr_performance_training.py new file mode 100644 index 00000000..5052289f --- /dev/null +++ b/python/ppc_model/secure_lr/test/test_secure_lr_performance_training.py @@ -0,0 +1,158 @@ +import unittest +import threading +import traceback + +from ppc_model.common.initializer import Initializer +from ppc_common.ppc_mock.mock_objects import MockLogger +from ppc_model.datasets.dataset import SecureDataset +from ppc_model.metrics.evaluation import Evaluation +from ppc_model.common.model_result import ResultFileHandling +from ppc_model.common.mock.mock_model_transport import MockModelRouterApi +from ppc_model.secure_lgbm.secure_lgbm_context import SecureLGBMContext +from ppc_model.secure_lgbm.vertical import VerticalLGBMActiveParty, VerticalLGBMPassiveParty + + +ACTIVE_PARTY = 'ACTIVE_PARTY' +PASSIVE_PARTY = 'PASSIVE_PARTY' + +data_size = 1000 +feature_dim = 20 + + +def mock_args(): + job_id = 'j-1111' + task_id = 't-1111' + + model_dict = { + 'objective': 'regression', + 'categorical_feature': [], + 'train_features': "", + 'epochs': 1, + 'batch_size': 8, + 'feature_rate': 0.8, + 'random_state': 2024 + } + + args_a = { + 'job_id': job_id, + 'task_id': task_id, + 'is_label_holder': True, + 'result_receiver_id_list': [ACTIVE_PARTY, PASSIVE_PARTY], + 'participant_id_list': [ACTIVE_PARTY, PASSIVE_PARTY], + 'model_predict_algorithm': None, + 'algorithm_type': 'Train', + 'algorithm_subtype': 'HeteroLR', + 'model_dict': model_dict + } + + args_b = { + 'job_id': job_id, + 'task_id': task_id, + 'is_label_holder': False, + 'result_receiver_id_list': [ACTIVE_PARTY, PASSIVE_PARTY], + 'participant_id_list': [ACTIVE_PARTY, PASSIVE_PARTY], + 'model_predict_algorithm': None, + 'algorithm_type': 'Train', + 'algorithm_subtype': 'HeteroLR', + 'model_dict': model_dict + } + + return args_a, args_b + + +class TestXgboostTraining(unittest.TestCase): + + def setUp(self): + participants = [PASSIVE_PARTY, ACTIVE_PARTY] + self._active_transport = MockModelRouterApi(participants) + self._passive_transport = MockModelRouterApi(participants) + + def test_fit(self): + args_a, args_b = mock_args() + + active_components = Initializer(log_config_path='', config_path='') + active_components.transport = self._active_transport + active_components.config_data = { + 'JOB_TEMP_DIR': '/tmp/active', 'AGENCY_ID': ACTIVE_PARTY} + active_components.mock_logger = MockLogger() + task_info_a = SecureLGBMContext(args_a['task_id'], args_a, active_components) + model_data = SecureDataset.simulate_dataset( + data_size, feature_dim, has_label=True) + secure_dataset_a = SecureDataset(task_info_a, model_data) + booster_a = VerticalLGBMActiveParty(task_info_a, secure_dataset_a) + print(secure_dataset_a.feature_name) + print(secure_dataset_a.train_idx.shape) + print(secure_dataset_a.train_X.shape) + print(secure_dataset_a.train_y.shape) + print(secure_dataset_a.test_idx.shape) + print(secure_dataset_a.test_X.shape) + print(secure_dataset_a.test_y.shape) + + passive_components = Initializer(log_config_path='', config_path='') + passive_components.transport = self._passive_transport + passive_components.config_data = { + 'JOB_TEMP_DIR': '/tmp/passive', 'AGENCY_ID': PASSIVE_PARTY} + passive_components.mock_logger = MockLogger() + task_info_b = SecureLGBMContext(args_b['task_id'], args_b, passive_components) + model_data = SecureDataset.simulate_dataset( + data_size, feature_dim, has_label=False) + secure_dataset_b = SecureDataset(task_info_b, model_data) + booster_b = VerticalLGBMPassiveParty(task_info_b, secure_dataset_b) + print(secure_dataset_b.feature_name) + print(secure_dataset_b.train_idx.shape) + print(secure_dataset_b.train_X.shape) + print(secure_dataset_b.test_idx.shape) + print(secure_dataset_b.test_X.shape) + + def active_worker(): + try: + booster_a.fit() + booster_a.save_model() + train_praba = booster_a.get_train_praba() + test_praba = booster_a.get_test_praba() + Evaluation(task_info_a, secure_dataset_a, + train_praba, test_praba) + ResultFileHandling(task_info_a) + booster_a.load_model() + booster_a.predict() + test_praba = booster_a.get_test_praba() + 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) + except Exception as e: + task_info_a.components.logger().info(traceback.format_exc()) + + def passive_worker(): + try: + booster_b.fit() + booster_b.save_model() + train_praba = booster_b.get_train_praba() + test_praba = booster_b.get_test_praba() + Evaluation(task_info_b, secure_dataset_b, + train_praba, test_praba) + ResultFileHandling(task_info_b) + booster_b.load_model() + booster_b.predict() + test_praba = booster_b.get_test_praba() + 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) + except Exception as e: + task_info_b.components.logger().info(traceback.format_exc()) + + thread_lgbm_active = threading.Thread(target=active_worker, args=()) + thread_lgbm_active.start() + + thread_lgbm_passive = threading.Thread(target=passive_worker, args=()) + thread_lgbm_passive.start() + + thread_lgbm_active.join() + thread_lgbm_passive.join() + + +if __name__ == '__main__': + unittest.main() diff --git a/python/ppc_model/secure_lr/test/test_secure_lr_training.py b/python/ppc_model/secure_lr/test/test_secure_lr_training.py new file mode 100644 index 00000000..6492f38f --- /dev/null +++ b/python/ppc_model/secure_lr/test/test_secure_lr_training.py @@ -0,0 +1,170 @@ +import unittest +import threading +import traceback +from sklearn.datasets import load_breast_cancer + +from ppc_model.common.initializer import Initializer +from ppc_common.ppc_mock.mock_objects import MockLogger +from ppc_model.datasets.dataset import SecureDataset +from ppc_model.metrics.evaluation import Evaluation +from ppc_model.common.mock.mock_model_transport import MockModelRouterApi +from ppc_model.common.model_result import ResultFileHandling +from ppc_model.secure_lr.secure_lr_context import SecureLRContext +from ppc_model.secure_lr.vertical import VerticalLRActiveParty, VerticalLRPassiveParty + + +ACTIVE_PARTY = 'ACTIVE_PARTY' +PASSIVE_PARTY = 'PASSIVE_PARTY' + + +def mock_args(): + job_id = 'j-1234' + task_id = 't-1234' + + model_dict = { + 'objective': 'regression', + 'categorical_feature': [], + 'train_features': "", + 'epochs': 1, + 'batch_size': 8, + 'feature_rate': 0.8, + 'random_state': 2024 + } + + args_a = { + 'job_id': job_id, + 'task_id': task_id, + 'is_label_holder': True, + 'result_receiver_id_list': [ACTIVE_PARTY, PASSIVE_PARTY], + 'participant_id_list': [ACTIVE_PARTY, PASSIVE_PARTY], + 'model_predict_algorithm': None, + 'algorithm_type': 'Train', + 'algorithm_subtype': 'HeteroLR', + 'model_dict': model_dict + } + + args_b = { + 'job_id': job_id, + 'task_id': task_id, + 'is_label_holder': False, + 'result_receiver_id_list': [ACTIVE_PARTY, PASSIVE_PARTY], + 'participant_id_list': [ACTIVE_PARTY, PASSIVE_PARTY], + 'model_predict_algorithm': None, + 'algorithm_type': 'Train', + 'algorithm_subtype': 'HeteroLR', + 'model_dict': model_dict + } + + return args_a, args_b + + +class TestXgboostTraining(unittest.TestCase): + + cancer = load_breast_cancer() + X = cancer.data + y = cancer.target + + # MinMaxScaler + from sklearn.preprocessing import MinMaxScaler + # 创建MinMaxScaler对象 + scaler = MinMaxScaler() + # 拟合并转换数据 + X = scaler.fit_transform(X) + + df = SecureDataset.assembling_dataset(X, y) + df_with_y, df_without_y = SecureDataset.hetero_split_dataset(df) + + def setUp(self): + participants = [PASSIVE_PARTY, ACTIVE_PARTY] + self._active_transport = MockModelRouterApi(participants) + self._passive_transport = MockModelRouterApi(participants) + + def test_fit(self): + args_a, args_b = mock_args() + plot_lock = threading.Lock() + + active_components = Initializer( + log_config_path='', config_path='', plot_lock=plot_lock) + active_components.transport = self._active_transport + active_components.config_data = { + 'JOB_TEMP_DIR': '/tmp/active', 'AGENCY_ID': ACTIVE_PARTY} + active_components.mock_logger = MockLogger() + task_info_a = SecureLRContext(args_a['task_id'], args_a, active_components) + + secure_dataset_a = SecureDataset(task_info_a, self.df_with_y) + booster_a = VerticalLRActiveParty(task_info_a, secure_dataset_a) + print(secure_dataset_a.feature_name) + print(secure_dataset_a.train_idx.shape) + print(secure_dataset_a.train_X.shape) + print(secure_dataset_a.train_y.shape) + print(secure_dataset_a.test_idx.shape) + print(secure_dataset_a.test_X.shape) + print(secure_dataset_a.test_y.shape) + + passive_components = Initializer( + log_config_path='', config_path='', plot_lock=plot_lock) + passive_components.transport = self._passive_transport + passive_components.config_data = { + 'JOB_TEMP_DIR': '/tmp/passive', 'AGENCY_ID': PASSIVE_PARTY} + passive_components.mock_logger = MockLogger() + task_info_b = SecureLRContext(args_b['task_id'], args_b, passive_components) + secure_dataset_b = SecureDataset(task_info_b, self.df_without_y) + booster_b = VerticalLRPassiveParty(task_info_b, secure_dataset_b) + print(secure_dataset_b.feature_name) + print(secure_dataset_b.train_idx.shape) + print(secure_dataset_b.train_X.shape) + print(secure_dataset_b.test_idx.shape) + print(secure_dataset_b.test_X.shape) + + def active_worker(): + try: + booster_a.fit() + booster_a.save_model() + train_praba = booster_a.get_train_praba() + test_praba = booster_a.get_test_praba() + Evaluation(task_info_a, secure_dataset_a, + train_praba, test_praba) + ResultFileHandling(task_info_a) + booster_a.load_model() + booster_a.predict() + test_praba = booster_a.get_test_praba() + 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) + except Exception as e: + task_info_a.components.logger().info(traceback.format_exc()) + + def passive_worker(): + try: + booster_b.fit() + booster_b.save_model() + train_praba = booster_b.get_train_praba() + test_praba = booster_b.get_test_praba() + Evaluation(task_info_b, secure_dataset_b, + train_praba, test_praba) + ResultFileHandling(task_info_b) + booster_b.load_model() + booster_b.predict() + test_praba = booster_b.get_test_praba() + 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) + except Exception as e: + task_info_b.components.logger().info(traceback.format_exc()) + + thread_lr_active = threading.Thread(target=active_worker, args=()) + thread_lr_active.start() + + thread_lr_passive = threading.Thread(target=passive_worker, args=()) + thread_lr_passive.start() + + thread_lr_active.join() + thread_lr_passive.join() + + +if __name__ == '__main__': + unittest.main() diff --git a/python/ppc_model/secure_lr/vertical/__init__.py b/python/ppc_model/secure_lr/vertical/__init__.py new file mode 100644 index 00000000..bf7ebebe --- /dev/null +++ b/python/ppc_model/secure_lr/vertical/__init__.py @@ -0,0 +1,4 @@ +from ppc_model.secure_lr.vertical.active_party import VerticalLRActiveParty +from ppc_model.secure_lr.vertical.passive_party import VerticalLRPassiveParty + +__all__ = ["VerticalLRActiveParty", "VerticalLRPassiveParty"] diff --git a/python/ppc_model/secure_lr/vertical/active_party.py b/python/ppc_model/secure_lr/vertical/active_party.py new file mode 100644 index 00000000..2040a359 --- /dev/null +++ b/python/ppc_model/secure_lr/vertical/active_party.py @@ -0,0 +1,175 @@ +import itertools +import time +import json + +import numpy as np +from pandas import DataFrame + +from ppc_common.deps_services.serialize_type import SerializeType +from ppc_common.ppc_ml.feature.feature_importance import FeatureImportanceStore +from ppc_common.ppc_ml.feature.feature_importance import FeatureImportanceType +from ppc_common.ppc_protos.generated.ppc_model_pb2 import BestSplitInfo, IterationRequest +from ppc_common.ppc_utils import utils +from ppc_model.datasets.data_reduction.feature_selection import FeatureSelection +from ppc_model.datasets.data_reduction.sampling import Sampling +from ppc_model.datasets.dataset import SecureDataset +from ppc_model.datasets.feature_binning.feature_binning import FeatureBinning +from ppc_model.metrics.evaluation import Evaluation +from ppc_model.metrics.loss import BinaryLoss +from ppc_model.secure_lr.secure_lr_context import SecureLRContext, LRMessage +from ppc_model.secure_lr.vertical.booster import VerticalBooster + + +class VerticalLRActiveParty(VerticalBooster): + + def __init__(self, ctx: SecureLRContext, dataset: SecureDataset) -> None: + super().__init__(ctx, dataset) + self.params = ctx.model_params + self._loss_func = BinaryLoss() + self._all_feature_name = [dataset.feature_name] + self._all_feature_num = len(dataset.feature_name) + self.log = ctx.components.logger() + self.storage_client = ctx.components.storage_client + self.log.info( + f'task {self.ctx.task_id}: print all params: {self.params.get_all_params()}') + + def fit( + self, + *args, + **kwargs, + ) -> None: + self.log.info( + f'task {self.ctx.task_id}: Starting the lr on the active party.') + self._init_active_data() + + max_iter = self._init_iter(self.dataset.train_X.shape[0], + self.params.epochs, self.params.batch_size) + self.log.info(f"task: {self.ctx.task_id}, max_iter: {max_iter}") + for _ in range(max_iter): + self._iter_id += 1 + start_time = time.time() + self.log.info( + f'task {self.ctx.task_id}: Starting iter-{self._iter_id} in active party.') + + # 初始化 + idx, feature_select = self._init_each_iter() + self.log.info( + f'task {self.ctx.task_id}: feature select: {len(feature_select)}, {feature_select}.') + + # 构建 + self._build_iter(feature_select, idx) + + # 预测 + self._train_praba = self._predict_tree( + self.dataset.train_X, LRMessage.PREDICT_LEAF_MASK.value) + # print('train_praba', set(self._train_praba)) + + # 评估 + if not self.params.silent and self.dataset.train_y is not None: + auc = Evaluation.fevaluation( + self.dataset.train_y, self._train_praba)['auc'] + self.log.info( + f'task {self.ctx.task_id}: iter-{self._iter_id}, auc: {auc}.') + self.log.info(f'task {self.ctx.task_id}: Ending iter-{self._iter_id}, ' + f'time_costs: {time.time() - start_time}s.') + + # 预测验证集 + self._test_praba = self._predict_tree( + self.dataset.test_X, LRMessage.TEST_LEAF_MASK.value) + if not self.params.silent and self.dataset.test_y is not None: + auc = Evaluation.fevaluation( + self.dataset.test_y, self._test_praba)['auc'] + self.log.info( + f'task {self.ctx.task_id}: iter-{self._iter_id}, test auc: {auc}.') + + self._end_active_data() + + def transform(self, transform_data: DataFrame) -> DataFrame: + ... + + def predict(self, dataset: SecureDataset = None) -> np.ndarray: + start_time = time.time() + if dataset is None: + dataset = self.dataset + + test_praba = self._predict_tree( + dataset.test_X, LRMessage.VALID_LEAF_MASK.value) + self._test_praba = test_praba + + if dataset.test_y is not None: + auc = Evaluation.fevaluation(dataset.test_y, test_praba)['auc'] + self.log.info(f'task {self.ctx.task_id}: predict test auc: {auc}.') + self.log.info( + f'task {self.ctx.task_id}: Ending predict, time_costs: {time.time() - start_time}s.') + + self._end_active_data(is_train=False) + + def _init_active_data(self): + + # 初始化预测值和权重 + self._train_praba = self._init_praba(self.dataset.train_X.shape[0]) + self._train_weights = self._init_weight(self.dataset.train_X.shape[1]) + self._test_weights = self._init_weight(self.dataset.test_X.shape[1]) + self._iter_id = 0 + + # 初始化所有参与方的特征 + for i in range(1, len(self.ctx.participant_id_list)): + feature_name_bytes = self._receive_byte_data( + self.ctx, LRMessage.FEATURE_NAME.value, i) + self._all_feature_name.append( + [s.decode('utf-8') for s in feature_name_bytes.split(b' ') if s]) + self._all_feature_num += len([s.decode('utf-8') + for s in feature_name_bytes.split(b' ') if s]) + for i in range(1, len(self.ctx.participant_id_list)): + self._send_byte_data(self.ctx, LRMessage.FEATURE_NAME.value, + json.dumps(self._all_feature_name).encode('utf-8'), i) + + self.log.info(f'task {self.ctx.task_id}: total feature number:{self._all_feature_num}, ' + f'total feature name: {self._all_feature_name}.') + self.params.categorical_idx = self._get_categorical_idx( + list(itertools.chain(*self._all_feature_name)), self.params.categorical_feature) + self.params.my_categorical_idx = self._get_categorical_idx( + self.dataset.feature_name, self.params.categorical_feature) + + def _build_iter(self, feature_select, idx): + + x_, y_ = self.dataset.train_X[idx], self.dataset.train_y[idx] + + g = self._loss_func.dot_product(x_, self._train_weights) + h = 0.5 + self._loss_func.inference(g) + d = h - y_ + + self._send_d_instance_list(d) + public_key_list, d_other_list, partner_index_list = self._receive_d_instance_list() + deriv = self._calculate_deriv(x_, d, partner_index_list, d_other_list) + + self._train_weights -= self.params.learning_rate * \ + deriv.astype('float') + self._train_weights[~np.isin( + np.arange(len(self._train_weights)), feature_select)] = 0 + + def _predict_tree(self, X, key_type): + train_g = self._loss_func.dot_product(X, self._train_weights) + for i in range(1, len(self.ctx.participant_id_list)): + train_g_other = np.frombuffer( + self._receive_byte_data(self.ctx, key_type, i), dtype='float') + train_g += train_g_other + return self._loss_func.sigmoid(train_g) + + def _end_active_data(self, is_train=True): + if is_train: + 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: + self._send_byte_data(self.ctx, f'{LRMessage.PREDICT_PRABA.value}_train', + self._train_praba.astype('float').tobytes(), partner_index) + + 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: + self._send_byte_data(self.ctx, f'{LRMessage.PREDICT_PRABA.value}_test', + self._test_praba.astype('float').tobytes(), partner_index) + + else: + 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: + self._send_byte_data(self.ctx, f'{LRMessage.PREDICT_PRABA.value}_predict', + self._test_praba.astype('float').tobytes(), partner_index) diff --git a/python/ppc_model/secure_lr/vertical/booster.py b/python/ppc_model/secure_lr/vertical/booster.py new file mode 100644 index 00000000..3d4b286e --- /dev/null +++ b/python/ppc_model/secure_lr/vertical/booster.py @@ -0,0 +1,336 @@ +import os +import time +import random +import json +import itertools +import numpy as np + +from ppc_common.ppc_protos.generated.ppc_model_pb2 import BestSplitInfo +from ppc_common.ppc_utils.utils import AlgorithmType +from ppc_model.model_crypto.crypto_aes import encrypt_data, decrypt_data, cipher_to_base64, base64_to_cipher +from ppc_model.interface.model_base import VerticalModel +from ppc_model.datasets.data_reduction.feature_selection import FeatureSelection +from ppc_model.datasets.dataset import SecureDataset +from ppc_model.common.protocol import PheMessage +from ppc_model.common.model_result import ResultFileHandling +from ppc_model.datasets.feature_binning.feature_binning import FeatureBinning +from ppc_model.secure_lr.secure_lr_context import SecureLRContext, LRMessage +from ppc_model.secure_model_base.secure_model_booster import SecureModelBooster + +# 抽离sgb的公共部分 + + +class VerticalBooster(SecureModelBooster): + def __init__(self, ctx: SecureLRContext, dataset: SecureDataset) -> None: + super().__init__(ctx) + self.dataset = dataset + + self._iter_id = None + + self._train_weights = None + self._train_praba = None + self._test_weights = None + self._test_praba = None + + random.seed(ctx.model_params.random_state) + np.random.seed(ctx.model_params.random_state) + + def _build_tree(self, *args, **kwargs): + + raise NotImplementedError + + def _predict_tree(self, *args, **kwargs): + + raise NotImplementedError + + @staticmethod + def _init_praba(n): + return np.full(n, 0.5) + + @staticmethod + def _init_weight(n): + return np.zeros(n, dtype=float) + + @staticmethod + def _init_iter(n, epochs, batch_size): + return round(n*epochs/batch_size) + + @staticmethod + def _get_sample_idx(i, n, size): + start_idx = (i * size) % n + end_idx = start_idx + size + if end_idx <= n: + idx = list(range(start_idx, end_idx)) + else: + head_idx = end_idx - n + idx = list(range(start_idx, n)) + list(range(head_idx)) + return idx + + @staticmethod + def _get_categorical_idx(feature_name, categorical_feature=[]): + categorical_idx = [] + if len(categorical_feature) > 0: + for i in categorical_feature: + if i in feature_name: + categorical_idx.append(feature_name.index(i)) + return categorical_idx + + def _init_each_iter(self): + + idx = self._get_sample_idx(self._iter_id-1, self.dataset.train_X.shape[0], + size=self.params.batch_size) + feature_select = FeatureSelection.feature_selecting( + list(self.dataset.feature_name), + self.params.train_feature, self.params.feature_rate) + + return idx, feature_select + + def _send_d_instance_list(self, d): + + d_list = self.rounding_d(d) + my_agency_id = self.ctx.components.config_data['AGENCY_ID'] + + start_time = time.time() + self.logger.info(f'task {self.ctx.task_id}: Starting iter-{self._iter_id} ' + f'encrypt d in {my_agency_id} party.') + enc_dlist = self.ctx.phe.encrypt_batch_parallel( + (d_list).astype('object')) + self.logger.info(f'task {self.ctx.task_id}: Finished iter-{self._iter_id} ' + f'encrypt d time_costs: {time.time() - start_time}.') + + for partner_index in range(len(self.ctx.participant_id_list)): + if self.ctx.participant_id_list[partner_index] != my_agency_id: + self._send_enc_data(self.ctx, f'{LRMessage.ENC_D_LIST.value}_{self._iter_id}', + enc_dlist, partner_index) + + def _receive_d_instance_list(self): + + my_agency_id = self.ctx.components.config_data['AGENCY_ID'] + + public_key_list = [] + d_other_list = [] + partner_index_list = [] + for partner_index in range(len(self.ctx.participant_id_list)): + if self.ctx.participant_id_list[partner_index] != my_agency_id: + public_key, enc_d = self._receive_enc_data( + self.ctx, f'{LRMessage.ENC_D_LIST.value}_{self._iter_id}', partner_index) + public_key_list.append(public_key) + d_other_list.append(np.array(enc_d)) + partner_index_list.append(partner_index) + + return public_key_list, d_other_list, partner_index_list + + def _calculate_deriv(self, x_, d, partner_index_list, d_other_list): + + x = self.rounding_d(x_) + deriv = np.matmul(x_.T, d) / x_.shape[0] + for i, partner_index in enumerate(partner_index_list): + # 计算明文*密文 matmul + # deriv_other_i = np.matmul(x.T, d_other_list[i]) + deriv_other_i = self.enc_matmul(x.T, d_other_list[i]) + + # 发送密文,接受密文并解密 + self._send_enc_data(self.ctx, f'{LRMessage.ENC_D_HIST.value}_{self._iter_id}', + deriv_other_i, partner_index) + _, enc_deriv_i = self._receive_enc_data( + self.ctx, f'{LRMessage.ENC_D_HIST.value}_{self._iter_id}', partner_index) + deriv_i_rec = np.array( + self.ctx.phe.decrypt_batch(enc_deriv_i), dtype='object') + deriv_i = self.recover_d( + self.ctx, deriv_i_rec, is_square=True) / x_.shape[0] + + # 发送明文,接受明文并计算 + self._send_byte_data(self.ctx, f'{LRMessage.D_MATMUL.value}_{self._iter_id}', + deriv_i.astype('float').tobytes(), partner_index) + deriv_x_i = np.frombuffer(self._receive_byte_data( + self.ctx, f'{LRMessage.D_MATMUL.value}_{self._iter_id}', partner_index), dtype=np.float) + self.logger.info( + f'{self.ctx.components.config_data["AGENCY_ID"]}, deriv size: {deriv.size}.') + self.logger.info( + f'{self.ctx.components.config_data["AGENCY_ID"]}, deriv_x_i size: {deriv_x_i.size}.') + deriv += deriv_x_i + self.logger.info( + f'{self.ctx.components.config_data["AGENCY_ID"]}, merged deriv size: {deriv.size}.') + return deriv + + def _calculate_deriv1(self, x_, d, partner_index_list, d_other_list): + + x = self.rounding_d(x_) + deriv = np.matmul(x_.T, d) / x_.shape[0] + for i, partner_index in enumerate(partner_index_list): + # TODO:重载方法,目前支持np.array(enc_dlist).sum()的方式,不支持明文*密文 + # deriv_other_i = np.matmul(x.T, d_other_list[i]) + deriv_other_i = self.enc_matmul(x.T, d_other_list[i]) + self._send_enc_data(self.ctx, f'{LRMessage.ENC_D_HIST.value}_{self._iter_id}', + deriv_other_i, partner_index) + _, enc_deriv_i = self._receive_enc_data( + self.ctx, f'{LRMessage.ENC_D_HIST.value}_{self._iter_id}', partner_index) + deriv_i = np.array(self.ctx.phe.decrypt_batch( + enc_deriv_i), dtype='object') + deriv += (self.recover_d(self.ctx, deriv_i, + is_square=True) / x_.shape[0]) + return deriv + + def _send_enc_data(self, ctx, key_type, enc_data, partner_index, matrix_data=False): + start_time = time.time() + partner_id = ctx.participant_id_list[partner_index] + + if matrix_data: + payload = PheMessage.packing_2dim_data( + ctx.codec, ctx.phe.public_key, enc_data) + else: + payload = PheMessage.packing_data( + ctx.codec, ctx.phe.public_key, enc_data) + self.ctx.model_router.push( + task_id=ctx.task_id, task_type=key_type, dst_agency=partner_id, payload=payload) + self.logger.info( + f"task {ctx.task_id}: Sending {key_type} to {partner_id} finished, " + f"data_length: {len(enc_data)}, time_costs: {time.time() - start_time}s") + + def _receive_enc_data(self, ctx, key_type, partner_index, matrix_data=False): + start_time = time.time() + partner_id = ctx.participant_id_list[partner_index] + byte_data = self.ctx.model_router.pop( + task_id=ctx.task_id, task_type=key_type, from_inst=partner_id) + if matrix_data: + public_key, enc_data = PheMessage.unpacking_2dim_data( + ctx.codec, byte_data) + else: + public_key, enc_data = PheMessage.unpacking_data( + ctx.codec, byte_data) + + self.logger.info( + f"task {ctx.task_id}: Received {key_type} from {partner_id} finished, " + f"data_size: {len(byte_data) / 1024}KB, time_costs: {time.time() - start_time}s") + return public_key, enc_data + + def _send_byte_data(self, ctx, key_type, byte_data, partner_index): + start_time = time.time() + partner_id = ctx.participant_id_list[partner_index] + self.ctx.model_router.push( + task_id=ctx.task_id, task_type=key_type, dst_agency=partner_id, payload=byte_data) + self.logger.info( + f"task {ctx.task_id}: Sending {key_type} to {partner_id} finished, " + f"data_size: {len(byte_data) / 1024}KB, time_costs: {time.time() - start_time}s") + + def _receive_byte_data(self, ctx, key_type, partner_index): + start_time = time.time() + partner_id = ctx.participant_id_list[partner_index] + + byte_data = self.ctx.model_router.pop( + task_id=ctx.task_id, task_type=key_type, from_inst=partner_id) + + self.logger.info( + f"task {ctx.task_id}: Received {key_type} from {partner_id} finished, " + f"data_size: {len(byte_data) / 1024}KB, time_costs: {time.time() - start_time}s") + return byte_data + + def save_model(self): + super().save_model("lr_model") + + def save_model_hook(self): + if not os.path.exists(self.ctx.model_data_file): + serial_weight = list(self._train_weights) + with open(self.ctx.model_data_file, 'w') as f: + json.dump(serial_weight, f) + ResultFileHandling._upload_file(self.ctx.components.storage_client, + self.ctx.model_data_file, + self.ctx.remote_model_data_file, + self.ctx.user) + self.logger.info( + f"task {self.ctx.task_id}: Saved serial_weight to {self.ctx.model_data_file} finished.") + + def merge_model_file(self, lr_model): + + # 加密文件 + model_text = {} + with open(self.ctx.model_data_file, 'rb') as f: + model_data = f.read() + model_data_enc = encrypt_data(self.ctx.key, model_data) + + my_agency_id = self.ctx.components.config_data['AGENCY_ID'] + model_text[my_agency_id] = cipher_to_base64(model_data_enc) + + # 发送&接受文件 + for partner_index in range(0, len(self.ctx.participant_id_list)): + if self.ctx.participant_id_list[partner_index] != my_agency_id: + self._send_byte_data( + self.ctx, f'{LRMessage.MODEL_DATA.value}_model_data', + model_data_enc, partner_index) + for partner_index in range(0, len(self.ctx.participant_id_list)): + if self.ctx.participant_id_list[partner_index] != my_agency_id: + model_data_enc = self._receive_byte_data( + self.ctx, f'{LRMessage.MODEL_DATA.value}_model_data', partner_index) + model_text[self.ctx.participant_id_list[partner_index] + ] = cipher_to_base64(model_data_enc) + lr_model['model_text'] = model_text + + # 上传密文模型 + with open(self.ctx.model_enc_file, 'w') as f: + json.dump(lr_model, f) + ResultFileHandling._upload_file(self.ctx.components.storage_client, + self.ctx.model_enc_file, + self.ctx.remote_model_enc_file, + self.ctx.user) + self.logger.info( + f"task {self.ctx.task_id}: Saved enc model to {self.ctx.model_enc_file} finished.") + + def split_model_file(self): + # 传入模型 + my_agency_id = self.ctx.components.config_data['AGENCY_ID'] + model_text = self.ctx.model_predict_algorithm['model_text'] + model_data_enc = base64_to_cipher(model_text[my_agency_id]) + + # 解密文件 + model_data = decrypt_data(self.ctx.key, model_data_enc) + with open(self.ctx.model_data_file, 'wb') as f: + f.write(model_data) + + def load_model(self, file_path=None): + if file_path is not None: + self.ctx.model_data_file = os.path.join( + file_path, self.ctx.MODEL_DATA_FILE) + + try: + ResultFileHandling._download_file(self.ctx.components.storage_client, + self.ctx.model_data_file, self.ctx.remote_model_data_file) + except: + self.split_model_file() + + with open(self.ctx.model_data_file, 'r') as f: + serial_weight = json.load(f) + self._train_weights = np.array(serial_weight) + self.logger.info( + f"task {self.ctx.task_id}: Load serial_weight from {self.ctx.model_data_file} finished.") + + def get_weights(self): + return self._train_weights + + def get_train_praba(self): + return self._train_praba + + def get_test_praba(self): + return self._test_praba + + @staticmethod + def enc_matmul(arr, enc): + result = [] + for i in range(len(arr)): + # arr[i] * enc # 需要将密文放在前面 + result.append((enc * arr[i]).sum()) + return np.array(result) + + @staticmethod + def rounding_d(d_list: np.ndarray, expand=1000): + return (d_list * expand).astype('int') + + @staticmethod + def recover_d(ctx, d_sum_list: np.ndarray, is_square=False, expand=1000): + + d_sum_list[d_sum_list > 2 ** + (ctx.phe.key_length-1)] -= 2**(ctx.phe.key_length) + + if is_square: + return (d_sum_list / expand / expand).astype('float') + else: + return (d_sum_list / expand).astype('float') diff --git a/python/ppc_model/secure_lr/vertical/passive_party.py b/python/ppc_model/secure_lr/vertical/passive_party.py new file mode 100644 index 00000000..372c3d6a --- /dev/null +++ b/python/ppc_model/secure_lr/vertical/passive_party.py @@ -0,0 +1,130 @@ +import itertools +import multiprocessing +import time +import json +import numpy as np +from pandas import DataFrame + +from ppc_common.ppc_utils import utils +from ppc_common.ppc_protos.generated.ppc_model_pb2 import BestSplitInfo, IterationRequest +from ppc_model.datasets.data_reduction.feature_selection import FeatureSelection +from ppc_model.datasets.dataset import SecureDataset +from ppc_model.datasets.feature_binning.feature_binning import FeatureBinning +from ppc_model.metrics.loss import BinaryLoss +from ppc_model.secure_lr.secure_lr_context import SecureLRContext, LRMessage +from ppc_model.secure_lr.vertical.booster import VerticalBooster + + +class VerticalLRPassiveParty(VerticalBooster): + + def __init__(self, ctx: SecureLRContext, dataset: SecureDataset) -> None: + super().__init__(ctx, dataset) + self.params = ctx.model_params + self._all_feature_name = [] + self._loss_func = BinaryLoss() + self.log = ctx.components.logger() + self.log.info( + f'task {self.ctx.task_id}: print all params: {self.params.get_all_params()}') + + def fit( + self, + *args, + **kwargs, + ) -> None: + self.log.info( + f'task {self.ctx.task_id}: Starting the lr on the passive party.') + self._init_passive_data() + + max_iter = self._init_iter(self.dataset.train_X.shape[0], + self.params.epochs, self.params.batch_size) + for _ in range(max_iter): + self._iter_id += 1 + start_time = time.time() + self.log.info( + f'task {self.ctx.task_id}: Starting iter-{self._iter_id} in passive party.') + + # 初始化 + idx, feature_select = self._init_each_iter() + self.log.info( + f'task {self.ctx.task_id}: feature select: {len(feature_select)}, {feature_select}.') + + # 构建 + self._build_iter(feature_select, idx) + + # 预测 + self._predict_tree(self.dataset.train_X, LRMessage.PREDICT_LEAF_MASK.value) + self.log.info(f'task {self.ctx.task_id}: Ending iter-{self._iter_id}, ' + f'time_costs: {time.time() - start_time}s.') + + # 预测验证集 + self._predict_tree(self.dataset.test_X, LRMessage.TEST_LEAF_MASK.value) + + self._end_passive_data() + + def transform(self, transform_data: DataFrame) -> DataFrame: + ... + + def predict(self, dataset: SecureDataset = None) -> np.ndarray: + start_time = time.time() + if dataset is None: + dataset = self.dataset + + self._predict_tree(dataset.test_X, LRMessage.VALID_LEAF_MASK.value) + self.log.info( + f'task {self.ctx.task_id}: Ending predict, time_costs: {time.time() - start_time}s.') + + self._end_passive_data(is_train=False) + + def _init_passive_data(self): + + # 初始化预测值和权重 + self._train_praba = self._init_praba(self.dataset.train_X.shape[0]) + self._train_weights = self._init_weight(self.dataset.train_X.shape[1]) + self._test_weights = self._init_weight(self.dataset.test_X.shape[1]) + self._iter_id = 0 + + # 初始化参与方特征 + self._send_byte_data(self.ctx, LRMessage.FEATURE_NAME.value, + b''.join(s.encode('utf-8') + b' ' for s in self.dataset.feature_name), 0) + self.params.my_categorical_idx = self._get_categorical_idx( + self.dataset.feature_name, self.params.categorical_feature) + feature_name_bytes = self._receive_byte_data( + self.ctx, LRMessage.FEATURE_NAME.value, 0) + self._all_feature_name = json.loads(feature_name_bytes.decode('utf-8')) + + def _build_iter(self, feature_select, idx): + + x_ = self.dataset.train_X[idx] + + g = self._loss_func.dot_product(x_, self._train_weights) + h = self._loss_func.inference(g) + d = h + + self._send_d_instance_list(d) + public_key_list, d_other_list, partner_index_list = self._receive_d_instance_list() + deriv = self._calculate_deriv(x_, d, partner_index_list, d_other_list) + + self._train_weights -= self.params.learning_rate * deriv.astype('float') + self._train_weights[~np.isin(np.arange(len(self._train_weights)), feature_select)] = 0 + + def _predict_tree(self, X, key_type): + train_g = self._loss_func.dot_product(X, self._train_weights) + self._send_byte_data(self.ctx, f'{key_type}', + train_g.astype('float').tobytes(), 0) + + def _end_passive_data(self, is_train=True): + + if self.ctx.components.config_data['AGENCY_ID'] in self.ctx.result_receiver_id_list: + if is_train: + self._train_praba = np.frombuffer( + self._receive_byte_data( + self.ctx, f'{LRMessage.PREDICT_PRABA.value}_train', 0), dtype=np.float) + + self._test_praba = np.frombuffer( + self._receive_byte_data( + self.ctx, f'{LRMessage.PREDICT_PRABA.value}_test', 0), dtype=np.float) + + else: + self._test_praba = np.frombuffer( + self._receive_byte_data( + self.ctx, f'{LRMessage.PREDICT_PRABA.value}_predict', 0), dtype=np.float) diff --git a/python/ppc_model/secure_model_base/__init__.py b/python/ppc_model/secure_model_base/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/python/ppc_model/secure_model_base/secure_model_booster.py b/python/ppc_model/secure_model_base/secure_model_booster.py new file mode 100644 index 00000000..fa47d786 --- /dev/null +++ b/python/ppc_model/secure_model_base/secure_model_booster.py @@ -0,0 +1,36 @@ +# -*- coding: utf-8 -*- +import os +import json +from ppc_model.interface.model_base import VerticalModel +from ppc_model.common.model_result import ResultFileHandling +from abc import abstractmethod + + +class SecureModelBooster(VerticalModel): + def __init__(self, ctx) -> None: + super().__init__(ctx) + self.logger = self.ctx.components.logger() + + def save_model(self, model_type=None): + self.save_model_hook() + model = {} + model['model_type'] = model_type + model['label_provider'] = self.ctx.participant_id_list[0] + model['label_column'] = 'y' + model['participant_agency_list'] = [] + for partner_index in range(0, len(self.ctx.participant_id_list)): + agency_info = { + 'agency': self.ctx.participant_id_list[partner_index]} + agency_info['fields'] = self._all_feature_name[partner_index] + model['participant_agency_list'].append(agency_info) + + model['model_dict'] = self.ctx.model_params.get_all_params() + self.merge_model_file(model) + + @abstractmethod + def merge_model_file(self, lr_model): + pass + + @abstractmethod + def save_model_hook(self): + pass diff --git a/python/ppc_model/secure_model_base/secure_model_context.py b/python/ppc_model/secure_model_base/secure_model_context.py new file mode 100644 index 00000000..a4a8d5ef --- /dev/null +++ b/python/ppc_model/secure_model_base/secure_model_context.py @@ -0,0 +1,183 @@ +# -*- coding: utf-8 -*- +from abc import abstractmethod +from typing import Any, Dict +import json +import os +from ppc_model.common.context import Context +from ppc_model.common.initializer import Initializer +from ppc_model.common.protocol import TaskRole +from ppc_common.ppc_utils import common_func +from ppc_common.ppc_utils.utils import AlgorithmType +from ppc_model.common.model_setting import ModelSetting +from ppc_model.common.base_context import BaseContext + +from sklearn.base import BaseEstimator + + +class SecureModel(BaseEstimator): + + def __init__( + self, + **kwargs): + self.train_feature = [] + self.categorical_feature = None + self.random_state = None + self._other_params: Dict[str, Any] = {} + self.set_params(**kwargs) + + def get_params(self, deep: bool = True) -> Dict[str, Any]: + """Get parameters for this estimator. + + Parameters + ---------- + deep : bool, optional (default=True) + If True, will return the parameters for this estimator and + contained subobjects that are estimators. + + Returns + ------- + params : dict + Parameter names mapped to their values. + """ + params = super().get_params(deep=deep) + params.update(self._other_params) + return params + + def set_model_setting(self, model_setting: ModelSetting): + # 获取对象的所有属性名 + attrs = dir(model_setting) + # 过滤掉以_或者__开头的属性(这些通常是特殊方法或内部属性) + attrs = [attr for attr in attrs if not attr.startswith('_')] + + params = {} + for attr in attrs: + try: + setattr(self, attr, getattr(model_setting, attr)) + except Exception as e: + pass + return self + + def set_params(self, **params: Any): + """Set the parameters of this estimator. + + Parameters + ---------- + **params + Parameter names with their new values. + + Returns + ------- + self : object + Returns self. + """ + for key, value in params.items(): + setattr(self, key, value) + if hasattr(self, f"_{key}"): + setattr(self, f"_{key}", value) + self._other_params[key] = value + return self + + def get_all_params(self): + """返回SecureLRParams所有参数""" + # 获取对象的所有属性名 + attrs = dir(self) + # 过滤掉以_或者__开头的属性(这些通常是特殊方法或内部属性) + attrs = [attr for attr in attrs if not attr.startswith('_')] + + params = {} + for attr in attrs: + try: + # 使用getattr来获取属性的值 + value = getattr(self, attr) + # 检查value是否可调用(例如,方法或函数),如果是,则不打印其值 + if not callable(value): + params[attr] = value + except Exception as e: + pass + return params + + +class SecureModelContext(Context): + def __init__(self, + task_id, + args, + components: Initializer): + + if args['is_label_holder']: + role = TaskRole.ACTIVE_PARTY + else: + role = TaskRole.PASSIVE_PARTY + + super().__init__(job_id=args['job_id'], + task_id=task_id, + components=components, + role=role, + user=args['user']) + self.is_label_holder = args['is_label_holder'] + self.result_receiver_id_list = args['result_receiver_id_list'] + self.participant_id_list = args['participant_id_list'] + + model_predict_algorithm_str = common_func.get_config_value( + "model_predict_algorithm", None, args, False) + self.model_predict_algorithm = None + if model_predict_algorithm_str is not None: + self.model_predict_algorithm = json.loads( + model_predict_algorithm_str) + self.algorithm_type = args['algorithm_type'] + self.predict = False + if self.algorithm_type == AlgorithmType.Predict.name: + self.predict = True + # check for the predict task + if self.predict and self.model_predict_algorithm is None: + raise f"Not set model_predict_algorithm for the job: {self.task_id}" + + if 'dataset_id' in args and args['dataset_id'] is not None: + self.dataset_file_path = os.path.join( + self.workspace, args['dataset_id']) + else: + self.dataset_file_path = None + # the remote dataset_file_path + if 'dataset_path' in args: + self.remote_dataset_path = args['dataset_path'] + if self.remote_dataset_path is None: + raise f"Must define the dataset_path!" + # the remote psi_path + if 'psi_result_path' in args: + self.remote_psi_path = args['psi_result_path'] + if self.remote_psi_path is None: + raise f"Must define the psi_result_path" + self.model_params = self.create_model_param() + self.reset_model_params(ModelSetting(args['model_dict'])) + # prepare the dataset and psi file + BaseContext.load_file(storage_client=self.components.storage_client, + remote_path=self.remote_dataset_path, + local_path=self.dataset_file_path, + logger=self.components.logger()) + if self.model_params.use_psi: + BaseContext.load_file(storage_client=self.components.storage_client, + remote_path=self.remote_psi_path, + local_path=self.psi_result_path, + logger=self.components.logger()) + self.sync_file_list = {} + if self.algorithm_type == AlgorithmType.Train.name: + self.set_sync_file() + + @abstractmethod + def set_sync_file(self): + pass + + @abstractmethod + def create_model_param(self): + pass + + def reset_model_params(self, model_setting: ModelSetting): + """设置lr参数""" + self.model_params.set_model_setting(model_setting) + if model_setting.train_features is not None and len(model_setting.train_features) > 0: + self.model_params.train_feature = model_setting.train_features.split( + ',') + if model_setting.categorical is not None and len(model_setting.categorical) > 0: + self.model_params.categorical_feature = model_setting.categorical.split( + ',') + if model_setting.seed is not None: + self.model_params.random_state = model_setting.seed diff --git a/python/ppc_model/task/__init__.py b/python/ppc_model/task/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/python/ppc_model/task/task_manager.py b/python/ppc_model/task/task_manager.py new file mode 100644 index 00000000..100a3199 --- /dev/null +++ b/python/ppc_model/task/task_manager.py @@ -0,0 +1,280 @@ +import datetime +import json +import threading +import time +from typing import Callable, Union + +from readerwriterlock import rwlock + +from ppc_common.ppc_async_executor.async_thread_executor import AsyncThreadExecutor +from ppc_common.ppc_async_executor.thread_event_manager import ThreadEventManager +from ppc_common.deps_services.sql_storage_api import SQLStorageAPI +from ppc_model.common.protocol import ModelTask, TaskStatus, LOG_START_FLAG_FORMATTER, LOG_END_FLAG_FORMATTER +from ppc_model.db.job_worker_record import JobWorkerRecord +from ppc_model.log.log_retriever import LogRetriever + + +class TaskResult: + def __init__(self, job_id, task_id, user): + self.task_status = TaskStatus.RUNNING.value + self.start_time = datetime.datetime.now() + self.job_id = job_id + self.task_id = task_id + self.user = user + self.diagnosis_msg = "" + self.exec_result = None + + def get_timecost(self): + return (datetime.datetime.now() - self.start_time).total_seconds() + + def finalize(self): + # generate the exec_result + exec_result_dict = {} + exec_result_dict.update({"timecost": self.get_timecost()}) + exec_result_dict.update({"diagnosis_msg": self.diagnosis_msg}) + exec_result_dict.update({"user": self.user}) + self.exec_result = json.dumps(exec_result_dict) + + def __repr__(self): + return f"job_id: {self.job_id}, task_id: {self.task_id}, " \ + f"task_status: {self.task_status}, start_time: {self.start_time}" + + +class TaskPersistent: + def __init__(self, logger, sql_storage: SQLStorageAPI): + self.logger = logger + self.sql_storage = sql_storage + + def query_tasks(self, job_id) -> []: + task_recorder_list = self.sql_storage.query(JobWorkerRecord, + JobWorkerRecord.job_id == job_id) + tasks = [] + if task_recorder_list is None or task_recorder_list.count() == 0: + return tasks + self.logger.info( + f"query_tasks, job_id: {job_id}, count: {task_recorder_list.count()}") + for task in task_recorder_list: + tasks.append(task) + return tasks + + def query_task(self, worker_id) -> JobWorkerRecord: + task = self.sql_storage.query(JobWorkerRecord, + JobWorkerRecord.worker_id == worker_id) + if task is None or task.count() == 0: + return None + return task.first() + + def job_finished(self, job_id): + task_recorders = self.query_tasks(job_id) + if task_recorders is None: + return True + for task in task_recorders: + if task.status == TaskStatus.RUNNING.value or task.status == TaskStatus.PENDING.value: + return False + return True + + def on_task_finished(self, task_result: TaskResult): + """ + :param task_result: the task result + :return: + """ + # query the task + worker_recorder = self.query_task(task_result.task_id) + if worker_recorder is None: + self.logger.warn( + f"TaskPersistent error, the task {task_result.task_id} not found! task_result: {task_result}") + return + # update the task result + worker_recorder.status = task_result.task_status + worker_recorder.exec_result = task_result.exec_result + self.sql_storage.merge(worker_recorder) + + +class TaskManager: + def __init__(self, logger, + task_persistent: TaskPersistent, + log_retriever: LogRetriever, + thread_event_manager: ThreadEventManager, + task_timeout_h: Union[int, float]): + self.logger = logger + self.task_persistent = task_persistent + self.log_retriever = log_retriever + self._thread_event_manager = thread_event_manager + self._task_timeout_s = task_timeout_h * 3600 + self._rw_lock = rwlock.RWLockWrite() + self._tasks: dict[str, TaskResult] = {} + self._handlers = {} + self._task_clear_handler = [] + self._async_executor = AsyncThreadExecutor( + event_manager=self._thread_event_manager, logger=logger) + self._cleanup_thread = threading.Thread(target=self._loop_cleanup) + self._cleanup_thread.daemon = True + self._cleanup_thread.start() + + def register_task_handler(self, task_type: ModelTask, task_handler: Callable): + """ + 注册任务的执行入口 + param task_type: 任务类型 + param task_handler: 任务执行入口 + """ + self._handlers[task_type.value] = task_handler + + # handler called when task finished + def register_task_clear_handler(self, handler: Callable[[str], None]): + self._task_clear_handler.append(handler) + + def run_task(self, task_id: str, task_type: ModelTask, args=()): + """ + 发起任务 + param task_id: 任务ID + param task_type: 任务类型 + param args: 各任务参数 + """ + job_id = args[0]['job_id'] + task_recorder = self.task_persistent.query_task(task_id) + if task_recorder is not None and task_recorder.status == TaskStatus.RUNNING.value: + self.logger.info( + f"Task already exists and Running, task_id: {task_id}") + return + with self._rw_lock.gen_wlock(): + if task_id in self._tasks: + self.logger.info( + f"Task already exists, task_id: {task_id}, status: {self._tasks[task_id].task_id}") + return + self._tasks[task_id] = TaskResult( + job_id=args[0]['job_id'], task_id=task_id, user=args[0]['user']) + self.logger.info(LOG_START_FLAG_FORMATTER.format(job_id=job_id)) + self.logger.info(f"Run task, job_id: {job_id}, task_id: {task_id}") + self._async_executor.execute( + args[0]['job_id'], task_id, self._handlers[task_type.value], self._on_task_finish, args) + + def kill_task(self, job_id: str): + """ + 终止任务 + """ + tasks = self.task_persistent.query_tasks(job_id) + user = None + for task in tasks: + user = self.kill_one_task(task.worker_id) + self.logger.info(f"kill_task, job {job_id} killed, upload the log") + if user is None: + return + self.logger.info(LOG_END_FLAG_FORMATTER.format( + job_id=job_id)) + # upload the log + self.log_retriever.upload_log(job_id, user) + + def kill_one_task(self, task_id: str): + task_result = None + with self._rw_lock.gen_rlock(): + if task_id not in self._tasks.keys() or self._tasks[task_id].task_status != TaskStatus.RUNNING.value: + return None + task_result = self._tasks[task_id] + self.logger.info(f"Kill task, task_id: {task_id}") + self._async_executor.kill(task_id) + user = task_result.user + # persistent the status to killed + with self._rw_lock.gen_wlock(): + task_result.task_status = TaskStatus.KILLED.value + self.task_persistent.on_task_finished(task_result) + self._tasks.pop(task_id) + self.logger.info( + f"Kill task success, task_id: {task_id}, user: {user}") + return user + + def task_finished(self, task_id: str) -> bool: + (status, _, _) = self.status(task_id) + if status == TaskStatus.RUNNING.value or status == TaskStatus.PENDING.value: + return False + return True + + def status(self, task_id: str) -> [str, float, str]: + """ + 返回: 任务状态, 通讯量(MB), 执行耗时(s) + """ + # hit the cache: first query the memory + with self._rw_lock.gen_rlock(): + if task_id in self._tasks.keys(): + task_result = self._tasks.get(task_id) + return task_result.task_status, 0, task_result.exec_result + # miss the cache: query from the db + result = self.task_persistent.query_task(task_id) + if result is None: + return TaskStatus.NotFound.value, 0.0, None + return result.status, 0, result.exec_result + + def _on_task_finish(self, task_id: str, is_succeeded: bool, error_msg: str = None): + try: + task_result = None + with self._rw_lock.gen_wlock(): + if task_id not in self._tasks.keys(): + self.logger.warn( + f"_on_task_finish: the task {task_id} not Found! maybe killed!") + return + task_result = self._tasks[task_id] + + # update the task result + if is_succeeded: + task_result.task_status = TaskStatus.SUCCESS.value + self.logger.info(f"Task {task_id} completed, job_id: {task_result.job_id}, " + f"time_costs: {task_result.get_timecost()}s") + else: + task_result.task_status = TaskStatus.FAILURE.value + task_result.diagnosis_msg = error_msg + self.logger.warn(f"Task {task_id} failed, job_id: {task_result.job_id}, " + f"time_costs: {self._tasks[task_id].get_timecost()}s, error: {error_msg}") + + self.logger.info(LOG_END_FLAG_FORMATTER.format( + job_id=task_result.job_id)) + # finalize the task result + task_result.finalize() + self.task_persistent.on_task_finished(task_result) + + with self._rw_lock.gen_wlock(): + # erase from the queue + self._tasks.pop(task_id) + + # record and upload the log if all task finished + if self.task_persistent.job_finished(task_result.job_id): + self.logger.info( + f"_on_task_finish: all sub tasks finished, upload the log, task_info: {task_result}") + self.log_retriever.upload_log( + task_result.job_id, task_result.user) + finally: + for handler in self._task_clear_handler: + handler(task_id) + + def _loop_cleanup(self): + while True: + self._terminate_timeout_tasks() + self._cleanup_finished_tasks() + time.sleep(5) + + def _terminate_timeout_tasks(self): + tasks_to_kill = [] + with self._rw_lock.gen_rlock(): + for task_id, value in self._tasks.items(): + alive_time = (datetime.datetime.now() - + value.start_time).total_seconds() + if alive_time >= self._task_timeout_s and value.task_status == TaskStatus.RUNNING.value: + tasks_to_kill.append(task_id) + + for task_id in tasks_to_kill: + self.logger.warn(f"Task is timeout, task_id: {task_id}") + self.kill_one_task(task_id) + + def _cleanup_finished_tasks(self): + tasks_to_cleanup = [] + with self._rw_lock.gen_rlock(): + for task_id, value in self._tasks.items(): + alive_time = (datetime.datetime.now() - + value.start_time).total_seconds() + if alive_time >= self._task_timeout_s + 3600: + tasks_to_cleanup.append((task_id, value.job_id)) + with self._rw_lock.gen_wlock(): + for task_id, job_id in tasks_to_cleanup: + if task_id in self._tasks: + del self._tasks[task_id] + self._thread_event_manager.remove_event(task_id) + self.logger.info( + f"Cleanup task cache, task_id: {task_id}, job_id: {job_id}") diff --git a/python/ppc_model/task/test/__init__.py b/python/ppc_model/task/test/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/python/ppc_model/task/test/task_manager_unittest.py b/python/ppc_model/task/test/task_manager_unittest.py new file mode 100644 index 00000000..33d38e1d --- /dev/null +++ b/python/ppc_model/task/test/task_manager_unittest.py @@ -0,0 +1,123 @@ +import time +import unittest + +from ppc_common.ppc_async_executor.thread_event_manager import ThreadEventManager +from ppc_common.ppc_mock.mock_objects import MockLogger +from ppc_model.common.protocol import ModelTask +from ppc_model.task.task_manager import TaskManager + +thread_event_manager = ThreadEventManager() + +# TODO: complement here + + +def my_send_task(args): + print("start my_send_task") + time.sleep(1) + byte_array = bytearray(31 * 1024 * 1024) + bytes_data = bytes(byte_array) + time.sleep(1) + + +def my_receive_task(args): + print("finish my_receive_task") + + +def my_failed_task(args): + print("start my_failed_task") + raise Exception('For Test') + + +def my_long_task(args): + print("start my_long_task") + print("finish my_receive_task") + + +def my_timeout_task(args): + print("start my_timeout_task") + print("finish my_timeout_task") + + +class TestTaskManager(unittest.TestCase): + + def setUp(self): + self._task_manager = TaskManager( + logger=MockLogger(), + thread_event_manager=thread_event_manager, + task_timeout_h=0.0005 + ) + self._task_manager.register_task_handler( + ModelTask.FEATURE_ENGINEERING, my_send_task) + self._task_manager.register_task_handler( + ModelTask.PREPROCESSING, my_receive_task) + self._task_manager.register_task_handler( + ModelTask.XGB_TRAINING, my_failed_task) + self._task_manager.register_task_handler( + ModelTask.XGB_PREDICTING, my_long_task) + + def test_run_task(self): + args = { + 'receiver': 'TEST_AGENCY', + 'sender': 'TEST_AGENCY', + 'task_id': '0x12345678', + 'job_id': '0x123456789', + 'key': 'TEST_MESSAGE', + } + self._task_manager.run_task( + "my_send_task", ModelTask.FEATURE_ENGINEERING, (args,)) + self.assertEqual(self._task_manager.status( + "my_send_task")[0], 'RUNNING') + self._task_manager.run_task( + "my_receive_task", ModelTask.PREPROCESSING, (args,)) + self.assertEqual(self._task_manager.status( + "my_receive_task")[0], 'RUNNING') + self._task_manager.run_task( + "my_failed_task", ModelTask.XGB_TRAINING, (args,)) + self.assertEqual(self._task_manager.status( + "my_failed_task")[0], 'RUNNING') + time.sleep(3) + self.assertEqual(self._task_manager.status( + "my_send_task")[0], 'COMPLETED') + self.assertEqual(self._task_manager.status( + "my_receive_task")[0], 'COMPLETED') + self.assertEqual(self._task_manager.status( + "my_failed_task")[0], 'FAILED') + time.sleep(1) + + def test_kill_task(self): + args = { + 'receiver': 'TEST_AGENCY', + 'sender': 'TEST_AGENCY', + 'task_id': 'my_long_task', + 'job_id': '0x123456789', + 'key': 'TEST_MESSAGE', + } + self._task_manager.run_task( + "my_long_task", ModelTask.XGB_PREDICTING, (args,)) + self.assertEqual(self._task_manager.status( + "my_long_task")[0], 'RUNNING') + self._task_manager.kill_task("0x123456789") + time.sleep(1) + self.assertEqual(self._task_manager.status( + "my_long_task")[0], 'FAILED') + + self._task_manager.register_task_handler( + ModelTask.XGB_PREDICTING, my_timeout_task) + args = { + 'receiver': 'TEST_AGENCY', + 'sender': 'TEST_AGENCY', + 'task_id': 'my_timeout_task', + 'job_id': '0x123456789', + 'key': 'TEST_MESSAGE', + } + self._task_manager.run_task( + "my_timeout_task", ModelTask.XGB_PREDICTING, (args,)) + self.assertEqual(self._task_manager.status( + "my_timeout_task")[0], 'RUNNING') + time.sleep(6) + self.assertEqual(self._task_manager.status( + "my_timeout_task")[0], 'FAILED') + + +if __name__ == '__main__': + unittest.main() diff --git a/python/ppc_model/tools/start.sh b/python/ppc_model/tools/start.sh new file mode 100644 index 00000000..ca412013 --- /dev/null +++ b/python/ppc_model/tools/start.sh @@ -0,0 +1,42 @@ +#!/bin/bash +SHELL_FOLDER=$(cd $(dirname $0);pwd) +LOG_ERROR() { + content=${1} + echo -e "\033[31m[ERROR] ${content}\033[0m" +} + +LOG_INFO() { + content=${1} + echo -e "\033[32m[INFO] ${content}\033[0m" +} +binary_path=${SHELL_FOLDER}/ppc_model_app.py +cd ${SHELL_FOLDER} +log_dir=logs +if [ ! -f ${log_dir} ];then + mkdir -p logs +fi +node=$(basename ${SHELL_FOLDER}) +node_pid=$(ps aux|grep ${binary_path}|grep -v grep|awk '{print $2}') + +if [ ! -z ${node_pid} ];then + echo " ${node} is running, pid is $node_pid." + exit 0 +else + # -u means Force the stdout and stderr streams to be unbuffered + nohup python -u ${binary_path} > start.out 2>&1 & + sleep 1.5 +fi +try_times=4 +i=0 +while [ $i -lt ${try_times} ] +do + node_pid=$(ps aux|grep ${binary_path}|grep -v grep|awk '{print $2}') + success_flag=$(tail -n20 start.out | grep successfully) + if [[ ! -z ${node_pid} && ! -z "${success_flag}" ]];then + echo -e "\033[32m ${node} start successfully pid=${node_pid}\033[0m" + exit 0 + fi + sleep 0.5 + ((i=i+1)) +done +echo -e "\033[31m Exceed waiting time. Please try again to start ${node} \033[0m" diff --git a/python/ppc_model/tools/stop.sh b/python/ppc_model/tools/stop.sh new file mode 100644 index 00000000..ae35743c --- /dev/null +++ b/python/ppc_model/tools/stop.sh @@ -0,0 +1,46 @@ +#!/bin/bash +SHELL_FOLDER=$(cd $(dirname $0);pwd) + +LOG_ERROR() { + content=${1} + echo -e "\033[31m[ERROR] ${content}\033[0m" +} + +LOG_INFO() { + content=${1} + echo -e "\033[32m[INFO] ${content}\033[0m" +} + +binary_path=${SHELL_FOLDER}/ppc_model_app.py +node=$(basename ${SHELL_FOLDER}) +node_pid=$(ps aux|grep ${binary_path}|grep -v grep|awk '{print $2}') +try_times=10 +i=0 +if [ -z ${node_pid} ];then + echo " ${node} isn't running." + exit 0 +fi + +#Stop monitor here +dirs=($(ls -l ${SHELL_FOLDER} | awk '/^d/ {print $NF}')) +for dir in ${dirs[*]} +do + if [[ -f "${SHELL_FOLDER}/${dir}/node.mtail" && -f "${SHELL_FOLDER}/${dir}/stop_mtail_monitor.sh" ]];then + echo "try to start ${dir}" + bash ${SHELL_FOLDER}/${dir}/stop_mtail_monitor.sh & + fi +done + +[ ! -z ${node_pid} ] && kill ${node_pid} > /dev/null +while [ $i -lt ${try_times} ] +do + sleep 1 + node_pid=$(ps aux|grep ${binary_path}|grep -v grep|awk '{print $2}') + if [ -z ${node_pid} ];then + echo -e "\033[32m stop ${node} success.\033[0m" + exit 0 + fi + ((i=i+1)) +done +echo " Exceed maximum number of retries. Please try again to stop ${node}" +exit 1 diff --git a/python/requirements.txt b/python/requirements.txt new file mode 100644 index 00000000..7b753c1b --- /dev/null +++ b/python/requirements.txt @@ -0,0 +1,59 @@ +cx-Oracle==8.3.0 +click>=8.0 +pytest +cheroot==8.5.2 +flask_restx==1.3.0 +configobj~=5.0.6 +Flask_SQLAlchemy==3.1.0 +cryptography~=41.0.5 +pandas +hypothesis~=5.48.0 +parsimonious~=0.8.1 +SQLAlchemy==2.0.16 +argcomplete~=1.12.2 +cytoolz~=0.10.1 +six~=1.15.0 +attrdict~=2.0.1 +Flask~=2.2.5 +pymitter~=0.3.0 +requests~=2.31.0 +requests_toolbelt==0.9.1 +lru_dict==1.1.6 +promise~=2.3 +#protobuf==3.19.0 +# protobuf>=4.21.6,<5.0dev +protobuf>=5.27.1 +pycryptodome==3.9.9 +pyjwt +pyyaml +mysqlclient==2.1.0 +waitress==3.0.0 +sqlparse~=0.4.1 +toolz~=0.11.1 +tenacity==7.0.0 +coincurve~=13.0.0 +google~=3.0.0 +paste~=3.5.0 +func_timeout==4.3.0 +cheroot==8.5.2 +gmssl~=3.2.1 +readerwriterlock~=1.0.4 +jsoncomment~=0.2.3 +matplotlib~=3.2.2 +seaborn~=0.10.1 +sqlvalidator==0.0.17 +requests-toolbelt==0.9.1 +hdfs +scikit-learn~=0.24.2 +gmpy2 +networkx +pydot +snowland-smx +numpy==1.23.1 +graphviz +xlrd~=1.0.0 +MarkupSafe>=2.1.1 +urllib3==1.26.18 +phe +chardet +requests_kerberos>=0.15.0 diff --git a/python/tools/fake_id_data.py b/python/tools/fake_id_data.py new file mode 100644 index 00000000..d78cc9ac --- /dev/null +++ b/python/tools/fake_id_data.py @@ -0,0 +1,187 @@ +# -*- coding: utf-8 -*- +import argparse +from enum import Enum +import datetime +import random +import string +import sys + + +class IDType(Enum): + CreditID = "credit_id", + + @classmethod + def has_value(cls, value): + return value in cls._value2member_map_ + + +class WithTimeType(Enum): + Empty = "none", + Random = "random", + ALL = "all", + + @classmethod + def has_value(cls, value): + return value in cls._value2member_map_ + + @classmethod + def value_of(cls, label): + if label in cls.Empty.value: + return cls.Empty + elif label in cls.Random.value: + return cls.Random + elif label in cls.ALL.value: + return cls.ALL + else: + raise NotImplementedError + + +def parse_args(): + parser = argparse.ArgumentParser(prog=sys.argv[0]) + parser.add_argument("-r", '--dataset_file', + help='the file to store the faked data', required=True) + parser.add_argument("-p", '--peer_dataset_size', + help='the peer dataset size', default=0, required=False) + parser.add_argument("-j", '--join_id_count', + help='the joined id count', default=0, required=False) + parser.add_argument("-c", '--id_count', + help='the id count', required=False) + parser.add_argument("-f", '--id_file', + help='the id file', required=False) + + parser.add_argument("-t", '--with_time', + help=f'generate id information with time({WithTimeType.Empty.value} means not with time, random means only generate a random time for one id, all means generate (end_date-start_date) times for one id)', default=WithTimeType.Empty.value[0], required=False) + + parser.add_argument("-s", '--start_date', + help='the start time(only useful when --with_time is setted)', required=False) + parser.add_argument("-e", '--end_date', + help='the end time(only useful when --with_time is setted)', required=False) + parser.add_argument("-I", '--id_type', + help=f'the id type, currently only support {IDType.CreditID.value}', + default=IDType.CreditID.value, required=False) + args = parser.parse_args() + return args + + +def generate_credit_id(): + code = random.choice(string.digits + string.ascii_uppercase) + code += random.choice(string.digits + string.ascii_uppercase) + code += ''.join(random.choices(string.digits, k=6)) + code += ''.join(random.choices(string.digits, k=9)) + code += random.choice(string.digits + string.ascii_uppercase) + return code + + +def generate_id(id_type): + if IDType.has_value(id_type) is False: + error_msg = f"Unsupported id type: {id_type}" + raise Exception(error_msg) + id_type = IDType(id_type) + if id_type == IDType.CreditID: + return generate_credit_id() + + +def generate_random_time(start_date, end_date): + start_time = datetime.time(8, 0, 0) + random_date = start_date + \ + (end_date - start_date) * random.random() + random_time = datetime.datetime.combine( + random_date, start_time) + datetime.timedelta(seconds=random.randint(0, 86399)) + return random_time.strftime("%Y-%m-%d") + + +def write_line_data(fp, with_time, id_data, start_date, end_date): + if with_time is WithTimeType.Random: + line_data = id_data + "," + \ + generate_random_time(start_date, end_date) + "\n" + fp.write(line_data) + elif with_time is WithTimeType.ALL: + for i in range((end_date - start_date).days + 1): + day = start_date + datetime.timedelta(days=i) + line_data = id_data + "," + day.strftime("%Y-%m-%d") + "\n" + fp.write(line_data) + else: + fp.write(id_data + "\n") + + +def generate_header(dataset_file, with_time): + with open(dataset_file, "a+") as fp: + # with the header + fp.write("id") + if with_time is not WithTimeType.Empty: + fp.write(",time") + fp.write("\n") + + +def generate_dataset(id_count, id_type, dataset_file, with_time, start_date, end_date, joined_fp, joined_count, id_file): + with open(dataset_file, "a+") as f: + # generate with id_count + if id_file is None: + epoch = int(id_count) * 0.1 + for i in range(int(id_count)): + if i % epoch == 0: + print( + f"#### generate {epoch}/{id_count} records for: {dataset_file}") + id_data = generate_id(id_type) + write_line_data(f, with_time, id_data, start_date, end_date) + if joined_fp is not None and joined_count > 0: + joined_count -= 1 + write_line_data(joined_fp, with_time, + id_data, start_date, end_date) + # generate with id_file + else: + with open(id_file, "r") as id_fp: + # skip the header + id_data = id_fp.readline().strip() + if id_data is not None: + id_data = id_fp.readline().strip() + while id_data is not None and id_data != '': + write_line_data(f, with_time, id_data, + start_date, end_date) + if joined_fp is not None and joined_count > 0: + joined_count -= 1 + write_line_data(joined_fp, with_time, + id_data, start_date, end_date) + id_data = id_fp.readline().strip() + + print(f"##### fake_data for {dataset_file} success") + + +def check_args(args): + if args.id_count is None and args.id_file is None: + raise Exception("Must set id_count or id_file") + + +def fake_data(args): + check_args(args) + end_date = datetime.datetime.now() + if args.end_date is not None: + end_date = datetime.datetime.strptime(args.end_date, "%Y-%m-%d") + start_date = datetime.datetime.now() + datetime.timedelta(days=-2 * 365) + if args.start_date is not None: + start_date = datetime.datetime.strptime(args.start_date, "%Y-%m-%d") + with_time = WithTimeType.Empty + if args.with_time is not None: + with_time = WithTimeType.value_of(args.with_time) + + joined_dataset_path = args.dataset_file + ".peer" + joined_dataset_fp = None + if int(args.join_id_count) > 0: + generate_header(joined_dataset_path, with_time) + if int(args.peer_dataset_size) > int(args.join_id_count): + expected_peer_data_size = int( + args.peer_dataset_size) - int(args.join_id_count) + generate_dataset(expected_peer_data_size, args.id_type, + joined_dataset_path, with_time, start_date, end_date, None, 0, None) + joined_dataset_fp = open(joined_dataset_path, "a+") + + generate_header(args.dataset_file, with_time) + generate_dataset(args.id_count, args.id_type, + args.dataset_file, with_time, start_date, end_date, joined_dataset_fp, int(args.join_id_count), args.id_file) + if joined_dataset_fp is not None: + joined_dataset_fp.close() + + +if __name__ == "__main__": + args = parse_args() + fake_data(args) diff --git a/python/tools/fake_ml_train_data.py b/python/tools/fake_ml_train_data.py new file mode 100644 index 00000000..c0b145e0 --- /dev/null +++ b/python/tools/fake_ml_train_data.py @@ -0,0 +1,170 @@ +# -*- coding: utf-8 -*- +import numpy as np +import sys +import os +import argparse +from enum import Enum +import random + + +class DataType(Enum): + TRAIN = "train", + PREDICT = "predict", + ALL = "all" + + @classmethod + def has_value(cls, value): + return value in cls._value2member_map_ + + @classmethod + def value_of(cls, label): + if label in cls.TRAIN.value: + return cls.TRAIN + elif label in cls.PREDICT.value: + return cls.PREDICT + elif label in cls.ALL.value: + return cls.ALL + else: + raise NotImplementedError + + +def parse_args(): + parser = argparse.ArgumentParser(prog=sys.argv[0]) + parser.add_argument("-f", '--feature_size', + help='the feature size', required=True) + parser.add_argument("-s", '--sample_capacity', + help='the faked data size(in MB, default 1MB)', default=1, required=False) + parser.add_argument("-d", '--id_file', + help='the id file', required=False) + parser.add_argument("-S", '--sample_file', + help='the file to store the faked data', required=True) + parser.add_argument("-i", "--start_id", + help="the start id", required=False, default=0) + parser.add_argument("-I", "--ignore_header", + help="ignore the file header", required=False, default=False) + parser.add_argument("-m", "--with_missing_value", help="with missing value", + required=False, default=False) + parser.add_argument("-p", "--missing_percent", required=False, + default=10, help="the missing value percentage") + parser.add_argument("-t", "--data_type", required=False, + default=DataType.ALL.value, help="the dataType, now support 'all'/'predict'/'train'") + parser.add_argument("-F", "--feature_prefix", required=False, + default="x", help="the feature prefix") + args = parser.parse_args() + return args + + +def generate_id_list(id_fp, granularity, id): + if id_fp is None: + return (granularity, np.array(range(id, id + granularity), dtype=str)) + lines = id_fp.readlines(granularity * 1024) + data = [line.split(",")[0].strip() for line in lines] + return (len(data), data) + + +class FileInfo: + def __init__(self, fp, fmt_setting): + self.fp = fp + self.fmt_setting = fmt_setting + + +def generate_header_for_given_data(file_name, ignore_header, data_type, feature_size, feature_prefix): + if ignore_header: + return + # write the header + f = open(file_name, "a") + # write the header + fmt_setting = "%s" + if data_type == DataType.PREDICT: + f.write("id") + if data_type == DataType.TRAIN: + f.write("id,y") + fmt_setting = "%s,%s" + for j in range(feature_size): + fmt_setting = fmt_setting + ",%s" + f.write(f",{feature_prefix}{str(j)}") + f.write("\n") + return FileInfo(f, fmt_setting) + + +def generate_header(args, data_type, feature_size): + train_file_info = None + predict_file_info = None + if data_type == DataType.PREDICT: + predict_file_info = generate_header_for_given_data( + args.sample_file, args.ignore_header, data_type, feature_size, args.feature_prefix) + if data_type == DataType.TRAIN: + train_file_info = generate_header_for_given_data( + args.sample_file, args.ignore_header, data_type, feature_size, args.feature_prefix) + if data_type == DataType.ALL: + train_file_info = generate_header_for_given_data( + args.sample_file, args.ignore_header, DataType.TRAIN, feature_size, args.feature_prefix) + predict_file_info = generate_header_for_given_data( + args.sample_file + ".predict", args.ignore_header, DataType.PREDICT, feature_size, args.feature_prefix) + return (train_file_info, predict_file_info) + + +def fake_data(args): + data_type = DataType.value_of(args.data_type) + sample_capacity_bytes = None + if args.sample_capacity is not None: + sample_capacity_bytes = int(args.sample_capacity) * 1024 * 1024 + feature_size = int(args.feature_size) + granularity = 100 + id = 0 + (train_file_info, predict_file_info) = generate_header( + args, data_type, feature_size) + if args.start_id is not None: + id = int(args.start_id) + id_fp = None + if args.id_file is not None: + id_fp = open(args.id_file, "r") + # skip the header + id_fp.readline() + # write the header + while True: + (rows, id_list) = generate_id_list(id_fp, granularity, id) + if rows == 0: + break + id += rows + feature_sample = np.random.standard_normal( + (rows, feature_size)) + if args.with_missing_value: + for i in range(int(args.missing_percent)): + selected_line = random.randrange(rows) + selected_feature = random.randrange(feature_size) + feature_sample[selected_line, selected_feature] = np.nan + if train_file_info is not None: + train_sample = feature_sample.astype("str") + y_list = np.random.randint(0, 2, rows) + # insert the y_list + train_sample = np.insert(train_sample, 0, values=y_list, axis=1) + # insert the id + train_sample = np.insert(train_sample.astype( + "str"), 0, values=id_list, axis=1) + np.set_printoptions(suppress=True, threshold=np.inf) + np.savetxt(train_file_info.fp, train_sample.astype( + "str"), fmt=train_file_info.fmt_setting) + if predict_file_info is not None: + predict_sample = feature_sample.astype("str") + # insert the id + predict_sample = np.insert(predict_sample.astype( + "str"), 0, values=id_list, axis=1) + np.set_printoptions(suppress=True, threshold=np.inf) + np.savetxt(predict_file_info.fp, predict_sample.astype( + "str"), fmt=predict_file_info.fmt_setting) + # check the file size + if args.id_file is None: + file_size = os.stat(args.sample_file).st_size + if file_size >= sample_capacity_bytes: + print(f"#### final id: {id}") + break + if train_file_info is not None: + train_file_info.fp.close() + if predict_file_info is not None: + predict_file_info.fp.close() + + +if __name__ == "__main__": + args = parse_args() + fake_data(args) diff --git a/python/tools/install.sh b/python/tools/install.sh new file mode 100644 index 00000000..143a5093 --- /dev/null +++ b/python/tools/install.sh @@ -0,0 +1,2 @@ +apt-get install pkg-config python3-dev default-libmysqlclient-dev build-essential +apt-get install graphviz \ No newline at end of file diff --git a/python/tools/requirements.txt b/python/tools/requirements.txt new file mode 100644 index 00000000..24ce15ab --- /dev/null +++ b/python/tools/requirements.txt @@ -0,0 +1 @@ +numpy diff --git a/python/wedpr_ml_toolkit/CHANGELOG.md b/python/wedpr_ml_toolkit/CHANGELOG.md new file mode 100644 index 00000000..e69de29b diff --git a/python/wedpr_ml_toolkit/MANIFEST.in b/python/wedpr_ml_toolkit/MANIFEST.in new file mode 100644 index 00000000..3b258244 --- /dev/null +++ b/python/wedpr_ml_toolkit/MANIFEST.in @@ -0,0 +1,2 @@ +include CHANGELOG.md +include *requirements.txt diff --git a/python/wedpr_ml_toolkit/conf/config.properties b/python/wedpr_ml_toolkit/conf/config.properties new file mode 100644 index 00000000..3fdec9b3 --- /dev/null +++ b/python/wedpr_ml_toolkit/conf/config.properties @@ -0,0 +1,13 @@ +access_key_id= +access_key_secret= +remote_entrypoints=http://127.0.0.1:16000,http://127.0.0.1:16001 + +agency_name=WeBank +workspace_path=/user/wedpr/webank/ +user=test_user + +storage_endpoint=http://127.0.0.1:50070 +enable_krb5_auth=False +hdfs_auth_principal=root@NODE.DC1.CONSUL +hdfs_auth_password=root +hdfs_hostname_override=wedpr-0001 \ No newline at end of file diff --git a/python/wedpr_ml_toolkit/jupyter-demo/test_dastaset.py b/python/wedpr_ml_toolkit/jupyter-demo/test_dastaset.py new file mode 100644 index 00000000..d8e8b918 --- /dev/null +++ b/python/wedpr_ml_toolkit/jupyter-demo/test_dastaset.py @@ -0,0 +1,81 @@ +#!/usr/bin/env python +# coding: utf-8 + +# In[4]: + + +import sys +import numpy as np +import pandas as pd +from wedpr_ml_toolkit.config.wedpr_ml_config import WeDPRMlConfigBuilder +from wedpr_ml_toolkit.wedpr_ml_toolkit import WeDPRMlToolkit +from wedpr_ml_toolkit.context.dataset_context import DatasetContext +from wedpr_ml_toolkit.transport.wedpr_remote_dataset_client import DatasetMeta + + +# In[5]: + + +# 读取配置文件 +wedpr_config = WeDPRMlConfigBuilder.build_from_properties_file('config.properties') +wedpr_ml_toolkit = WeDPRMlToolkit(wedpr_config) + + +# In[8]: + + +# 注册 dataset,支持两种方式: pd.Dataframe, hdfs_path +# 1. pd.Dataframe +df = pd.DataFrame({ + 'id': np.arange(0, 100), # id列,顺序整数 + 'y': np.random.randint(0, 2, size=100), + # x1到x10列,随机数 + **{f't{i}': np.random.rand(100) for i in range(1, 11)} +}) + +dataset1_meta = DatasetMeta(file_path = "d-01", user_config = wedpr_config.user_config) + +dataset1 = DatasetContext(storage_entrypoint=wedpr_ml_toolkit.get_storage_entry_point(), + storage_workspace=wedpr_config.user_config.get_workspace_path(), + dataset_meta = dataset1_meta) +print(f"* dataset1: {dataset1.dataset_meta}") +dataset1.save_values(df) +print(f"* updated dataset1: {dataset1}") + +(values, cols, shape) = dataset1.load_values() +print(f"* load values result: {cols}, {shape}, {values}") + + +# In[11]: + + +# 2. hdfs_path +dataset2 = DatasetContext(storage_entrypoint=wedpr_ml_toolkit.get_storage_entry_point(), + dataset_client=wedpr_ml_toolkit.dataset_client, + storage_workspace=wedpr_config.user_config.get_workspace_path(), + dataset_id = "d-9866227816474629") +print(f"* dataset2 meta: {dataset2}") + +# load values +(values, cols, shape) = dataset2.load_values(header=0) +print(f"* dataset2 detail, cols: {cols}, shape: {shape}, values: {values}") + + +# 支持更新dataset的values数据 +df2 = pd.DataFrame({ + 'id': np.arange(0, 100), # id列,顺序整数 + **{f'w{i}': np.random.rand(100) for i in range(1, 11)} # x1到x10列,随机数 + }) +dataset2.save_values(values=df2) + +print(f"*** updated dataset2 meta: {dataset2}") + +(values, cols, shape) = dataset2.load_values(header=0) +print(f"*** updated dataset2 detail, cols: {cols}, shape: {shape}, values: {values}") + + +# In[ ]: + + + + diff --git a/python/wedpr_ml_toolkit/jupyter-demo/test_ml.py b/python/wedpr_ml_toolkit/jupyter-demo/test_ml.py new file mode 100644 index 00000000..e60dc733 --- /dev/null +++ b/python/wedpr_ml_toolkit/jupyter-demo/test_ml.py @@ -0,0 +1,288 @@ +#!/usr/bin/env python +# coding: utf-8 + +# In[1]: + + +import matplotlib.pyplot as plt +from sklearn.metrics import roc_curve, roc_auc_score, precision_recall_curve, accuracy_score, f1_score, precision_score, recall_score +import sys +import numpy as np +import pandas as pd +from wedpr_ml_toolkit.config.wedpr_ml_config import WeDPRMlConfigBuilder +from wedpr_ml_toolkit.wedpr_ml_toolkit import WeDPRMlToolkit +from wedpr_ml_toolkit.context.dataset_context import DatasetContext +from wedpr_ml_toolkit.context.data_context import DataContext +from wedpr_ml_toolkit.context.job_context import JobType +from wedpr_ml_toolkit.context.model_setting import ModelSetting +from wedpr_ml_toolkit.context.result.model_result_context import PredictResultContext +from wedpr_ml_toolkit.context.result.model_result_context import TrainResultContext +from wedpr_ml_toolkit.context.result.model_result_context import PreprocessingResultContext + + +# In[2]: + + +# 读取配置文件 +wedpr_config = WeDPRMlConfigBuilder.build_from_properties_file( + 'config.properties') +wedpr_ml_toolkit = WeDPRMlToolkit(wedpr_config) + + +# In[3]: + + +# dataset1 +dataset1 = DatasetContext(storage_entrypoint=wedpr_ml_toolkit.get_storage_entry_point(), + dataset_client=wedpr_ml_toolkit.dataset_client, + dataset_id='d-9743660607744005', + is_label_holder=True) +print(f"* load dataset1: {dataset1}") +(values, cols, shapes) = dataset1.load_values() +print(f"* dataset1 detail: {cols}, {shapes}") +print(f"* dataset1 value: {values}") + + +# In[4]: + + +# dataset2 +dataset2 = DatasetContext(storage_entrypoint=wedpr_ml_toolkit.get_storage_entry_point(), + dataset_client=wedpr_ml_toolkit.dataset_client, + dataset_id="d-9743674298214405") +print(f"* dataset2: {dataset2}") + +# 构建 dataset context +dataset = DataContext(dataset1, dataset2) +print(dataset.datasets) + +# init the job context +project_id = "9737304249804806" + +# 构造xgb任务配置 +model_setting = ModelSetting() +model_setting.use_psi = True +xgb_job_context = wedpr_ml_toolkit.build_job_context( + job_type=JobType.XGB_TRAINING, + project_id=project_id, + dataset=dataset, + model_setting=model_setting) +print(f"* build xgb job context: {xgb_job_context}") + + +# In[5]: + + +# 执行xgb任务 +xgb_job_id = xgb_job_context.submit() +print(xgb_job_id) + + +# In[7]: + + +# 获取xgb任务结果 +print(xgb_job_id) +# xgb_job_id = "9868279583877126" +xgb_result_detail = xgb_job_context.fetch_job_result(xgb_job_id, True) +# load the result context +xgb_result_context = wedpr_ml_toolkit.build_result_context(job_context=xgb_job_context, + job_result_detail=xgb_result_detail) +print(f"* xgb job result ctx: {xgb_result_context}") + +xgb_test_dataset = xgb_result_context.test_result_dataset +print( + f"* xgb_test_dataset: {xgb_test_dataset}, file_path: {xgb_test_dataset.dataset_meta.file_path}") + +(data, cols, shapes) = xgb_test_dataset.load_values() +print( + f"* test dataset detail, columns: {cols}, shape: {shapes}, value: {data}") + + +# In[8]: + + +# evaluation result +result_context: TrainResultContext = xgb_result_context +evaluation_result_dataset = result_context.evaluation_dataset +(eval_data, cols, shape) = evaluation_result_dataset.load_values(header=0) +print( + f"* evaluation detail, col: {cols}, shape: {shape}, eval_data: {eval_data}") + + +# In[9]: + + +# feature importance +feature_importance_dataset = result_context.feature_importance_dataset +(feature_importance_data, cols, shape) = feature_importance_dataset.load_values() + +print( + f"* feature_importance detail, col: {cols}, shape: {shape}, feature_importance_data: {feature_importance_data}") + + +# In[10]: + + +# 预处理结果 +preprocessing_dataset = result_context.preprocessing_dataset +(preprocessing_data, cols, shape) = preprocessing_dataset.load_values() + +print( + f"* preprocessing detail, col: {cols}, shape: {shape}, preprocessing_data: {preprocessing_data}") + + +# In[11]: + + +# 建模结果 +model_result_dataset = result_context.model_result_dataset +(model_result, cols, shape) = model_result_dataset.load_values() + +print( + f"* model_result detail, col: {cols}, shape: {shape}, model_result: {model_result}") + + +# In[12]: + + +# 明文处理预测结果 + +# 提取真实标签和预测概率 +y_true = data['class_label'] +y_pred_proba = data['class_pred'] +y_pred = np.where(y_pred_proba >= 0.5, 1, 0) # 二分类阈值设为0.5 + +# 计算评估指标 +accuracy = accuracy_score(y_true, y_pred) +precision = precision_score(y_true, y_pred) +recall = recall_score(y_true, y_pred) +f1 = f1_score(y_true, y_pred) +auc = roc_auc_score(y_true, y_pred_proba) + +print(f"Accuracy: {accuracy:.2f}") +print(f"Precision: {precision:.2f}") +print(f"Recall: {recall:.2f}") +print(f"F1 Score: {f1:.2f}") +print(f"AUC: {auc:.2f}") + +# ROC 曲线 +fpr, tpr, _ = roc_curve(y_true, y_pred_proba) +plt.figure(figsize=(12, 5)) + +# ROC 曲线 +plt.subplot(1, 2, 1) +plt.plot(fpr, tpr, label=f'AUC = {auc:.2f}') +plt.plot([0, 1], [0, 1], 'k--') +plt.xlabel('False Positive Rate') +plt.ylabel('True Positive Rate') +plt.title('ROC Curve') +plt.legend() + +# 精确率-召回率曲线 +precision_vals, recall_vals, _ = precision_recall_curve(y_true, y_pred_proba) +plt.subplot(1, 2, 2) +plt.plot(recall_vals, precision_vals) +plt.xlabel('Recall') +plt.ylabel('Precision') +plt.title('Precision-Recall Curve') + +plt.tight_layout() +plt.show() + + +# In[13]: + + +# 构造xgb预测任务配置 +predict_setting = ModelSetting() +predict_setting.use_psi = True +# model_predict_algorithm = {} +# model_predict_algorithm.update({"setting": xgb_result_context.job_result_detail.model}) +predict_xgb_job_context = wedpr_ml_toolkit.build_job_context( + job_type=JobType.XGB_PREDICTING, + project_id=project_id, + dataset=dataset, + model_setting=predict_setting, + predict_algorithm=xgb_result_context.job_result_detail.model_predict_algorithm) +print(f"* predict_xgb_job_context: {predict_xgb_job_context}") + + +# In[14]: + + +# 执行xgb预测任务 +# xgb_job_id = '9868428439267334' # 测试时跳过创建新任务过程 +xgb_predict_job_id = predict_xgb_job_context.submit() +print(xgb_predict_job_id) + + +# In[15]: + + +# query the job detail +print(f"* xgb_predict_job_id: {xgb_predict_job_id}") + +predict_xgb_job_result = predict_xgb_job_context.fetch_job_result( + xgb_predict_job_id, True) + +# generate the result context +result_context = wedpr_ml_toolkit.build_result_context(job_context=predict_xgb_job_context, + job_result_detail=predict_xgb_job_result) + +xgb_predict_result_context: PredictResultContext = result_context +print(f"* result_context is {xgb_predict_result_context}") + + +# In[16]: + + +# 明文处理预测结果 + + +(data, cols, shapes) = xgb_predict_result_context.model_result_dataset.load_values(header=0) + +# 提取真实标签和预测概率 +y_true = data['class_label'] +y_pred_proba = data['class_pred'] +y_pred = np.where(y_pred_proba >= 0.5, 1, 0) # 二分类阈值设为0.5 + +# 计算评估指标 +accuracy = accuracy_score(y_true, y_pred) +precision = precision_score(y_true, y_pred) +recall = recall_score(y_true, y_pred) +f1 = f1_score(y_true, y_pred) +auc = roc_auc_score(y_true, y_pred_proba) + +print(f"Accuracy: {accuracy:.2f}") +print(f"Precision: {precision:.2f}") +print(f"Recall: {recall:.2f}") +print(f"F1 Score: {f1:.2f}") +print(f"AUC: {auc:.2f}") + +# ROC 曲线 +fpr, tpr, _ = roc_curve(y_true, y_pred_proba) +plt.figure(figsize=(12, 5)) + +# ROC 曲线 +plt.subplot(1, 2, 1) +plt.plot(fpr, tpr, label=f'AUC = {auc:.2f}') +plt.plot([0, 1], [0, 1], 'k--') +plt.xlabel('False Positive Rate') +plt.ylabel('True Positive Rate') +plt.title('ROC Curve') +plt.legend() + +# 精确率-召回率曲线 +precision_vals, recall_vals, _ = precision_recall_curve(y_true, y_pred_proba) +plt.subplot(1, 2, 2) +plt.plot(recall_vals, precision_vals) +plt.xlabel('Recall') +plt.ylabel('Precision') +plt.title('Precision-Recall Curve') + +plt.tight_layout() +plt.show() + + +# In[ ]: diff --git a/python/wedpr_ml_toolkit/requirements.txt b/python/wedpr_ml_toolkit/requirements.txt new file mode 100644 index 00000000..fd33a62e --- /dev/null +++ b/python/wedpr_ml_toolkit/requirements.txt @@ -0,0 +1,5 @@ +setuptools>=70.0.0 +hdfs>=2.7.2 +requests~=2.31.0 +requests_toolbelt==0.9.1 +requests_kerberos>=0.15.0 diff --git a/python/wedpr_ml_toolkit/setup.py b/python/wedpr_ml_toolkit/setup.py new file mode 100644 index 00000000..e1bba009 --- /dev/null +++ b/python/wedpr_ml_toolkit/setup.py @@ -0,0 +1,61 @@ +import sys + +from setuptools import find_packages, setup +from setuptools.command.bdist_egg import bdist_egg + + +class bdist_egg_disabled(bdist_egg): + """Disabled version of bdist_egg + + Prevents setup.py install from performing setuptools' default easy_install, + which it should never ever do. + """ + + def run(self): + sys.exit( + "Aborting implicit building of eggs. Use `pip install .` to install from source." + ) + + +setup_args = dict( + name='wedpr_ml_toolkit', + packages=find_packages(), + version="1.0.0.dev-20241201", + description="wedpr-ml-toolkit: The ML toolkit for WeDPR", + long_description_content_type="text/markdown", + author="WeDPR Development Team", + author_email="wedpr@webank.com", + url="https://github.com/WeBankBlockchain/WeDPR-Component", + license="Apache-2.0", + platforms="Linux, Mac OS X", + keywords=['Interactive', 'Interpreter', 'Shell', 'Web'], + python_requires=">=3.8", + include_package_data=True, + classifiers=[ + 'Intended Audience :: Developers', + 'Intended Audience :: System Administrators', + 'Intended Audience :: Science/Research', + 'Programming Language :: Python', + 'Programming Language :: Python :: 3', + ], +) + +setup_args['cmdclass'] = { + 'bdist_egg': bdist_egg if 'bdist_egg' in sys.argv else bdist_egg_disabled, +} + +setup_args['install_requires'] = install_requires = [] +with open('requirements.txt') as f: + for line in f.readlines(): + req = line.strip() + if not req or req.startswith(('-e', '#')): + continue + install_requires.append(req) + + +def main(): + setup(**setup_args) + + +if __name__ == '__main__': + main() diff --git a/python/wedpr_ml_toolkit/test/UserGuide.md b/python/wedpr_ml_toolkit/test/UserGuide.md new file mode 100644 index 00000000..d01f7391 --- /dev/null +++ b/python/wedpr_ml_toolkit/test/UserGuide.md @@ -0,0 +1,42 @@ +# wedpr专家模式用户手册 + +## 配置 + +1. 左侧用户目录中新建配置文件,文件命名为:config.properties +2. 配置信息参考: + +``` +access_key_id= +access_key_secret= +remote_entrypoints=http://127.0.0.1:8005,http://127.0.0.1:8006 + +agency_name=WeBank +workspace_path=/user/ppc/webank/ +user=test_user +storage_endpoint=http://127.0.0.1:50070 +``` + +3. 通过前端页面登录,例如:http://139.159.202.235:8005/ +4. 创建个人项目空间,通过【打开jupyter】按钮进入专家模式 + +## 基础功能 + +1. 支持通过launcher启动python,jupyter,终端,文本编辑等功能 +2. 支持在用户目录空间创建/修改/删除配置文件,文本文件,bash,python notebook等格式文件 +3. 通过launcher启动python,jupyter,终端后可以正常执行对应的代码功能 + +## hdfs数据功能 + +1. 支持注册dataset,支持两种方式: pd.Dataframe, hdfs_path +2. 支持更新dataset + +* 详细使用说明参考示例文件:【test_dataset.ipynb】 + +## wedpr任务功能 + +1. 支持配置任务参数 +2. 支持提交psi,建模训练,预测等任务 +3. 支持获取任务结果 +4. 支持对任务结果进行明文处理 + +* 详细使用说明参考示例文件:【test_psi.ipynb】和【test_xgboost.ipynb】 diff --git a/python/wedpr_ml_toolkit/test/__init__.py b/python/wedpr_ml_toolkit/test/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/python/wedpr_ml_toolkit/test/test_ml_toolkit.py b/python/wedpr_ml_toolkit/test/test_ml_toolkit.py new file mode 100644 index 00000000..824d53c5 --- /dev/null +++ b/python/wedpr_ml_toolkit/test/test_ml_toolkit.py @@ -0,0 +1,143 @@ +# -*- coding: utf-8 -*- +import unittest +import numpy as np +import pandas as pd +from wedpr_ml_toolkit.config.wedpr_ml_config import WeDPRMlConfigBuilder +from wedpr_ml_toolkit.wedpr_ml_toolkit import WeDPRMlToolkit +from wedpr_ml_toolkit.context.dataset_context import DatasetContext +from wedpr_ml_toolkit.context.data_context import DataContext +from wedpr_ml_toolkit.context.job_context import JobType +from wedpr_ml_toolkit.context.model_setting import PreprocessingSetting +from wedpr_ml_toolkit.context.model_setting import ModelSetting + + +class WeDPRMlToolkitTestWrapper: + def __init__(self, config_file_path): + self.wedpr_config = WeDPRMlConfigBuilder.build_from_properties_file( + config_file_path) + self.wedpr_ml_toolkit = WeDPRMlToolkit(self.wedpr_config) + + def test_submit_job(self): + # 注册 dataset,支持两种方式: pd.Dataframe, hdfs_path + df = pd.DataFrame({ + 'id': np.arange(0, 100), # id列,顺序整数 + 'y': np.random.randint(0, 2, size=100), + # x1到x10列,随机数 + **{f'x{i}': np.random.rand(100) for i in range(1, 11)} + }) + # the dataset + dataset1 = DatasetContext(storage_entrypoint=self.wedpr_ml_toolkit.get_storage_entry_point(), + dataset_client=self.wedpr_ml_toolkit.get_dataset_client(), + storage_workspace=self.wedpr_config.user_config.get_workspace_path(), + dataset_id="d-9743660607744005", + is_label_holder=True) + dataset1.save_values(df, path='d-101') + + # the dataset + dataset2 = DatasetContext(storage_entrypoint=self.wedpr_ml_toolkit.get_storage_entry_point(), + dataset_client=self.wedpr_ml_toolkit.get_dataset_client(), + dataset_id="d-9743674298214405") + print(f"### dataset2 meta: {dataset2.dataset_meta}") + if dataset1.storage_client is not None: + # save values to dataset1 + dataset1.save_values(df) + (values, columns, shape) = dataset1.load_values() + print(f"### values: {values}") + + # 构建 dataset context + dataset = DataContext(dataset1, dataset2) + + # init the job context + project_id = "9737304249804806" + print("* build psi job context") + psi_job_context = self.wedpr_ml_toolkit.build_job_context( + JobType.PSI, project_id, dataset, None, "id") + print(psi_job_context.participant_id_list, + psi_job_context.result_receiver_id_list) + # 执行psi任务 + print("* submit psi job") + psi_job_id = psi_job_context.submit() + print(f"* submit psi job success, job_id: {psi_job_id}") + psi_result = psi_job_context.fetch_job_result(psi_job_id, True) + print( + f"* fetch_job_result for psi job {psi_job_id} success, result: {psi_result}") + # build the psi result: + psi_result_ctx = self.wedpr_ml_toolkit.build_result_context( + psi_job_context, psi_result) + print(f"* psi_result_ctx: {psi_result_ctx}") + (psi_result_values, psi_result_columns, + psi_result_shape) = psi_result_ctx.result_dataset.load_values() + # obtain the intersection + print( + f"* psi result, psi_result_columns: {psi_result_columns}, " + f"psi_result_shape: {psi_result_shape}, psi_result_values: {psi_result_values}") + # 初始化 + print(f"* build pre-processing data-context") + preprocessing_data = DataContext(dataset1, dataset2) + preprocessing_job_context = self.wedpr_ml_toolkit.build_job_context( + JobType.PREPROCESSING, project_id, preprocessing_data, PreprocessingSetting()) + # 执行预处理任务 + print(f"* submit pre-processing job") + preprocessing_job_id = preprocessing_job_context.submit() + print( + f"* submit pre-processing job success, job_id: {preprocessing_job_id}") + preprocessing_result = preprocessing_job_context.fetch_job_result( + preprocessing_job_id, True) + print( + f"* fetch pre-processing job result success, job_id: {preprocessing_job_id}, result: {preprocessing_result}") + print(preprocessing_job_context.participant_id_list, + preprocessing_job_context.result_receiver_id_list) + # build the context + preprocessing_result_ctx = self.wedpr_ml_toolkit.build_result_context(preprocessing_job_context, + preprocessing_result) + print( + f"* preprocessing_result_ctx: {preprocessing_result_ctx.preprocessing_dataset}") + preprocessing_values, columns, shape = preprocessing_result_ctx.preprocessing_dataset.load_values() + print( + f"* preprocessing_result_dataset, columns: {columns}, shape: {shape}") + # test xgb job + xgb_data = DataContext(dataset1, dataset2) + model_setting = ModelSetting() + model_setting.use_psi = True + xgb_job_context = self.wedpr_ml_toolkit.build_job_context( + job_type=JobType.XGB_TRAINING, project_id=project_id, + dataset=xgb_data, + model_setting=model_setting, id_fields="id") + print(f"* construct xgb job context: participant_id_list: {xgb_job_context.participant_id_list}, " + f"result_receiver_id_list: {xgb_job_context.result_receiver_id_list}") + xgb_job_id = xgb_job_context.submit() + print(f"* submit xgb job success, {xgb_job_id}") + xgb_job_result = xgb_job_context.fetch_job_result(xgb_job_id, True) + print(f"* xgb job result: {xgb_job_result}") + xgb_job_context = self.wedpr_ml_toolkit.build_result_context( + job_context=xgb_job_context, job_result_detail=xgb_job_result) + print(f"* xgb job result: {xgb_job_context}") + # load the feature_importance information + (feature_importance_value, feature_importance_cols, feature_importance_shape) = \ + xgb_job_context.feature_importance_dataset.load_values() + print(f"* xgb feature importance information: {feature_importance_cols}, " + f"{feature_importance_shape}, {feature_importance_value}") + # load the evaluation information + (evaluation_value, evaluation_cols, evaluation_shape) = \ + xgb_job_context.evaluation_dataset.load_values() + print(f"* xgb evaluation information: {evaluation_cols}, " + f"{evaluation_shape}, {evaluation_value}") + + def test_query_job(self, job_id: str, block_until_finish): + job_result = self.wedpr_ml_toolkit.query_job_status( + job_id, block_until_finish) + print(f"#### query_job_status job_result: {job_result}") + job_detail_result = self.wedpr_ml_toolkit.query_job_detail( + job_id, block_until_finish) + print(f"#### query_job_detail job_detail_result: {job_detail_result}") + return (job_result, job_detail_result) + + +class TestMlToolkit(unittest.TestCase): + def test_query_jobs(self): + wrapper = WeDPRMlToolkitTestWrapper("config.properties") + job_id = wrapper.test_submit_job() + + +if __name__ == '__main__': + unittest.main() diff --git a/python/wedpr_ml_toolkit/wedpr_ml_toolkit/__init__.py b/python/wedpr_ml_toolkit/wedpr_ml_toolkit/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/python/wedpr_ml_toolkit/wedpr_ml_toolkit/common/__init__.py b/python/wedpr_ml_toolkit/wedpr_ml_toolkit/common/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/python/wedpr_ml_toolkit/wedpr_ml_toolkit/common/utils/__init__.py b/python/wedpr_ml_toolkit/wedpr_ml_toolkit/common/utils/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/python/wedpr_ml_toolkit/wedpr_ml_toolkit/common/utils/base_object.py b/python/wedpr_ml_toolkit/wedpr_ml_toolkit/common/utils/base_object.py new file mode 100644 index 00000000..9eda6a3e --- /dev/null +++ b/python/wedpr_ml_toolkit/wedpr_ml_toolkit/common/utils/base_object.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +from typing import Any +import time + + +class BaseObject: + def set_params(self, **params: Any): + for key, value in params.items(): + setattr(self, key, value) + if hasattr(self, f"{key}"): + setattr(self, f"{key}", value) + return self + + def as_dict(obj): + return {attr: getattr(obj, attr) for attr in dir(obj) if not callable(getattr(obj, attr)) and not attr.startswith("__")} + + def execute_with_retry(self, request_func, retry_times, retry_wait_seconds, *args, **kwargs): + attempt = 0 + while attempt < retry_times: + try: + response = request_func(*args, **kwargs) + return response + except Exception as e: + attempt += 1 + if attempt < retry_times: + time.sleep(retry_wait_seconds) + else: + raise e + + +class WeDPRResponse(BaseObject): + def __init__(self, **params: Any): + self.code = None + self.msg = None + self.data = None + self.set_params(**params) + + def success(self): + return self.code is not None and self.code == 0 diff --git a/python/wedpr_ml_toolkit/wedpr_ml_toolkit/common/utils/constant.py b/python/wedpr_ml_toolkit/wedpr_ml_toolkit/common/utils/constant.py new file mode 100644 index 00000000..626b2c21 --- /dev/null +++ b/python/wedpr_ml_toolkit/wedpr_ml_toolkit/common/utils/constant.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- + +class Constant: + NUMERIC_ARRAY = [i for i in range(10)] + HTTP_STATUS_OK = 200 + WEDPR_API_PREFIX = 'api/wedpr/v3/' + DEFAULT_SUBMIT_JOB_URI = f'{WEDPR_API_PREFIX}project/submitJob' + DEFAULT_QUERY_JOB_STATUS_URL = f'{WEDPR_API_PREFIX}project/queryJobByCondition' + DEFAULT_QUERY_JOB_DETAIL_URL = f'{WEDPR_API_PREFIX}scheduler/queryJobDetail' + # the dataset related url + DEFAULT_QUERY_DATASET_URL = f'{WEDPR_API_PREFIX}dataset/queryDataset' + DEFAULT_UPDATED_DATASET_URL = f'{WEDPR_API_PREFIX}dataset/updateDatasetMeta' + PSI_RESULT_FILE = "psi_result.csv" + + FEATURE_BIN_FILE = "feature_bin.json" + XGB_TREE_PREFIX = "xgb_tree" + MODEL_RESULT_FILE = XGB_TREE_PREFIX + '.json' + PREPROCESSING_RESULT_FILE = "preprocessing_result.csv" + EVALUATION_TABLE_FILE = "mpc_xgb_evaluation_table.csv" + FEATURE_IMPORTANCE_FILE = "xgb_result_feature_importance_table.csv" + FEATURE_SELECTION_FILE = "xgb_result_column_info_selected.csv" + MODEL_FILE = "model_enc.kpl" + WOE_IV_FILE = "woe_iv.csv" diff --git a/python/wedpr_ml_toolkit/wedpr_ml_toolkit/common/utils/hdfs_storage_impl.py b/python/wedpr_ml_toolkit/wedpr_ml_toolkit/common/utils/hdfs_storage_impl.py new file mode 100644 index 00000000..761d152f --- /dev/null +++ b/python/wedpr_ml_toolkit/wedpr_ml_toolkit/common/utils/hdfs_storage_impl.py @@ -0,0 +1,91 @@ +import os +from typing import AnyStr + +from hdfs.client import InsecureClient +from wedpr_ml_toolkit.common.utils import utils +from wedpr_ml_toolkit.config.wedpr_ml_config import StorageConfig +from hdfs.ext.kerberos import KerberosClient + + +class HdfsStorageImpl: + # endpoint: http://127.0.0.1:50070 + def __init__(self, storage_config: StorageConfig): + self.hdfs_config = storage_config + self._hdfs_storage_path = self.hdfs_config.user_config.get_workspace_path() + self.client = None + if self.hdfs_config.get_enable_krb5_auth() is True: + self.client = KerberosClient( + url=self.hdfs_config.storage_endpoint, + principal=self.hdfs_config.hdfs_auth_principal, + hostname_override=self.hdfs_config.hdfs_hostname_override, + password=self.hdfs_config.hdfs_auth_password, + timeout=10000) + else: + self.client = InsecureClient( + self.hdfs_config.storage_endpoint, + user=self.hdfs_config.user_config.user) + + def get_home_path(self): + return self._hdfs_storage_path + + def download_file(self, hdfs_path, local_file_path, enable_cache=False): + # hit the cache + if enable_cache is True and utils.file_exists(local_file_path): + return + if utils.file_exists(local_file_path): + utils.delete_file(local_file_path) + local_path = os.path.dirname(local_file_path) + if len(local_path) > 0 and not os.path.exists(local_path): + os.makedirs(local_path) + self.client.download(os.path.join(self._hdfs_storage_path, + hdfs_path), local_file_path) + return + + def upload_file(self, local_file_path, hdfs_path): + self.make_file_path(hdfs_path) + self.client.upload(os.path.join(self._hdfs_storage_path, hdfs_path), + local_file_path, overwrite=True) + return + + def make_file_path(self, hdfs_path): + hdfs_dir = os.path.dirname(hdfs_path) + if self.client.status(os.path.join(self._hdfs_storage_path, hdfs_dir), strict=False) is None: + self.client.makedirs(os.path.join( + self._hdfs_storage_path, hdfs_dir)) + return + + def delete_file(self, hdfs_path): + self.client.delete(os.path.join( + self._hdfs_storage_path, hdfs_path), recursive=True) + return + + def save_data(self, data: AnyStr, hdfs_path): + self.make_file_path(hdfs_path) + self.client.write(os.path.join(self._hdfs_storage_path, + hdfs_path), data, overwrite=True) + return + + def get_data(self, hdfs_path) -> AnyStr: + with self.client.read(os.path.join(self._hdfs_storage_path, hdfs_path)) as reader: + content = reader.read() + return content + + def mkdir(self, hdfs_dir): + self.client.makedirs(hdfs_dir) + + def file_existed(self, hdfs_path): + if self.client.status(os.path.join(self._hdfs_storage_path, hdfs_path), strict=False) is None: + return False + return True + + def file_rename(self, old_hdfs_path, hdfs_path): + old_path = os.path.join(self._hdfs_storage_path, old_hdfs_path) + new_path = os.path.join(self._hdfs_storage_path, hdfs_path) + # return for the file not exists + if not self.file_existed(old_path): + return + parent_path = os.path.dirname(new_path) + if len(parent_path) > 0 and not self.file_existed(parent_path): + self.mkdir(parent_path) + self.client.rename(old_path, new_path) + return diff --git a/python/wedpr_ml_toolkit/wedpr_ml_toolkit/common/utils/properies_parser.py b/python/wedpr_ml_toolkit/wedpr_ml_toolkit/common/utils/properies_parser.py new file mode 100644 index 00000000..dd05a475 --- /dev/null +++ b/python/wedpr_ml_toolkit/wedpr_ml_toolkit/common/utils/properies_parser.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- + +class Properties: + def __init__(self, file_path): + self.file_path = file_path + + def getProperties(self): + try: + pro_file = open(self.file_path, 'r', encoding='utf-8') + properties = {} + for line in pro_file: + if line.find('=') > 0: + strs = line.strip("\"").replace('\n', '').split('=') + properties[strs[0].strip()] = strs[1].strip() + except Exception as e: + raise e + else: + pro_file.close() + return properties diff --git a/python/wedpr_ml_toolkit/wedpr_ml_toolkit/common/utils/utils.py b/python/wedpr_ml_toolkit/wedpr_ml_toolkit/common/utils/utils.py new file mode 100644 index 00000000..9bc61962 --- /dev/null +++ b/python/wedpr_ml_toolkit/wedpr_ml_toolkit/common/utils/utils.py @@ -0,0 +1,58 @@ +# -*- coding: utf-8 -*- +import uuid +from enum import Enum +import shutil +import os +import random +from wedpr_ml_toolkit.common.utils.constant import Constant + + +class IdPrefixEnum(Enum): + DATASET = "d-" + ALGORITHM = "a-" + JOB = "j-" + + +def make_id(prefix): + return prefix + str(uuid.uuid4()).replace("-", "") + + +def generate_nonce(nonce_len): + return ''.join(str(random.choice(Constant.NUMERIC_ARRAY)) for _ in range(nonce_len)) + + +def file_exists(_file): + if os.path.exists(_file) and os.path.isfile(_file): + return True + return False + + +def delete_file(path): + if os.path.isfile(path): + os.remove(path) + elif os.path.isdir(path): + shutil.rmtree(path) + else: + raise (Exception(' path not exisited ! path => %s', path)) + + +def get_config_value(key, default_value, config_value, required): + if required and config_value is None: + raise Exception(f"Invalid config for '{key}' for not set!") + if config_value is None: + return default_value + value = config_value + if type(config_value) is dict: + if key in config_value: + value = config_value[key] + else: + value = default_value + if value is None: + return default_value + return value + + +def str_to_bool(str_value): + if str_value.lower() == "true": + return True + return False diff --git a/python/wedpr_ml_toolkit/wedpr_ml_toolkit/config/__init__.py b/python/wedpr_ml_toolkit/wedpr_ml_toolkit/config/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/python/wedpr_ml_toolkit/wedpr_ml_toolkit/config/wedpr_ml_config.py b/python/wedpr_ml_toolkit/wedpr_ml_toolkit/config/wedpr_ml_config.py new file mode 100644 index 00000000..2b5f6e9c --- /dev/null +++ b/python/wedpr_ml_toolkit/wedpr_ml_toolkit/config/wedpr_ml_config.py @@ -0,0 +1,109 @@ +# -*- coding: utf-8 -*- +import os +from wedpr_ml_toolkit.common.utils.base_object import BaseObject +from wedpr_ml_toolkit.common.utils.constant import Constant +from wedpr_ml_toolkit.common.utils.properies_parser import Properties +from wedpr_ml_toolkit.common.utils import utils + + +class AuthConfig(BaseObject): + def __init__(self, access_key_id: str = None, access_key_secret: str = None, remote_entrypoints: str = None, nonce_len: int = 5): + self.access_key_id = access_key_id + self.access_key_secret = access_key_secret + self.remote_entrypoints = remote_entrypoints + self.nonce_len = nonce_len + + def get_remote_entrypoints_list(self) -> []: + if self.remote_entrypoints is None: + return None + return self.remote_entrypoints.split(',') + + +class JobConfig(BaseObject): + def __init__(self, polling_interval_s: int = 5, max_retries: int = 2, retry_delay_s: int = 5, + submit_job_uri: str = Constant.DEFAULT_SUBMIT_JOB_URI, + query_job_status_uri: str = Constant.DEFAULT_QUERY_JOB_STATUS_URL, + query_job_detail_uri: str = Constant.DEFAULT_QUERY_JOB_DETAIL_URL): + self.polling_interval_s = polling_interval_s + self.max_retries = max_retries + self.retry_delay_s = retry_delay_s + self.submit_job_uri = submit_job_uri + self.query_job_status_uri = query_job_status_uri + self.query_job_detail_uri = query_job_detail_uri + + +class DatasetConfig(BaseObject): + def __init__(self, + query_dataset_uri=Constant.DEFAULT_QUERY_DATASET_URL, + update_dataset_uri=Constant.DEFAULT_UPDATED_DATASET_URL): + self.query_dataset_uri = query_dataset_uri + self.update_dataset_uri = update_dataset_uri + + +class UserConfig(BaseObject): + def __init__(self, agency_name: str = None, workspace_path: str = None, user_name: str = None): + self.agency_name = agency_name + self.workspace_path = workspace_path + self.user = user_name + + def get_workspace_path(self): + return os.path.join(self.workspace_path, self.user) + + +class StorageConfig(BaseObject): + def __init__(self, + user_config: UserConfig, + storage_endpoint: str = None, + enable_krb5_auth: str = "False", + hdfs_auth_principal: str = None, + hdfs_auth_password: str = None, + hdfs_hostname_override: str = None): + self.user_config = user_config + self.storage_endpoint = storage_endpoint + self.enable_krb5_auth = enable_krb5_auth + self.hdfs_auth_principal = hdfs_auth_principal + self.hdfs_auth_password = hdfs_auth_password + self.hdfs_hostname_override = hdfs_hostname_override + + def get_enable_krb5_auth(self) -> bool: + if self.enable_krb5_auth is None or len(self.enable_krb5_auth) == 0: + return False + return utils.str_to_bool(self.enable_krb5_auth) + + def __repr__(self): + return f"hdfs_user: {self.hdfs_user}, hdfs_home: {self.hdfs_home}, hdfs_url: {self.hdfs_url}, " \ + f"enable_krb5_auth: {self.enable_krb5_auth}, hdfs_auth_principal: {self.hdfs_auth_principal}" + + +class HttpConfig(BaseObject): + def __init__(self, timeout_seconds=3): + self.timeout_seconds = timeout_seconds + + +class WeDPRMlConfig: + def __init__(self, config_dict): + self.auth_config = AuthConfig() + self.auth_config.set_params(**config_dict) + self.job_config = JobConfig() + self.job_config.set_params(**config_dict) + self.user_config = UserConfig() + self.user_config.set_params(**config_dict) + self.http_config = HttpConfig() + self.http_config.set_params(**config_dict) + self.dataset_config = DatasetConfig() + self.storage_config = StorageConfig(self.user_config) + self.storage_config.set_params(**config_dict) + + +class WeDPRMlConfigBuilder: + @staticmethod + def build(config_dict) -> WeDPRMlConfig: + return WeDPRMlConfig(config_dict) + + @staticmethod + def build_from_properties_file(config_file_path): + if not os.path.exists(config_file_path): + raise Exception( + f"build WeDPRMlConfig failed for the config file {config_file_path} not exits!") + properties = Properties(config_file_path) + return WeDPRMlConfigBuilder.build(properties.getProperties()) diff --git a/python/wedpr_ml_toolkit/wedpr_ml_toolkit/context/__init__.py b/python/wedpr_ml_toolkit/wedpr_ml_toolkit/context/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/python/wedpr_ml_toolkit/wedpr_ml_toolkit/context/data_context.py b/python/wedpr_ml_toolkit/wedpr_ml_toolkit/context/data_context.py new file mode 100644 index 00000000..b7d029b9 --- /dev/null +++ b/python/wedpr_ml_toolkit/wedpr_ml_toolkit/context/data_context.py @@ -0,0 +1,45 @@ +import os + +from wedpr_ml_toolkit.common import utils +from wedpr_ml_toolkit.context.dataset_context import DatasetContext + + +class DataContext: + + def __init__(self, *datasets): + self.datasets = list(datasets) + + def to_psi_format(self, merge_filed, result_receiver_id_list): + dataset_psi = [] + for dataset in self.datasets: + if dataset.dataset_meta.ownerAgencyName in result_receiver_id_list: + result_receiver = True + else: + result_receiver = False + dataset_psi_info = self.__generate_dataset_info__( + merge_filed, result_receiver, None, dataset) + dataset_psi.append(dataset_psi_info) + return dataset_psi + + def __generate_dataset_info__(self, id_field: str, receive_result: bool, label_provider: bool, dataset: DatasetContext): + return {"idFields": [id_field], + "dataset": {"ownerAgency": dataset.dataset_meta.ownerAgencyName, + "datasetID": dataset.dataset_id}, + "receiveResult": receive_result, + "labelProvider": label_provider} + + def to_model_formort(self, merge_filed, result_receiver_id_list): + dataset_model = [] + for dataset in self.datasets: + if dataset.dataset_meta.ownerAgencyName in result_receiver_id_list: + result_receiver = True + else: + result_receiver = False + if dataset.is_label_holder: + label_provider = True + else: + label_provider = False + dataset_psi_info = self.__generate_dataset_info__( + merge_filed, result_receiver, label_provider, dataset) + dataset_model.append(dataset_psi_info) + return dataset_model diff --git a/python/wedpr_ml_toolkit/wedpr_ml_toolkit/context/dataset_context.py b/python/wedpr_ml_toolkit/wedpr_ml_toolkit/context/dataset_context.py new file mode 100644 index 00000000..f6d08d39 --- /dev/null +++ b/python/wedpr_ml_toolkit/wedpr_ml_toolkit/context/dataset_context.py @@ -0,0 +1,83 @@ +import os +import pandas as pd +from wedpr_ml_toolkit.transport.storage_entrypoint import StorageEntryPoint +from wedpr_ml_toolkit.transport.wedpr_remote_dataset_client import WeDPRDatasetClient +from wedpr_ml_toolkit.transport.wedpr_remote_dataset_client import DatasetMeta +import io + + +class DatasetContext: + + def __init__(self, + storage_entrypoint: StorageEntryPoint, + storage_workspace=None, + dataset_client: WeDPRDatasetClient = None, + dataset_meta=None, + dataset_id=None, + is_label_holder=False): + self.storage_client = storage_entrypoint + self.dataset_client = dataset_client + self.dataset_id = dataset_id + params = {} + self.dataset_meta = dataset_meta + # fetch the dataset information + if self.dataset_meta is None and self.dataset_id is not None and self.dataset_client is not None: + self.dataset_meta = self.dataset_client.query_dataset( + self.dataset_id) + self.is_label_holder = is_label_holder + # the storage workspace + self.storage_workspace = storage_workspace + + def __repr__(self): + return f"dataset_id: {self.dataset_id}, " \ + f"dataset_meta: {self.dataset_meta}" + + def load_values(self, header=0): + # 加载hdfs的数据集 + if self.storage_client is not None: + values = self.storage_client.download( + self.dataset_meta.file_path, header=header) + if values is None: + return values, None, None + return values, values.columns, values.shape + raise Exception("Must set the storage client to load data!") + + def save_values(self, values: pd.DataFrame = None, path=None): + # no values to save + if values is None: + return + csv_buffer = io.StringIO() + values.to_csv(csv_buffer, index=False) + value_bytes = csv_buffer.getvalue() + columns = values.columns.to_list() + # update the meta firstly + if path is None and self.dataset_meta is not None and self.dataset_meta.datasetId is not None: + dataset_meta = DatasetMeta(dataset_id=self.dataset_meta.datasetId, + dataset_fields=','.join(columns), + dataset_size=len(value_bytes), + dataset_record_count=len(values), + dataset_column_count=len(columns)) + self.dataset_client.update_dataset(dataset_meta) + # update the dataset meta + if self.dataset_meta is not None: + self.dataset_meta.datasetSize = len(value_bytes) + self.dataset_meta.datasetFields = ','.join(columns) + self.dataset_meta.recordCount = len(values) + self.dataset_meta.columnCount = len(columns) + # update the content + target_path = self.dataset_meta.file_path + # 保存数据到hdfs目录 + if path is not None: + target_path = path + # add the storage_workspace + if self.storage_workspace is not None and \ + not target_path.startswith(self.storage_workspace): + target_path = os.path.join( + self.storage_workspace, target_path) + if self.storage_client is not None: + self.storage_client.upload_bytes(value_bytes, target_path) + + def update_path(self, path: str = None): + # 将数据集存入hdfs相同路径,替换旧数据集 + if path is not None: + self.dataset_meta.file_path = path diff --git a/python/wedpr_ml_toolkit/wedpr_ml_toolkit/context/job_context.py b/python/wedpr_ml_toolkit/wedpr_ml_toolkit/context/job_context.py new file mode 100644 index 00000000..0fadb81a --- /dev/null +++ b/python/wedpr_ml_toolkit/wedpr_ml_toolkit/context/job_context.py @@ -0,0 +1,276 @@ +# -*- coding: utf-8 -*- +import json + +from wedpr_ml_toolkit.transport.storage_entrypoint import StorageEntryPoint +from wedpr_ml_toolkit.context.data_context import DataContext +from wedpr_ml_toolkit.transport.wedpr_remote_job_client import JobParam +from wedpr_ml_toolkit.transport.wedpr_remote_job_client import JobInfo +from abc import abstractmethod +from wedpr_ml_toolkit.transport.wedpr_remote_job_client import WeDPRRemoteJobClient +from wedpr_ml_toolkit.transport.wedpr_remote_job_client import JobType, ModelType +from wedpr_ml_toolkit.transport.wedpr_remote_dataset_client import DatasetMeta +from wedpr_ml_toolkit.context.model_setting import ModelSetting +from wedpr_ml_toolkit.config.wedpr_ml_config import UserConfig + + +class JobContext: + + def __init__(self, remote_job_client: WeDPRRemoteJobClient, + storage_entry_point: StorageEntryPoint, + project_id: str, + dataset: DataContext, + user_config: UserConfig): + if dataset is None: + raise Exception("Must define the job related datasets!") + self.dataset = dataset + self.user_config = user_config + + self.remote_job_client = remote_job_client + self.storage_entry_point = storage_entry_point + self.project_id = project_id + self.participant_id_list = [] + self.task_parties = [] + self.dataset_id_list = [] + self.dataset_list = [] + self.label_holder_agency = None + self.label_columns = None + self.__init_participant__() + self.__init_label_information__() + self.result_receiver_id_list = [ + self.user_config.agency_name] # 仅限jupyter所在机构 + self.__check__() + + def __check__(self): + """ + 校验机构数和任务是否匹配 + """ + if len(self.participant_id_list) < 2: + raise Exception("至少需要传入两个机构") + if not self.label_holder_agency or self.label_holder_agency not in self.participant_id_list: + raise Exception("数据集中标签提供方配置错误") + + def __init_participant__(self): + participant_id_list = [] + dataset_id_list = [] + for dataset in self.dataset.datasets: + participant_id_list.append(dataset.dataset_meta.ownerAgencyName) + dataset_id_list.append(dataset.dataset_id) + self.task_parties.append({'userName': dataset.dataset_meta.ownerUserName, + 'agency': dataset.dataset_meta.ownerAgencyName}) + self.participant_id_list = participant_id_list + self.dataset_id_list = dataset_id_list + + def __init_label_information__(self): + label_holder_agency = None + label_columns = None + for dataset in self.dataset.datasets: + if dataset.is_label_holder: + label_holder_agency = dataset.dataset_meta.ownerAgencyName + label_columns = 'y' + self.label_holder_agency = label_holder_agency + self.label_columns = label_columns + + @abstractmethod + def build(self) -> JobParam: + pass + + @abstractmethod + def get_job_type(self) -> JobType: + pass + + def submit(self): + return self.remote_job_client.submit_job(self.build()) + + def fetch_job_result(self, job_id, block_until_success): + # query_job_detail + result_detail = self.remote_job_client.query_job_detail( + job_id, block_until_success) + return result_detail + + +class PSIJobContext(JobContext): + def __init__(self, + remote_job_client: WeDPRRemoteJobClient, + storage_entry_point: StorageEntryPoint, + project_id: str, + dataset: DataContext, + user_config: UserConfig, + merge_field: str = 'id'): + super().__init__(remote_job_client, storage_entry_point, + project_id, dataset, user_config) + self.merge_field = merge_field + + def get_job_type(self) -> JobType: + return JobType.PSI + + def build(self) -> JobParam: + self.dataset_list = self.dataset.to_psi_format( + self.merge_field, self.result_receiver_id_list) + job_info = JobInfo(job_type=self.get_job_type(), + project_id=self.project_id, + param=json.dumps({'dataSetList': self.dataset_list})) + job_param = JobParam(job_info, self.task_parties, self.dataset_id_list) + return job_param + + +class PreprocessingJobContext(JobContext): + def __init__(self, remote_job_client: WeDPRRemoteJobClient, + storage_entry_point: StorageEntryPoint, + project_id: str, model_setting: ModelSetting, + dataset: DataContext, user_config: UserConfig, + merge_field: str = 'id'): + super().__init__(remote_job_client, storage_entry_point, + project_id, dataset, user_config) + self.model_setting = model_setting + self.merge_field = merge_field + + def get_job_type(self) -> JobType: + return JobType.PREPROCESSING + + def build(self) -> JobParam: + self.dataset_list = self.dataset.to_model_formort( + self.merge_field, self.result_receiver_id_list) + job_info = JobInfo(job_type=self.get_job_type(), + project_id=self.project_id, + param=json.dumps({'dataSetList': self.dataset_list, 'modelSetting': self.model_setting.as_dict()})) + job_param = JobParam(job_info, self.task_parties, self.dataset_id_list) + return job_param + + +class FeatureEngineeringJobContext(JobContext): + def __init__(self, + remote_job_client: WeDPRRemoteJobClient, + storage_entry_point: StorageEntryPoint, + project_id: str, + model_setting: ModelSetting, + dataset: DataContext, + user_config: UserConfig, merge_field: str = 'id'): + super().__init__(remote_job_client, storage_entry_point, + project_id, dataset, user_config) + self.model_setting = model_setting + self.merge_field = merge_field + + def get_job_type(self) -> JobType: + return JobType.FEATURE_ENGINEERING + + def build(self) -> JobParam: + self.dataset_list = self.dataset.to_model_formort( + self.merge_field, self.result_receiver_id_list) + job_info = JobInfo(job_type=self.get_job_type(), + project_id=self.project_id, + param=json.dumps({'dataSetList': self.dataset_list, 'modelSetting': self.model_setting.as_dict()})) + job_param = JobParam(job_info, self.task_parties, self.dataset_id_list) + return job_param + + +class SecureLGBMTrainingJobContext(JobContext): + def __init__(self, + remote_job_client: WeDPRRemoteJobClient, + storage_entry_point: StorageEntryPoint, + project_id: str, + model_setting: ModelSetting, + dataset: DataContext, + user_config: UserConfig, + merge_field: str = 'id'): + super().__init__(remote_job_client, storage_entry_point, + project_id, dataset, user_config) + self.model_setting = model_setting + self.merge_field = merge_field + + def get_job_type(self) -> JobType: + return JobType.XGB_TRAINING + + def build(self) -> JobParam: + self.dataset_list = self.dataset.to_model_formort( + self.merge_field, self.result_receiver_id_list) + job_info = JobInfo(job_type=self.get_job_type(), + project_id=self.project_id, + param=json.dumps({'dataSetList': self.dataset_list, 'modelSetting': self.model_setting.as_dict()})) + job_param = JobParam(job_info, self.task_parties, self.dataset_id_list) + return job_param + + +class SecureLGBMPredictJobContext(JobContext): + def __init__(self, + remote_job_client: WeDPRRemoteJobClient, + storage_entry_point: StorageEntryPoint, + project_id: str, + model_setting: ModelSetting, predict_algorithm, + dataset: DataContext, + user_config: UserConfig, + merge_field: str = 'id'): + super().__init__(remote_job_client, storage_entry_point, + project_id, dataset, user_config) + self.model_setting = model_setting + self.merge_field = merge_field + self.predict_algorithm = predict_algorithm + + def get_job_type(self) -> JobType: + return JobType.XGB_PREDICTING + + def build(self) -> JobParam: + self.dataset_list = self.dataset.to_model_formort( + self.merge_field, self.result_receiver_id_list) + job_info = JobInfo(job_type=self.get_job_type(), + project_id=self.project_id, param=json.dumps( + {'dataSetList': self.dataset_list, 'modelSetting': self.model_setting.as_dict(), + 'modelPredictAlgorithm': json.dumps(self.predict_algorithm)})) + job_param = JobParam(job_info, self.task_parties, self.dataset_id_list) + return job_param + + +class SecureLRTrainingJobContext(JobContext): + def __init__(self, + remote_job_client: WeDPRRemoteJobClient, + storage_entry_point: StorageEntryPoint, + project_id: str, + model_setting: ModelSetting, + dataset: DataContext, + user_config: UserConfig, merge_field: str = 'id'): + super().__init__(remote_job_client, storage_entry_point, + project_id, dataset, user_config) + self.model_setting = model_setting + self.merge_field = merge_field + + def get_job_type(self) -> JobType: + return JobType.LR_TRAINING + + def build(self) -> JobParam: + self.dataset_list = self.dataset.to_model_formort( + self.merge_field, self.result_receiver_id_list) + job_info = JobInfo(job_type=self.get_job_type(), + project_id=self.project_id, + param=json.dumps( + {'dataSetList': self.dataset_list, 'modelSetting': self.model_setting.as_dict()})) + job_param = JobParam(job_info, self.task_parties, self.dataset_id_list) + return job_param + + +class SecureLRPredictJobContext(JobContext): + def __init__(self, + remote_job_client: WeDPRRemoteJobClient, + storage_entry_point: StorageEntryPoint, + project_id: str, + model_setting: ModelSetting, predict_algorithm, + dataset: DataContext, + user_config: UserConfig, + merge_field: str = 'id'): + super().__init__(remote_job_client, storage_entry_point, + project_id, dataset, user_config) + self.model_setting = model_setting + self.merge_field = merge_field + self.predict_algorithm = predict_algorithm + + def get_job_type(self) -> JobType: + return JobType.LR_PREDICTING + + def build(self) -> JobParam: + self.dataset_list = self.dataset.to_model_formort( + self.merge_field, self.result_receiver_id_list) + job_info = JobInfo(job_type=self.get_job_type(), + project_id=self.project_id, + param=json.dumps( + {'dataSetList': self.dataset_list, 'modelSetting': self.model_setting.as_dict(), + 'modelPredictAlgorithm': json.dumps(self.predict_algorithm)})) + job_param = JobParam(job_info, self.task_parties, self.dataset_id_list) + return job_param diff --git a/python/wedpr_ml_toolkit/wedpr_ml_toolkit/context/model_setting.py b/python/wedpr_ml_toolkit/wedpr_ml_toolkit/context/model_setting.py new file mode 100644 index 00000000..dec57e21 --- /dev/null +++ b/python/wedpr_ml_toolkit/wedpr_ml_toolkit/context/model_setting.py @@ -0,0 +1,131 @@ +# -*- coding: utf-8 -*- +from wedpr_ml_toolkit.common.utils import utils +from wedpr_ml_toolkit.common.utils.base_object import BaseObject + + +class PreprocessingSetting(BaseObject): + def __init__(self, model_dict=None): + self.use_psi = utils.get_config_value( + "use_psi", False, model_dict, False) + self.fillna = utils.get_config_value( + "fillna", False, model_dict, False) + self.na_select = float(utils.get_config_value( + "na_select", 1.0, model_dict, False)) + self.filloutlier = utils.get_config_value( + "filloutlier", False, model_dict, False) + self.normalized = utils.get_config_value( + "normalized", False, model_dict, False) + self.standardized = utils.get_config_value( + "standardized", False, model_dict, False) + self.categorical = utils.get_config_value( + "categorical", '', model_dict, False) + self.psi_select_col = utils.get_config_value( + "psi_select_col", '', model_dict, False) + self.psi_select_base = utils.get_config_value( + "psi_select_base", '', model_dict, False) + self.psi_select_base = float(utils.get_config_value( + "psi_select_thresh", 0.3, model_dict, False)) + self.psi_select_bins = int(utils.get_config_value( + "psi_select_bins", 4, model_dict, False)) + self.corr_select = float(utils.get_config_value( + "corr_select", 0, model_dict, False)) + self.use_goss = utils.get_config_value( + "use_goss", False, model_dict, False) + + +class FeatureEngineeringEngineSetting(BaseObject): + def __init__(self, model_dict=None): + self.use_iv = utils.get_config_value( + "use_iv", False, model_dict, False) + self.group_num = int(utils.get_config_value( + "group_num", 4, model_dict, False)) + self.iv_thresh = float(utils.get_config_value( + "iv_thresh", 0.1, model_dict, False)) + + +class CommonModelSetting(BaseObject): + def __init__(self, model_dict=None): + self.learning_rate = float(utils.get_config_value( + "learning_rate", 0.1, model_dict, False)) + + self.eval_set_column = utils.get_config_value( + "eval_set_column", "", model_dict, False) + self.train_set_value = utils.get_config_value( + "train_set_value", "", model_dict, False) + self.eval_set_value = utils.get_config_value( + "eval_set_value", "", model_dict, False) + self.verbose_eval = int(utils.get_config_value( + "verbose_eval", 1, model_dict, False)) + self.silent = utils.get_config_value( + "silent", False, model_dict, False) + self.train_features = utils.get_config_value( + "train_features", "", model_dict, False) + random_state_str = utils.get_config_value( + "random_state", "", model_dict, False) + if len(random_state_str) > 0: + self.random_state = int(random_state_str) + self.n_jobs = int(utils.get_config_value( + "n_jobs", 0, model_dict, False)) + + +class SecureLGBMSetting(CommonModelSetting, BaseObject): + def __init__(self, model_dict=None): + super().__init__(model_dict) + self.test_size = float(utils.get_config_value( + "test_dataset_percentage", 0.3, model_dict, False)) + self.num_trees = int(utils.get_config_value( + "num_trees", 6, model_dict, False)) + self.max_depth = int(utils.get_config_value( + "max_depth", 3, model_dict, False)) + self.max_bin = int(utils.get_config_value( + "max_bin", 4, model_dict, False)) + + self.subsample = float(utils.get_config_value( + "subsample", 1, model_dict, False)) + self.colsample_bytree = float(utils.get_config_value( + "colsample_bytree", 1, model_dict, False)) + self.colsample_bylevel = float(utils.get_config_value( + "colsample_bylevel", 1, model_dict, False)) + self.reg_alpha = float(utils.get_config_value( + "reg_alpha", 0, model_dict, False)) + self.reg_lambda = float(utils.get_config_value( + "reg_lambda", 1, model_dict, False)) + self.gamma = float(utils.get_config_value( + "gamma", 0, model_dict, False)) + self.min_child_weight = float(utils.get_config_value( + "min_child_weight", 0.0, model_dict, False)) + self.min_child_samples = int(utils.get_config_value( + "min_child_samples", 10, model_dict, False)) + self.seed = int(utils.get_config_value( + "seed", 2024, model_dict, False)) + self.early_stopping_rounds = int(utils.get_config_value( + "early_stopping_rounds", 5, model_dict, False)) + self.eval_metric = utils.get_config_value( + "eval_metric", "auc", model_dict, False) + self.threads = int(utils.get_config_value( + "threads", 8, model_dict, False)) + self.one_hot = utils.get_config_value( + "one_hot", 0, model_dict, False) + + +class SecureLRSetting(CommonModelSetting, BaseObject): + def __init__(self, model_dict=None): + super().__init__(model_dict) + self.feature_rate = float(utils.get_config_value( + "feature_rate", 1.0, model_dict, False)) + self.batch_size = int(utils.get_config_value( + "batch_size", 16, model_dict, False)) + self.epochs = int(utils.get_config_value( + "epochs", 3, model_dict, False)) + + +class ModelSetting(PreprocessingSetting, FeatureEngineeringEngineSetting, SecureLGBMSetting, SecureLRSetting, BaseObject): + def __init__(self, model_dict=None): + # init PreprocessingSetting + super().__init__(model_dict) + # init FeatureEngineeringEngineSetting + FeatureEngineeringEngineSetting.__init__(self, model_dict) + # init SecureLGBMSetting + SecureLGBMSetting.__init__(self, model_dict) + # init SecureLRSetting + SecureLRSetting.__init__(self, model_dict) diff --git a/python/wedpr_ml_toolkit/wedpr_ml_toolkit/context/result/__init__.py b/python/wedpr_ml_toolkit/wedpr_ml_toolkit/context/result/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/python/wedpr_ml_toolkit/wedpr_ml_toolkit/context/result/fe_result_context.py b/python/wedpr_ml_toolkit/wedpr_ml_toolkit/context/result/fe_result_context.py new file mode 100644 index 00000000..a7ad3b16 --- /dev/null +++ b/python/wedpr_ml_toolkit/wedpr_ml_toolkit/context/result/fe_result_context.py @@ -0,0 +1,30 @@ +import os + +from wedpr_ml_toolkit.context.data_context import DataContext +from wedpr_ml_toolkit.common.utils.constant import Constant +from wedpr_ml_toolkit.context.result.result_context import ResultContext +from wedpr_ml_toolkit.context.job_context import JobContext +from wedpr_ml_toolkit.transport.wedpr_remote_job_client import JobDetailResponse +from wedpr_ml_toolkit.transport.wedpr_remote_dataset_client import DatasetMeta +from wedpr_ml_toolkit.context.dataset_context import DatasetContext + + +class PreprocessingResultContext(ResultContext): + def __init__(self, job_context: JobContext, job_result_detail: JobDetailResponse): + super().__init__(job_context, job_result_detail) + self.preprocessing_dataset = self._generate_result_dataset_( + self.preprocessing_result_path) + + def __repr__(self): + return f"preprocessing_dataset: {self.preprocessing_dataset}" + + +class FeResultContext(ResultContext): + + def __init__(self, job_context: JobContext, job_result_detail: JobDetailResponse): + super().__init__(job_context, job_result_detail) + self.fe_dataset = self._generate_result_dataset_( + self.fe_result_file_path) + + def __repr__(self): + return f"fe_dataset: {self.fe_dataset}" diff --git a/python/wedpr_ml_toolkit/wedpr_ml_toolkit/context/result/model_result_context.py b/python/wedpr_ml_toolkit/wedpr_ml_toolkit/context/result/model_result_context.py new file mode 100644 index 00000000..c93d9606 --- /dev/null +++ b/python/wedpr_ml_toolkit/wedpr_ml_toolkit/context/result/model_result_context.py @@ -0,0 +1,60 @@ +from wedpr_ml_toolkit.context.result.result_context import ResultContext +from wedpr_ml_toolkit.context.result.fe_result_context import PreprocessingResultContext +from wedpr_ml_toolkit.context.result.fe_result_context import FeResultContext +from wedpr_ml_toolkit.context.job_context import JobContext +from wedpr_ml_toolkit.transport.wedpr_remote_job_client import JobDetailResponse +from wedpr_ml_toolkit.context.dataset_context import DatasetContext + + +class ModelResultContext(PreprocessingResultContext, FeResultContext): + def __init__(self, job_context: JobContext, job_result_detail: JobDetailResponse): + PreprocessingResultContext.__init__( + self, job_context, job_result_detail) + FeResultContext.__init__(self, job_context, job_result_detail) + + +class TrainResultContext(ModelResultContext): + def __init__(self, job_context: JobContext, job_result_detail: JobDetailResponse): + ModelResultContext.__init__(self, job_context, job_result_detail) + # train_model_output + self.train_result_dataset = self._generate_result_dataset_( + self.job_result_detail.modelResultDetail['ModelResult']['trainResultPath']) + # test_model_output + self.test_result_dataset = self._generate_result_dataset_( + self.job_result_detail.modelResultDetail['ModelResult']['testResultPath']) + # xgb_tree.json + self.model_result_dataset = self._generate_result_dataset_( + self.model_result_path) + # model_enc.kpl + self.model_dataset = self._generate_result_dataset_(self.model_path) + # mpc_xgb_evaluation_table.csv + self.evaluation_dataset = self._generate_result_dataset_( + self.evaluation_table_path) + # xgb_result_column_info_selected.csv + self.feature_selection_dataset = self._generate_result_dataset_( + self.feature_selection_file_path) + # xgb_result_feature_importance_table.csv + self.feature_importance_dataset = self._generate_result_dataset_( + self.feature_importance_result_path) + + def __repr__(self): + return f"train_result_dataset: {self.train_result_dataset}," \ + f"test_result_dataset: {self.test_result_dataset}," \ + f"model_result_dataset: {self.model_result_dataset}," \ + f"model_dataset: {self.model_dataset}," \ + f"evaluation_dataset: {self.evaluation_dataset}," \ + f"feature_selection_dataset: {self.feature_selection_dataset}," \ + f"feature_importance_dataset: {self.feature_importance_dataset}," \ + f"preprocessing_dataset: {self.preprocessing_dataset}," \ + f"fe_dataset: {self.fe_dataset}," \ + f"psi_dataset: {self.psi_result_file_path}" + + +class PredictResultContext(ResultContext): + def __init__(self, job_context: JobContext, job_result_detail: JobDetailResponse): + super().__init__(job_context, job_result_detail) + self.model_result_dataset = self._generate_result_dataset_( + self.job_result_detail.modelResultDetail['ModelResult']['testResultPath']) + + def __repr__(self): + return f"model_result_dataset: {self.model_result_dataset}" diff --git a/python/wedpr_ml_toolkit/wedpr_ml_toolkit/context/result/psi_result_context.py b/python/wedpr_ml_toolkit/wedpr_ml_toolkit/context/result/psi_result_context.py new file mode 100644 index 00000000..fbc24725 --- /dev/null +++ b/python/wedpr_ml_toolkit/wedpr_ml_toolkit/context/result/psi_result_context.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +from wedpr_ml_toolkit.context.job_context import JobContext +from wedpr_ml_toolkit.context.dataset_context import DatasetContext +from wedpr_ml_toolkit.context.result.result_context import ResultContext +from wedpr_ml_toolkit.transport.wedpr_remote_job_client import JobDetailResponse + + +class PSIResultContext(ResultContext): + def __init__(self, job_context: JobContext, job_result_detail: JobDetailResponse): + super().__init__(job_context, job_result_detail) + self.result_dataset = self._generate_result_dataset_( + self.job_result_detail.resultFileInfo['path']) + + def __repr__(self): + return f"result_dataset: {self.result_dataset}" diff --git a/python/wedpr_ml_toolkit/wedpr_ml_toolkit/context/result/result_context.py b/python/wedpr_ml_toolkit/wedpr_ml_toolkit/context/result/result_context.py new file mode 100644 index 00000000..e580d018 --- /dev/null +++ b/python/wedpr_ml_toolkit/wedpr_ml_toolkit/context/result/result_context.py @@ -0,0 +1,64 @@ +# -*- coding: utf-8 -*- +from wedpr_ml_toolkit.context.job_context import JobContext +from wedpr_ml_toolkit.common.utils.constant import Constant +from abc import abstractmethod +from wedpr_ml_toolkit.transport.wedpr_remote_job_client import JobDetailResponse +import os +from wedpr_ml_toolkit.transport.wedpr_remote_dataset_client import DatasetMeta +from wedpr_ml_toolkit.context.data_context import DatasetContext + + +class ResultContext: + def __init__(self, job_context: JobContext, job_result_detail: JobDetailResponse): + self.check_and_get_job_type(job_context, job_result_detail) + self.job_context = job_context + self.job_result_detail = job_result_detail + self.job_id = self.job_result_detail.job_object.id + # init the result file path + self.model_base_dir = os.path.join( + "share", "jobs", "model", self.job_id) + + self.feature_bin_file_path = os.path.join( + self.model_base_dir, Constant.FEATURE_BIN_FILE) + self.fe_result_file_path = os.path.join( + self.model_base_dir, Constant.WOE_IV_FILE) + self.model_result_path = os.path.join( + self.model_base_dir, Constant.MODEL_RESULT_FILE) + self.preprocessing_result_path = os.path.join( + self.model_base_dir, Constant.PREPROCESSING_RESULT_FILE) + self.feature_importance_result_path = os.path.join( + self.model_base_dir, Constant.FEATURE_IMPORTANCE_FILE) + self.evaluation_table_path = os.path.join( + self.model_base_dir, Constant.EVALUATION_TABLE_FILE) + self.feature_selection_file_path = os.path.join( + self.model_base_dir, Constant.FEATURE_SELECTION_FILE) + self.model_path = os.path.join( + self.model_base_dir, Constant.MODEL_FILE) + self.woe_iv_path = os.path.join( + self.model_base_dir, Constant.WOE_IV_FILE) + + self.psi_result_file_path = os.path.join( + self.job_context.user_config.user, "share", "psi", f"psi-{self.job_id}") + + @staticmethod + def check_and_get_job_type(job_context: JobContext, job_result_detail: JobDetailResponse): + if job_context is None: + raise Exception( + "Invalid empty job_context!") + if job_result_detail is None: + raise Exception("Invalid empty job result!") + if job_result_detail.job_object is None: + raise Exception( + "Invalid job result: must contain the job information!") + if job_result_detail.job_object.job_status.run_failed(): + raise Exception( + f"RunFailed job can't construct the result context!") + return job_result_detail.job_object.jobType + + def _generate_result_dataset_(self, dataset_file_path): + dataset_meta = DatasetMeta(user=self.job_context.user_config.user, + agency=self.job_context.user_config.agency_name, + file_path=dataset_file_path) + return DatasetContext(storage_entrypoint=self.job_context.storage_entry_point, + storage_workspace=None, + dataset_meta=dataset_meta) diff --git a/python/wedpr_ml_toolkit/wedpr_ml_toolkit/transport/__init__.py b/python/wedpr_ml_toolkit/wedpr_ml_toolkit/transport/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/python/wedpr_ml_toolkit/wedpr_ml_toolkit/transport/credential_generator.py b/python/wedpr_ml_toolkit/wedpr_ml_toolkit/transport/credential_generator.py new file mode 100644 index 00000000..de028bcd --- /dev/null +++ b/python/wedpr_ml_toolkit/wedpr_ml_toolkit/transport/credential_generator.py @@ -0,0 +1,58 @@ +# -*- coding: utf-8 -*- +import hashlib +from wedpr_ml_toolkit.common.utils import utils +from datetime import datetime + + +class CredentialInfo: + ACCESS_ID_KEY = "accessKeyID" + NONCE_KEY = "nonce" + TIMESTAMP_KEY = "timestamp" + SIGNATURE_KEY = "signature" + HASH_ALGORITHM_KEY = "hashAlgorithm" + + def __init__(self, access_key_id: str, nonce: str, timestamp: int, signature: str): + self.access_key_id = access_key_id + self.nonce = nonce + self.timestamp = timestamp + self.signature = signature + # use SHA3-256 algorithm + self.hash_algorithm = "SHA3-256" + + def to_dict(self): + result = {} + result.update({CredentialInfo.ACCESS_ID_KEY: self.access_key_id}) + result.update({CredentialInfo.NONCE_KEY: self.nonce}) + result.update({CredentialInfo.TIMESTAMP_KEY: self.timestamp}) + result.update({CredentialInfo.SIGNATURE_KEY: self.signature}) + result.update({CredentialInfo.HASH_ALGORITHM_KEY: self.hash_algorithm}) + return result + + +class CredentialGenerator: + def __init__(self, access_key_id: str, access_key_secret: str, nonce_len=5): + self.access_key_id = access_key_id + self.access_key_secret = access_key_secret + self.nonce_len = nonce_len + + def generate_credential(self) -> CredentialInfo: + nonce = utils.generate_nonce(self.nonce_len) + # convert to the million-seconds timestamp + timestamp = int(datetime.now().timestamp() * 1000) + # generate the signature + signature = CredentialGenerator.generate_signature( + self.access_key_id, self.access_key_secret, nonce, timestamp) + return CredentialInfo(self.access_key_id, nonce, timestamp, signature) + + @staticmethod + def generate_signature(access_key_id, access_key_secret, nonce, timestamp) -> str: + anti_replay_info_hash = hashlib.sha3_256() + # hash(access_key_id + nonce + timestamp) + anti_replay_info_hash.update( + bytes(access_key_id + nonce + str(timestamp), encoding='utf-8')) + # hash(anti_replay_info + access_key_secret) + signature_hash = hashlib.sha3_256() + signature_hash.update( + bytes(anti_replay_info_hash.hexdigest(), encoding='utf-8')) + signature_hash.update(bytes(access_key_secret, encoding='utf-8')) + return signature_hash.hexdigest() diff --git a/python/wedpr_ml_toolkit/wedpr_ml_toolkit/transport/storage_entrypoint.py b/python/wedpr_ml_toolkit/wedpr_ml_toolkit/transport/storage_entrypoint.py new file mode 100644 index 00000000..dd750102 --- /dev/null +++ b/python/wedpr_ml_toolkit/wedpr_ml_toolkit/transport/storage_entrypoint.py @@ -0,0 +1,47 @@ +import pandas as pd +import io + +from wedpr_ml_toolkit.common.utils.hdfs_storage_impl import HdfsStorageImpl +from wedpr_ml_toolkit.config.wedpr_ml_config import StorageConfig +from wedpr_ml_toolkit.config.wedpr_ml_config import UserConfig + + +class StorageEntryPoint: + def __init__(self, storage_config: StorageConfig): + self.storage_config = storage_config + self.storage_client = HdfsStorageImpl(self.storage_config) + + def upload_bytes(self, data, hdfs_path): + self.storage_client.save_data(data, hdfs_path) + + def upload(self, dataframe, hdfs_path): + """ + 上传Pandas DataFrame到HDFS + :param dataframe: 要上传的Pandas DataFrame + :param hdfs_path: HDFS目标路径 + :return: 响应信息 + """ + # 将DataFrame转换为CSV格式 + csv_buffer = io.StringIO() + dataframe.to_csv(csv_buffer, index=False) + self.storage_client.save_data(csv_buffer.getvalue(), hdfs_path) + return + + def download(self, hdfs_path, header=None): + """ + 从HDFS下载数据并返回为Pandas DataFrame + :param hdfs_path: HDFS文件路径 + :return: Pandas DataFrame + """ + content = self.storage_client.get_data(hdfs_path) + dataframe = pd.read_csv(io.BytesIO(content), header=header) + return dataframe + + def download_byte(self, hdfs_path): + """ + 从HDFS下载数据 + :param hdfs_path: HDFS文件路径 + :return: text + """ + content = self.storage_client.get_data(hdfs_path) + return content diff --git a/python/wedpr_ml_toolkit/wedpr_ml_toolkit/transport/wedpr_entrypoint.py b/python/wedpr_ml_toolkit/wedpr_ml_toolkit/transport/wedpr_entrypoint.py new file mode 100644 index 00000000..d711528b --- /dev/null +++ b/python/wedpr_ml_toolkit/wedpr_ml_toolkit/transport/wedpr_entrypoint.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +import requests +from wedpr_ml_toolkit.transport.credential_generator import CredentialGenerator +from wedpr_ml_toolkit.config.wedpr_ml_config import HttpConfig +from wedpr_ml_toolkit.common.utils.constant import Constant +import json + + +class LoadBanlancer: + def __init__(self, remote_entrypoints: []): + if remote_entrypoints == None or len(remote_entrypoints) == 0: + raise Exception(f"Must define the wedpr entrypoints") + self.remote_entrypoints = remote_entrypoints + self.round_robin_idx = 0 + + # choose with round-robin policy + def select(self, uri_path: str): + selected_idx = self.round_robin_idx + self.round_robin_idx += 1 + selected_entrypoint = self.remote_entrypoints[selected_idx % len( + self.remote_entrypoints)] + return f"{selected_entrypoint}/{uri_path}" + + +class WeDPREntryPoint: + def __init__(self, access_key_id: str, access_key_secret: str, remote_entrypoints: [], http_config: HttpConfig, nonce_len: int = 5): + self.credential_generator = CredentialGenerator( + access_key_id, access_key_secret, nonce_len) + self.http_config = http_config + self.loadbalancer = LoadBanlancer(remote_entrypoints) + + def send_request(self, is_post: bool, uri, params, headers, data): + credential_info = self.credential_generator.generate_credential() + if params is None: + params = {} + params.update(credential_info.to_dict()) + url = self.loadbalancer.select(uri) + if not headers: + headers = {'content-type': 'application/json'} + response = None + if is_post: + response = requests.post(url, data=data, params=params, headers=headers, + timeout=self.http_config.timeout_seconds) + else: + response = requests.get(url, params=params, headers=headers, + timeout=self.http_config.timeout_seconds) + if response.status_code != Constant.HTTP_STATUS_OK: + raise Exception( + f"send post request to {url} failed, response: {response.text}") + # parse the result + return json.loads(response.text) diff --git a/python/wedpr_ml_toolkit/wedpr_ml_toolkit/transport/wedpr_remote_dataset_client.py b/python/wedpr_ml_toolkit/wedpr_ml_toolkit/transport/wedpr_remote_dataset_client.py new file mode 100644 index 00000000..9c70e3e1 --- /dev/null +++ b/python/wedpr_ml_toolkit/wedpr_ml_toolkit/transport/wedpr_remote_dataset_client.py @@ -0,0 +1,109 @@ +# -*- coding: utf-8 -*- +from wedpr_ml_toolkit.common.utils.base_object import BaseObject +from wedpr_ml_toolkit.common.utils.base_object import WeDPRResponse +from wedpr_ml_toolkit.transport.wedpr_entrypoint import WeDPREntryPoint +from wedpr_ml_toolkit.config.wedpr_ml_config import DatasetConfig +from wedpr_ml_toolkit.config.wedpr_ml_config import HttpConfig +from wedpr_ml_toolkit.config.wedpr_ml_config import AuthConfig +from wedpr_ml_toolkit.config.wedpr_ml_config import UserConfig +from typing import Any +import json + + +class DatasetMeta(BaseObject): + def __init__(self, dataset_id: str = None, + dataset_label: str = None, + dataset_title: str = None, + dataset_desc: str = None, + dataset_fields: str = None, + dataset_hash: str = None, + dataset_size: int = -1, + dataset_record_count: int = -1, + dataset_column_count: int = -1, + dataset_storage_type: str = None, + dataset_storage_path: str = None, + datasource_type: str = None, + datasource_meta: str = None, + agency: str = None, + user: str = None, + status: str = None, + status_desc: str = None, + file_path: str = None, + user_config: UserConfig = None, + **params: Any): + self.datasetId = dataset_id + self.datasetLabel = dataset_label + self.datasetTitle = dataset_title + self.datasetDesc = dataset_desc + self.datasetFields = dataset_fields + self.datasetHash = dataset_hash + self.datasetSize = dataset_size + self.recordCount = dataset_record_count + self.columnCount = dataset_column_count + self.datasetStorageType = dataset_storage_type + self.datasetStoragePath = dataset_storage_path + self.dataSourceType = datasource_type + self.dataSourceMeta = datasource_meta + self.ownerAgencyName = agency + self.ownerUserName = user + self.user_config = user_config + if self.user_config is not None: + self.ownerAgencyName = self.user_config.agency_name + self.ownerUserName = self.user_config.user + self.status = status + self.statusDesc = status_desc + self.file_path = file_path + self.set_params(**params) + if self.datasetStoragePath is not None: + dataset_storage_path_dict = json.loads(self.datasetStoragePath) + if "filePath" in dataset_storage_path_dict.keys(): + self.file_path = dataset_storage_path_dict.get("filePath") + + def __repr__(self): + return f"id: {self.datasetId}, " \ + f"file_path, {self.file_path}, " \ + f"datasetTitle: {self.datasetTitle}, datasetFields: {self.datasetFields}, " \ + f"datasetSize: {self.datasetSize}, recordCount: {self.recordCount}," \ + f"columnCount: {self.columnCount}, datasetStorageType: {self.datasetStorageType}, " \ + f"user: {self.ownerUserName}, " \ + f"agency: {self.ownerAgencyName}" + + +class WeDPRDatasetClient(WeDPREntryPoint, BaseObject): + def __init__(self, http_config: HttpConfig, auth_config: AuthConfig, dataset_config: DatasetConfig): + if auth_config is None: + raise Exception("Must define the auth config!") + if http_config is None: + raise Exception("Must define the http config") + super().__init__(auth_config.access_key_id, auth_config.access_key_secret, + auth_config.get_remote_entrypoints_list(), http_config, auth_config.nonce_len) + self.auth_config = auth_config + self.http_config = http_config + self.dataset_config = dataset_config + + def query_dataset(self, dataset_id) -> DatasetMeta: + params = {} + params.update({"datasetId": dataset_id}) + response_dict = self.send_request( + False, self.dataset_config.query_dataset_uri, params, None, None) + wedpr_response = WeDPRResponse(**response_dict) + # query the dataset failed + if wedpr_response.success() is False: + raise Exception( + f"Query dataset information failed for {wedpr_response.msg}, dataset_id: {dataset_id}") + # query success, deserialize to DatasetMeta + return DatasetMeta(**wedpr_response.data) + + def update_dataset(self, dataset_meta: DatasetMeta): + if dataset_meta.datasetId is None or len(dataset_meta.datasetId) == 0: + raise Exception( + f"Invalid dataset meta {dataset_meta}, must define the datasetId") + response_dict = self.send_request(is_post=True, + uri=self.dataset_config.update_dataset_uri, + headers=None, + params=None, + data=json.dumps(dataset_meta.as_dict())) + wedpr_response = WeDPRResponse(**response_dict) + if wedpr_response.success() is False: + raise Exception( + f"Update dataset meta {dataset_meta} failed, msg: {wedpr_response.msg}") diff --git a/python/wedpr_ml_toolkit/wedpr_ml_toolkit/transport/wedpr_remote_job_client.py b/python/wedpr_ml_toolkit/wedpr_ml_toolkit/transport/wedpr_remote_job_client.py new file mode 100644 index 00000000..32e59440 --- /dev/null +++ b/python/wedpr_ml_toolkit/wedpr_ml_toolkit/transport/wedpr_remote_job_client.py @@ -0,0 +1,245 @@ +from wedpr_ml_toolkit.transport.wedpr_entrypoint import WeDPREntryPoint +from wedpr_ml_toolkit.common.utils.constant import Constant +from wedpr_ml_toolkit.config.wedpr_ml_config import AuthConfig +from wedpr_ml_toolkit.config.wedpr_ml_config import JobConfig +from wedpr_ml_toolkit.config.wedpr_ml_config import HttpConfig +from wedpr_ml_toolkit.common.utils.base_object import BaseObject +import json +import time +from enum import Enum +from typing import Any + + +class JobType(Enum): + PSI = "PSI", + PREPROCESSING = "PREPROCESSING", + FEATURE_ENGINEERING = "FEATURE_ENGINEERING", + XGB_TRAINING = "XGB_TRAINING", + XGB_PREDICTING = "XGB_PREDICTING" + LR_TRAINING = "LR_TRAINING", + LR_PREDICTING = "LR_PREDICTING" + + +class ModelType(Enum): + XGB_MODEL_SETTING = "XGB_MODEL_SETTING", + LR_MODEL_SETTING = "LR_MODEL_SETTING", + + +class JobStatus(Enum): + Submitted = "Submitted", + Running = "Running", + RunFailed = "RunFailed", + RunSuccess = "RunSuccess", + WaitToRetry = "WaitToRetry", + WaitToKill = "WaitToKill", + Killing = "Killing", + Killed = "Killed", + ChainInProgress = "ChainInProgress" + + def run_success(self) -> bool: + if self.name == JobStatus.RunSuccess.name: + return True + return False + + def run_failed(self) -> bool: + if self.name == JobStatus.RunFailed.name: + return True + return False + + def scheduling(self) -> bool: + return (not self.run_success()) and (not self.run_failed()) + + @staticmethod + def get_job_status(job_status_tr: str): + try: + if job_status_tr is None or len(job_status_tr) == 0: + return None + return JobStatus[job_status_tr] + except: + return None + + +class JobInfo(BaseObject): + def __init__(self, job_id: str = None, + job_type: JobType = None, + project_id: str = None, + param: str = None, **params: Any): + if job_id is not None: + self.id = job_id + self.name = None + self.owner = None + self.ownerAgency = None + self.jobType: str = None + if job_type is not None: + self.jobType = job_type.name + self.parties = None + self.projectId = project_id + self.param = param + self.status = None + self.result = None + self.createTime = None + self.lastUpdateTime = None + self.set_params(**params) + self.job_status: JobStatus = JobStatus.get_job_status(self.status) + + def __repr__(self): + return f"job_id: {self.id}, owner: {self.owner}, ownerAgency: {self.ownerAgency}, " \ + f"jobType: {self.jobType}, status: {self.status}" + + +class JobParam: + def __init__(self, job_info: JobInfo, task_parities, dataset_list): + self.job = job_info.__dict__ + self.taskParties = task_parities + self.datasetList = dataset_list + + +class WeDPRResponse(BaseObject): + def __init__(self, **params: Any): + self.code = None + self.msg = None + self.data = None + self.set_params(**params) + + def success(self): + return self.code is not None and self.code == 0 + + +class QueryJobRequest(BaseObject): + def __init__(self, job_info: JobInfo): + self.job = job_info + + def as_dict(self): + result = {} + if self.job is None: + return result + result.update({"job": self.job.as_dict()}) + return result + + def __repr__(self): + return f"job: {self.job}" + + +class JobListResponse(BaseObject): + def __init__(self, **params: Any): + self.jobs = [] + self.job_object_list = [] + self.total = None + self.set_params(**params) + for job_item in self.jobs: + self.job_object_list.append(JobInfo(**job_item)) + + def get_queried_job(self) -> JobInfo: + if len(self.job_object_list) == 0: + return None + return self.job_object_list[0] + + +class JobDetailResponse(BaseObject): + def __init__(self, job_info: JobInfo = None, **params: Any): + self.job: dict = None + self.job_object: JobInfo = job_info + self.modelResultDetail: dict = None + self.resultFileInfo: dict = None + self.model: dict = None + self.model_predict_algorithm = {} + self.set_params(**params) + if self.job_object is None and self.job is not None: + self.job_object = JobInfo(**self.job) + # generate the model_predict algorithm + if self.model is not None: + self.model_predict_algorithm.update({"setting": self.model}) + + def __repr__(self): + return f"job: {self.job_object}, modelResultDetail: {self.modelResultDetail}, " \ + f"resultFileInfo: {self.resultFileInfo}, model: {self.model}" + + +class JobDetailRequest(BaseObject): + def __init__(self, job_id=None, + fetch_job_detail=True, + fetch_job_result=True, + fetch_log=False): + self.jobID = job_id + self.fetchJobDetail = fetch_job_detail + self.fetchJobResult = fetch_job_result + self.fetchLog = fetch_log + + +class WeDPRRemoteJobClient(WeDPREntryPoint, BaseObject): + def __init__(self, http_config: HttpConfig, auth_config: AuthConfig, job_config: JobConfig): + if auth_config is None: + raise Exception("Must define the auth config!") + if job_config is None: + raise Exception("Must define the job config") + super().__init__(auth_config.access_key_id, auth_config.access_key_secret, + auth_config.get_remote_entrypoints_list(), http_config, auth_config.nonce_len) + self.auth_config = auth_config + self.job_config = job_config + + def get_auth_config(self): + return self.auth_config + + def get_job_config(self): + return self.job_config + + def submit_job(self, job_params: JobParam) -> WeDPRResponse: + wedpr_response = self.send_request(True, + self.job_config.submit_job_uri, None, None, json.dumps(job_params.__dict__)) + submit_result = WeDPRResponse(**wedpr_response) + # return the job_id + if submit_result.success(): + return submit_result.data + raise Exception( + f"submit_job failed, code: {submit_result.code}, msg: {submit_result.msg}") + + def query_job_detail(self, job_id, block_until_finish) -> JobDetailResponse: + job_result = self.poll_job_result(job_id, block_until_finish) + # failed case + if job_result == None or job_result.job_status == None \ + or (not job_result.job_status.run_success()): + return JobDetailResponse(job_info=job_result, params=None) + # success case, query the job detail + job_detail_requests = JobDetailRequest(job_id) + response_dict = self.execute_with_retry(self.send_request, + self.job_config.max_retries, + self.job_config.retry_delay_s, + True, + self.job_config.query_job_detail_uri, + None, + None, json.dumps(job_detail_requests.as_dict())) + wedpr_response = WeDPRResponse(**response_dict) + if not wedpr_response.success(): + raise Exception( + f"query_job_detail exception, job: {job_id}, " + f"code: {wedpr_response.code}, msg: {wedpr_response.msg}") + return JobDetailResponse(**(wedpr_response.data)) + + def poll_job_result(self, job_id, block_until_finish) -> JobInfo: + while True: + query_condition = JobInfo(job_id=job_id) + response_dict = self.execute_with_retry(self.send_request, + self.job_config.max_retries, + self.job_config.retry_delay_s, + True, + self.job_config.query_job_status_uri, + None, None, + json.dumps(QueryJobRequest(job_info=query_condition).as_dict())) + wedpr_response = WeDPRResponse(**response_dict) + if not wedpr_response.success(): + raise Exception( + f"poll_job_result failed, job_id: {job_id}, code: {wedpr_response.code}, msg: {wedpr_response.msg}") + # check the result + result = JobListResponse(**(wedpr_response.data)) + result_job = result.get_queried_job() + if result_job is None: + raise Exception( + f"poll_job_result for the queried job {job_id} not exists!") + # run finished + if result_job.job_status.run_success() or result_job.job_status.run_failed(): + return result_job + # wait to finish + if block_until_finish: + time.sleep(self.job_config.polling_interval_s) + else: + return None diff --git a/python/wedpr_ml_toolkit/wedpr_ml_toolkit/wedpr_ml_toolkit.py b/python/wedpr_ml_toolkit/wedpr_ml_toolkit/wedpr_ml_toolkit.py new file mode 100644 index 00000000..ab2383c3 --- /dev/null +++ b/python/wedpr_ml_toolkit/wedpr_ml_toolkit/wedpr_ml_toolkit.py @@ -0,0 +1,98 @@ +# -*- coding: utf-8 -*- + +from wedpr_ml_toolkit.config.wedpr_ml_config import WeDPRMlConfig +from wedpr_ml_toolkit.transport.wedpr_remote_job_client import WeDPRRemoteJobClient +from wedpr_ml_toolkit.transport.wedpr_remote_job_client import JobInfo +from wedpr_ml_toolkit.transport.storage_entrypoint import StorageEntryPoint +from wedpr_ml_toolkit.transport.wedpr_remote_dataset_client import WeDPRDatasetClient +from wedpr_ml_toolkit.context.job_context import JobType +from wedpr_ml_toolkit.context.job_context import PSIJobContext +from wedpr_ml_toolkit.context.job_context import PreprocessingJobContext +from wedpr_ml_toolkit.context.job_context import FeatureEngineeringJobContext +from wedpr_ml_toolkit.context.job_context import SecureLGBMPredictJobContext +from wedpr_ml_toolkit.context.job_context import SecureLGBMTrainingJobContext +from wedpr_ml_toolkit.context.job_context import SecureLRPredictJobContext +from wedpr_ml_toolkit.context.job_context import SecureLRTrainingJobContext +from wedpr_ml_toolkit.context.job_context import JobContext +from wedpr_ml_toolkit.context.data_context import DataContext +from wedpr_ml_toolkit.context.model_setting import ModelSetting +from wedpr_ml_toolkit.context.result.result_context import ResultContext +from wedpr_ml_toolkit.context.result.psi_result_context import PSIResultContext +from wedpr_ml_toolkit.context.result.fe_result_context import FeResultContext +from wedpr_ml_toolkit.context.result.fe_result_context import PreprocessingResultContext +from wedpr_ml_toolkit.context.result.model_result_context import TrainResultContext +from wedpr_ml_toolkit.context.result.model_result_context import PredictResultContext +from wedpr_ml_toolkit.transport.wedpr_remote_job_client import JobDetailResponse + + +class WeDPRMlToolkit: + def __init__(self, config: WeDPRMlConfig): + self.config = config + self.remote_job_client = WeDPRRemoteJobClient( + self.config.http_config, self.config.auth_config, self.config.job_config) + self.dataset_client = WeDPRDatasetClient(http_config=self.config.http_config, + auth_config=self.config.auth_config, + dataset_config=self.config.dataset_config) + self.storage_entry_point = StorageEntryPoint( + self.config.storage_config) + + def get_config(self) -> WeDPRMlConfig: + return self.config + + def get_dataset_client(self) -> WeDPRDatasetClient: + return self.dataset_client + + def get_remote_job_client(self) -> WeDPRRemoteJobClient: + return self.remote_job_client + + def get_storage_entry_point(self) -> StorageEntryPoint: + return self.storage_entry_point + + def submit(self, job_param): + return self.remote_job_client.submit_job(job_param) + + def query_job_status(self, job_id, block_until_finish=False) -> JobInfo: + return self.remote_job_client.poll_job_result(job_id, block_until_finish) + + def query_job_detail(self, job_id, block_until_finish=False) -> JobDetailResponse: + return self.remote_job_client.query_job_detail(job_id, block_until_finish) + + def build_result_context(self, job_context: JobContext, job_result_detail: JobDetailResponse): + job_type = ResultContext.check_and_get_job_type( + job_context, job_result_detail) + if job_type == JobType.PSI.name: + return PSIResultContext(job_context, job_result_detail) + if job_type == JobType.PREPROCESSING.name: + return PreprocessingResultContext(job_context, job_result_detail) + if job_type == JobType.FEATURE_ENGINEERING.name: + return FeResultContext(job_context, job_result_detail) + if job_type == JobType.XGB_TRAINING.name or job_type == JobType.LR_TRAINING.name: + return TrainResultContext(job_context, job_result_detail) + if job_type == JobType.XGB_PREDICTING.name or job_type == JobType.LR_PREDICTING.name: + return PredictResultContext(job_context, job_result_detail) + raise Exception(f"Unsupported job type: {job_type}") + + def build_job_context(self, job_type: JobType, project_id: str, dataset: DataContext, model_setting: ModelSetting = None, + id_fields='id', predict_algorithm=None): + if job_type == JobType.PSI: + return PSIJobContext(self.remote_job_client, self.storage_entry_point, project_id, dataset, + self.config.user_config, id_fields) + if job_type == JobType.PREPROCESSING: + return PreprocessingJobContext(self.remote_job_client, self.storage_entry_point, project_id, + model_setting, dataset, self.config.user_config, id_fields) + if job_type == JobType.FEATURE_ENGINEERING: + return FeatureEngineeringJobContext(self.remote_job_client, self.storage_entry_point, project_id, + model_setting, dataset, self.config.user_config, id_fields) + if job_type == JobType.XGB_TRAINING: + return SecureLGBMTrainingJobContext(self.remote_job_client, self.storage_entry_point, project_id, + model_setting, dataset, self.config.user_config, id_fields) + if job_type == JobType.XGB_PREDICTING: + return SecureLGBMPredictJobContext(self.remote_job_client, self.storage_entry_point, project_id, + model_setting, predict_algorithm, dataset, self.config.user_config, id_fields) + if job_type == JobType.LR_TRAINING: + return SecureLRTrainingJobContext(self.remote_job_client, self.storage_entry_point, project_id, + model_setting, dataset, self.config.user_config, id_fields) + if job_type == JobType.LR_PREDICTING: + return SecureLRPredictJobContext(self.remote_job_client, self.storage_entry_point, project_id, + model_setting, predict_algorithm, dataset, self.config.user_config, id_fields) + raise Exception(f"Unsupported job type: {job_type}") diff --git a/static/images/wedpr_logo.png b/static/images/wedpr_logo.png new file mode 100644 index 00000000..8f10965f Binary files /dev/null and b/static/images/wedpr_logo.png differ